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

时间:2024-09-30 编辑: 浏览:(660)

作者: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 传亚马逊(AMZN.US)英国分部工人将于1月25日举行罢工

    英国亚马逊通常会在特定节日或假期时举办活动,比如圣诞节、黑色星期五、情人节等。他们还会定期举行闪购、特价促销和清仓活动。可以通过关注他们的官方网站、社交媒体平台或订阅电子邮件来获取最新活动信息。建议大家时常关注亚马逊的促销活动,以获取优惠价格和折扣。

  • 2 荧德控股(08535)发布前三季度业绩,股东应占溢利588.8万港元 同比减少60.2%

    荧德控股(08535)公布了前三季度业绩,股东应占溢利为588.8万港元,同比减少了60.2%。

  • 3 万讯自控(300112.SZ)拟推1141万股限制性股票激励计划

    万讯自控是一家专业从事智能控制系统和自动化设备的研发、生产和销售的企业。公司的股价受市场经济环境、行业发展趋势和公司财务业绩等因素的影响。投资者需关注公司的核心竞争力、技术实力以及未来发展前景来评估公司的股价走势。

  • 4 朝聚眼科(02219)认购2.3亿元中国银行结构性存款产品

    朝阳银行结构性存款是一种金融产品,客户在存款的同时可以获得相应的收益。该产品的收益与利率、期限、市场变化等因素有关,通常具有一定的风险性。客户可根据自身的风险承受能力和投资需求选择不同类型的结构性存款,以实现资金增值的目的。朝阳银行结构性存款为客户提供了多样化的投资选择,满足了不同客户的投资需求。

  • 5 香港短期或出台措施助科企业上市以激活创业板 小摩增持再鼎医药(09688)

    香港政府正在考虑采取短期措施来帮助科技企业在香港上市,以激活创业板市场。同时,摩根大通增持了再鼎医药(09688.HK)的股份。这些举措显示了香港市场对科技行业的重视和支持,有望推动更多科技企业在香港上市,促进市场活跃。

  • 6 小金属走出大行情!钼价一年飙升122%至799美元/吨

    小金属钼的价格在过去一年中飙升了122%,达到每吨799美元。这一涨势让钼在国际市场上走出了一波大行情,受到投资者的关注和追捧。钼的价格上涨主要受到市场供应减少和需求增加的影响,预计未来钼价格仍将保持稳步上涨的趋势。

  • 7 东莞证券:12月挖掘机出口占比创新高 工程机械需求有望迎来边际改善

    摘要:根据东莞证券的数据显示,12月份挖掘机出口占比达到了创新高,这表明工程机械需求有望迎来边际改善。这一数据显示了市场对于工程机械的需求正在逐渐增加,未来该行业可能会迎来更好的发展机遇。

  • 8 SOFI(SOFI.US)一度涨超12% Q4营收同比增60%

    摘要:SOFI(SOFI.US)股价一度涨超12%,Q4营收同比增长60%。这表明公司在去年第四季度取得了显著的业绩提升,业务发展势头良好。这一利好消息也带动了投资者对公司未来发展的乐观态度,市场对SOFI的前景持续看好。

  • 9 远东股份(600869.SH):圣达电气重新纳入合并报表范围

    圣达电气和远东股份均是中国知名的电气企业,分别在不同领域拥有一定的市场地位。圣达电气专注于电气开关设备的研发、生产和销售,产品包括断路器、接地开关、避雷器等,广泛应用于建筑、工业和能源领域。远东股份主要从事输配电设备和系统解决方案的设计、制造和服务,产品涵盖变电设备、绝缘子、线路材料等,服务范围覆盖国内外市场。两家企业都注重技术创新和质量管理,致力于为客户提供高品质的电气产品和服务。

  • 10 麦当劳(MCD.US)Q4营收同比下降1% 2023年将新开1900家餐厅

    麦当劳2023年Q4营收同比下降1%,但仍计划在此年度新开1900家餐厅。这表明麦当劳仍然保持着扩张和发展的势头,尽管面临一定的挑战。新店开业将为麦当劳带来新的增长机遇,助力公司在竞争激烈的快餐市场中保持竞争力。