基于 BOLT 框架构建具有可重用组件和可定制逻辑的井字棋

时间:2024-09-21 编辑: 浏览:(261)

作者:Magicblock;来源:MetaCat

本文展示了一个使用 Bolt 引擎的实体组件系统 (ECS) 开发的简单游戏示例,它促进了组件的可重用性,并使用户能够修改和扩展游戏的逻辑。

该框架通过抽象帐户空间(Account Space)和程序派生地址 (Program Derived Addresses)等底层概念,显著简化了基于 Solana 的开发。要与基于 Anchor 的程序进行比较,请参阅本教程?

https://book.anchor-lang.com/anchor_in_depth/milestone_project_tic-tac-toe.html

有关 Bolt 的更详细说明,请参阅公告博文?

https://blog.magicblock.gg/bolt-v0.1/

开发井字棋

本文第一部分详细介绍如何使用 Bolt 框架实现游戏逻辑。第二部分解释从开源井字棋实现开始,如何将基于 React 的客户端与程序集成。

该示例的完整源代码可在此处获取?

https://github.com/magicblock-labs/bolt-tic-tac-toe

游戏逻辑:使用 Bolt ECS 实现井字棋

首先,安装bolt-cli:

npminstall@magicblock-labs/bolt-cli

安装后,使用以下命令创建新项目:

boltinittic-tac-toe

创建组件(Component)

我们需要定义所需的数据结构。为简单起见,我们将创建两个组件:一个包含活跃玩家,另一个包含网格信息。

使用以下命令创建新组件:

boltcomponentplayers

此命令在 program-ecs/components 下创建一个players 组件。保存两个玩家的公钥的玩家组件可以定义如下:

usebolt_lang::*;declare_id!("5Xz6iiE2FZdpqrvCKbGqDajNYt1tP8cRGXrq3THSFo1q");#[component]#[derive(Default)]pubstructPlayers{pubplayers:[Option<Pubkey>;2],}

第二个组件包含网格信息。使用如下命令创建它:

boltcomponentgrid

网格组件可以定义为:

usebolt_lang::*;declare_id!("rdiVoU6KomhXBDMLi6UXVHvmjEUtKqb5iDCWChxMzZ7");#[component]pubstructGrid{pubboard:[[Option<Sign>;3];3],pubstate:GameState,pubis_first_player_turn:bool,}#[component_deserialize]#[derive(PartialEq)]pubenumGameState{Active,Tie,Won{winner:Pubkey},}#[component_deserialize]#[derive(PartialEq)]pubenumSign{X,O,}implSign{pubfnfrom_usize(value:usize)->Sign{matchvalue{0=>Sign::X,_=>Sign::O,}}}implDefaultforGrid{fndefault()->Self{Self::new(GridInit{board:[[None;3];3],state:GameState::Active,is_first_player_turn:true,})}}

创建系统(Systems)

系统以模块化方式实现游戏逻辑。它们对一组输入组件进行操作,并且可以执行任何计算。系统在你的世界实例中执行,并遵守审批策略,例如,一个世界可以允许任何人提交新系统,而另一个世界可能需要白名单方或 DAO 的批准。

我们构建的第一个系统将允许玩家加入比赛:

boltsystemjoin-game

将逻辑(在 program-ecs/systems/join-game.rs 中)修改为:

#[system]pubmodjoin_game{pubfnexecute(ctx:Context<Components>,_args_p:Vec<u8>)->Result<Components>{letplayers=&mutctx.accounts.players.players;letidx=matchplayers.iter_mut().position(|player|player.is_none()){Some(player_index)=>player_index,None=>returnErr(PlayersError::GameFull.into()),};ctx.accounts.players.players[idx]=Some(*ctx.accounts.authority.key);Ok(ctx.accounts)}#[system_input]pubstructComponents{pubplayers:Players,}}

第二个系统实现了游戏的核心逻辑:

1. 创建一个玩游戏系统:

boltsystemplay

2. 实现逻辑:

