本文将引导你使用 Solana 区块链和 Anchor 框架创建一个简单的链上游戏 "Tiny Adventure"。无需本地安装任何开发环境,我们将直接使用 Solana Playground 这一在线 IDE 完成编写、构建和部署的全过程。通过这个项目,你将学会如何创建基础游戏逻辑、存储玩家状态并与之交互。
开发环境与工具准备
我们将使用 Solana Playground 这一基于浏览器的集成开发环境。它省去了复杂的本地配置步骤,让开发者能专注于代码逻辑。
访问 Solana Playground 并创建新的 Anchor 项目。初次使用时,你需要创建一个 Playground 钱包并确保连接到 Devnet 测试网络。运行 solana airdrop 5 即可获取测试用 SOL 代币。
游戏程序结构与初始化
游戏的核心逻辑是一个 Solana 程序(智能合约),使用 Rust 语言和 Anchor 框架编写。
初始程序代码
创建项目后,将 lib.rs 文件中的默认代码替换为以下基础结构:
use anchor_lang::prelude::*;
declare_id!("11111111111111111111111111111111");
#[program]
mod tiny_adventure {
use super::*;
// 指令处理程序将在这里定义
}
// 结构体将在这里定义
fn print_player(player_position: u8) {
if player_position == 0 {
msg!("A Journey Begins!");
msg!("o.......");
} else if player_position == 1 {
msg!("..o.....");
} else if player_position == 2 {
msg!("....o...");
} else if player_position == 3 {
msg!("........\\o/");
msg!("You have reached the end! Super!");
}
}这个游戏开始时玩家位于位置 0,可以通过指令向左或向右移动。我们将使用消息日志来显示玩家的进度。
定义游戏数据账户
我们需要定义一个链上账户结构来存储玩家位置:
// 定义游戏数据账户结构
#[account]
pub struct GameDataAccount {
player_position: u8,
}该结构包含一个字段 player_position,以无符号 8 位整数存储玩家的当前位置。
程序指令设计
Tiny Adventure 程序包含三个指令处理器:
initialize:设置存储玩家位置的链上账户move_left:让玩家向左移动move_right:让玩家向右移动
初始化指令
初始化指令负责创建 GameDataAccount(如果尚不存在),将 player_position 设置为 0,并打印初始消息。
// 初始化GameDataAccount并将位置设置为0的指令
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
ctx.accounts.new_game_data_account.player_position = 0;
msg!("A Journey Begins!");
msg!("o.......");
Ok(())
}初始化指令需要三个账户:
new_game_data_account:我们要初始化的 GameDataAccountsigner:支付 GameDataAccount 初始化费用的玩家system_program:创建新账户时必需的系统程序
我们使用程序派生地址(PDA)作为 GameDataAccount 的地址,使用单个固定值 "level1" 作为种子。这种设计允许我们确定性地定位地址,但限制了程序只能创建一个 GameDataAccount。
向左移动指令
move_left 指令让玩家更新其位置:向左移动意味着将 player_position 减 1,最低位置为 0。
// 向左移动的指令
pub fn move_left(ctx: Context<MoveLeft>) -> Result<()> {
let game_data_account = &mut ctx.accounts.game_data_account;
if game_data_account.player_position == 0 {
msg!("You are back at the start.");
} else {
game_data_account.player_position -= 1;
print_player(game_data_account.player_position);
}
Ok(())
}向右移动指令
类似地,move_right 指令将 player_position 加 1,最高位置限制为 3。
// 向右移动的指令
pub fn move_right(ctx: Context<MoveRight>) -> Result<()> {
let game_data_account = &mut ctx.accounts.game_data_account;
if game_data_account.player_position == 3 {
msg!("You have reached the end! Super!");
} else {
game_data_account.player_position = game_data_account.player_position + 1;
print_player(game_data_account.player_position);
}
Ok(())
}构建与部署
完成程序代码后,在 Solana Playground 中构建并部署程序。确保你已创建 Playground 钱包并连接到 Devnet 端点,且有足够的 SOL 用于部署。
👉 查看实时开发工具
客户端交互实现
现在我们将创建一个简单的客户端实现来与游戏交互。
派生游戏数据账户地址
首先,使用 findProgramAddress 函数派生 GameDataAccount 的 PDA:
// 每个人都可以通过这个PDA地址控制角色(如果与你的程序交互)
const [globalLevel1GameDataAccount, bump] =
await anchor.web3.PublicKey.findProgramAddress(
[Buffer.from("level1", "utf8")],
pg.program.programId,
);初始化游戏状态
接下来,尝试使用上一步的 PDA 获取游戏数据账户。如果账户不存在,我们将通过调用程序中的 initialize 指令来创建它。
左右移动功能
通过调用程序的 moveLeft 或 moveRight 指令并与 Solana 网络提交交易,实现与游戏的交互。你可以多次重复此步骤,每次都会在链上执行移动逻辑并更新玩家状态。
记录玩家位置
使用 switch 语句根据 gameDateAccount 中存储的 playerPosition 值记录角色位置,作为游戏中角色移动的视觉表示。
运行客户端程序
在 Solana Playground 中点击 "Run" 按钮运行客户端。输出应类似于:
Running client...
client.ts:
My address: 8ujtDmwpkQ4Bp4GU4zUWmzf65sc21utdcxFAELESca22
My balance: 4.649749614 SOL
Use 'solana confirm -v 4MRXEWfGqvmro1KsKb94Zz8qTZsPa9x99oMFbLBz2WicLnr8vdYYsQwT5u3pK5Vt1i9BDrVH5qqTXwtif6sCRJCy' to see the logs
Player position is: 1
... .o. ...恭喜!你已成功从客户端构建、部署并调用了 Tiny Adventure 游戏。
进阶开发建议
完成基础游戏后,你可以发挥创意,独立实现自己的创意来丰富游戏体验:
- 修改游戏内文本,创建有趣的故事线。邀请朋友体验你设计的叙事,并观察链上交易的展开!
- 添加宝箱系统,用 SOL 奖励玩家,或让玩家在游戏进程中收集硬币并与代币交互
- 创建网格系统,允许玩家上下左右移动,并引入多个玩家以获得更动态的体验
常见问题
什么是 Solana Playground?
Solana Playground 是一个基于浏览器的集成开发环境,允许开发者无需本地安装即可编写、构建和部署 Solana 程序。它特别适合初学者和快速原型开发。
程序派生地址(PDA)有什么作用?
PDA 是一种特殊类型的地址,格式类似于公钥,但不由私钥控制。它们由程序 ID 和额外种子派生而来,允许程序以确定性的方式管理账户,而不需要私钥签名。
如何让每个玩家拥有独立的游戏状态?
在当前实现中,我们使用固定种子 "level1" 生成 PDA,这意味着所有玩家共享同一个游戏状态。要让每个玩家拥有独立状态,可以使用签名者的地址作为额外种子。
如何扩展这个基础游戏?
你可以添加更多移动方向、引入物品系统、设计多关卡进度或集成代币经济系统。Solana 的高性能和低交易成本为链上游戏开发提供了广阔可能性。
在哪里可以获取测试网 SOL?
在 Solana Playground 中,可以使用 solana airdrop 5 命令获取 Devnet 测试网 SOL。如果失败,可以尝试其他 Devnet 水龙头获取测试代币。
后续学习路径
完成本教程后,你可以继续学习 Tiny Adventure 游戏的第二部分,了解如何在程序中存储 SOL 并将其作为奖励分发给玩家。此外,还可以探索更多 Solana 游戏开发资源,包括入门指南、游戏 SDK、示例项目以及能量系统和 NFT 在游戏中的应用等专题。