usebolt_lang::*;usegrid::Grid;useplayers::Players;declare_id!("DyUy1naq1kb3r7HYBrTf7YhnGMJ5k5NqS3Mhk65GfSih");#[system]pubmodplay{pubfnexecute(ctx:Context<Components>,args:Args)->Result<Components>{letgrid=&mutctx.accounts.grid;letplayers=&mutctx.accounts.players;letauthority=*ctx.accounts.authority.key;require!(players.players[0]==Some(authority)||players.players[1]==Some(authority),TicTacToeError::NotInGame);require!(grid.state==grid::GameState::Active,TicTacToeError::NotActive);letplayer_idx:usize=ifplayers.players[0]==Some(authority){0}else{1};require!(grid.is_first_player_turn==(player_idx==0),TicTacToeError::NotPlayersTurn);//Coregamelogicmatchargs{tile@Args{row:0..=2,column:0..=2,}=>matchgrid.board[tile.rowasusize][tile.columnasusize]{Some(_)=>returnErr(TicTacToeError::TileAlreadySet.into()),None=>{grid.board[tile.rowasusize][tile.columnasusize]=Some(grid::Sign::from_usize(player_idx));}},_=>returnErr(TicTacToeError::TileOutOfBounds.into()),}grid.is_first_player_turn=!grid.is_first_player_turn;check_winner(grid,authority);Ok(ctx.accounts)}#[system_input]pubstructComponents{pubgrid:Grid,pubplayers:Players,}#[arguments]structArgs{row:u8,column:u8,}}pubfncheck_winner(grid:&mutAccount<Grid>,player:Pubkey){...}

有关详细信息,请参阅完整源代码?

https://github.com/magicblock-labs/bolt-tic-tac-toe/blob/main/programs-ecs/systems/play/src/lib.rs

正如你所注意到的,实现非常简单。标记的结构体system_input定义了可以在execute函数中访问和使用的组件输入包。标记为的结构体arguments定义你的系统可以作为输入接收的参数。

构建并测试程序

使用以下命令构建程序:

boltbuild

此命令编译程序并自动生成 IDL 和 TypeScript 类型以进行客户端集成。

设置组件和执行系统的过程涉及以下步骤:

实例化一个世界。

创建与之匹配实体。

将玩家和网格组件附加到该匹配实体。

执行系统以促进游戏玩法。

Tic-Tac-Toe 游戏的 TypeScript 测试可以在这里找到?

连接 React 客户端

连接 React 客户端非常简单,这要归功于类型的动态检索和生成以及 Bolt TypeScript SDK 提供的实用函数。

添加依赖项:

yarnadd-D@magicblock-labs/bolt-sdk

例如,要执行一个系统:

// Componentsconst GRID_COMPONENT = new PublicKey("rdiVoU6KomhXBDMLi6UXVHvmjEUtKqb5iDCWChxMzZ7");const PLAYERS_COMPONENT = new PublicKey("5Xz6iiE2FZdpqrvCKbGqDajNYt1tP8cRGXrq3THSFo1q");// Systemsconst JOIN_GAME = new PublicKey("2umhnxiCtmg5KTn4L9BLo24uLjb74gAh4tmpMLRKYndN");const PLAY = new PublicKey("DyUy1naq1kb3r7HYBrTf7YhnGMJ5k5NqS3Mhk65GfSih");const applySystem = await ApplySystem({ authority: publicKey, system: JOIN_GAME, entity, components: [PLAYERS_COMPONENT],});const transaction = applySystem.transaction;const signature = await submitTransaction(transaction);

在这里找到用 React 制作的简单井字棋 UI?

https://github.com/magicblock-labs/bolt-tic-tac-toe/tree/main/app/react-tic-tac-toe

需要强调的一个重要方面是:执行系统和实例化组件仅需要 ID。这意味着可以动态创建和利用新的逻辑和数据结构,从而能够开发模组并更改游戏的行为。

结论

我们已经演练了使用 Bolt ECS 的井字棋游戏的简单实现,演示了如何将其连接到 React UI。这凸显了该框架的简单性和灵活性。除了抽象 Solana 和重用链上逻辑之外,我们对 BOLT 将为用户生成的逻辑和 mod 引入带来的可能性感到兴奋。在后续示例中,我们将展示游戏开发人员如何独立且无需许可地扩展游戏逻辑,以及如何使用临时汇总(Ephemeral Rollups)实现低延迟/高吞吐量交易。

最新 更多 >
  • 1 SGMT币历史价格走势怎么样?

    SGMT币历史价格走势怎么样?SGMT币是一种新兴的数字货币,随着加密货币市场的不断发展,越来越多的人开始关注和投资这种数字资产。那么,SGMT币的历史价格走势究竟怎么样呢?2018年12月,SGMT币正式推出并上线交易所。当时,SGMT币的价格为0.005美元左右。在接下来的几个月里,SGMT币价格一直在低位波动,直至2019年5月初,价格突然上涨至0.14美元,创下历史新高。然而,这一涨势并没

  • 2 PEX是什么币种,PEX币怎么样?

    PEX是什么币种PEX是一个加密货币,是Pexa项目的原生代币。Pexa项目致力于构建一个完全去中心化的区块链生态系统,旨在为用户提供更安全、快速、低成本的转账和支付服务。PEX币作为Pexa项目的代币,具有一定的使用场景和功能。PEX币有哪些特点PEX币是一个去中心化的数字货币,具有一些独特的特点。首先,PEX币的发行总量是固定的,没有通胀机制,因此更具价值稳定性。其次,PEX币采用区块链技术,

  • 3 SHIBL币历史价格走势怎么样?

    SHIBL币是近期备受瞩目的加密货币之一。然而,这种数字货币的价格走势却一直备受争议。下面我们将带您了解一下SHIBL币的历史价格走势。SHIBL币的初始价格SHIBL币首次亮相于2020年,当时该数字货币的价格约为0.00000001美元。由于SHIBL币的供应量相对较高,许多人对它的长期价值表示怀疑。SHIBL币的价格暴涨2021年初,SHIBL币的价格开始暴涨。在5月初,这种数字货币的价格一

  • 4 SIENNA币的创始人是谁

    SIENNA币是一种刚刚崭露头角的新型数字货币,它的诞生背后有着一位极为重要的人物——SIENNA币的创始人。下面,我们将从他的个人背景、创立SIENNA币的初衷以及币种的特点等方面,来详细介绍SIENNA币的创始人是谁。个人背景SIENNA币的创始人名为Jayson E. Wong,他是一名美籍华人,拥有多年的区块链技术和数字货币的从业经验。他先后就读于美国加州大学伯克利分校以及麻省理工学院,拥

  • 5 KPAD币最高的时候是多少钱?

    KPAD币最高价格近年来,区块链技术和数字货币市场的快速发展使得越来越多人开始关注和投资各种加密货币。其中,KPAD币也成为了越来越多投资者的选择。在过去的几年中,KPAD币的价格出现了剧烈波动,那么它的最高价格是多少呢?要了解KPAD币的最高价格,我们首先需要了解什么是KPAD币。KPAD币是一个建立在区块链上的去中心化自动市场制造商(AMM)。其目的是像传统市场制造商一样创建流动性池,为交易提

  • 6 SCREAM币历史价格走势怎么样?

    SCREAM币历史价格走势怎么样?SCREAM币是一种基于以太坊区块链的去中心化金融平台币种,于2021年5月正式上线交易所。在这短短的几个月内,SCREAM币价格经历了不同的波动,以下是它的历史价格走势。5月份:上线初期表现平稳SCREAM币于5月份上线交易所,初始价格为0.24美元。上线当天价格略有波动,但整体表现平稳。5月8日价格达到0.31美元,最高涨幅达到29%。尽管市场波动较大,SCR

  • 7 SHARD币最高的时候是多少钱?

    SHARD币最高的时候是多少钱?SHARD币是一种基于区块链技术的数字货币,它由加密货币交易所Kucoin推出。SHARD币的核心理念是为解决现有区块链的安全和性能问题提供一种全新的解决方案,从而推动区块链技术的进一步发展。自2019年4月份SHARD币上线以来,它已经成为了市场上备受关注的数字货币之一。在市场上,SHARD币的价格一直在波动。在这篇文章中,我们将一起去看看SHARD币最高的时候是

  • 8 Axelar(AXL币)未来价值如何?

    AXELAR(AXL币)未来的潜在价值AXELAR(AXL币)是一个新兴的加密货币项目,致力于跨链和跨网络互操作性,以提供更好的去中心化金融(DeFi)解决方案。该项目旨在解决现有区块链网络之间互通性的问题,为用户提供无缝的体验。随着区块链技术的不断发展和普及,AXELAR的未来潜在价值不容小觑。以下是几个因素,支持这种看法:技术创新AXELAR团队致力于研究和开发跨链技术,并不断推动该领域的创新

  • 9 SHUMO币的创始人是谁

    SHUMO币的创始人是谁?SHUMO币是一种新型的数字货币,也是近年来备受关注的币种之一。它的创始人是李小明,一位来自中国的年轻企业家,现在已成为数字货币行业的重要人物。李小明的创业历程李小明自幼喜欢数学和计算机,从小就展现出良好的编程天赋。在进入大学后,他选择了学习计算机科学。毕业后,他在一家软件公司工作了几年,积累了一定的工作经验和技术能力。然而,作为一个有梦想的年轻人,李小明并不满足于只是为

  • 10 SETH币的创始人是谁

    SETH币的创始人是谁?SETH币是近几年兴起的一种数字货币,它是基于以太坊区块链技术的一种代币,是以及智能合约系统为基础的应用型数字货币,其创始人是Devin Soni。Devin Soni是谁?Devin Soni出生于印度,成长于美国。他是一位技术天才,从小对编程有着浓厚的兴趣。他早年就已经开始从事比特币、以太坊和智能合约的研究和开发。2017年,Devin Soni创建了SETH基金会,他