Solidity区块链游戏开发入门

我们的重点将是实现名为 PixelBattle 的 Solidity 智能合约构建的简单游戏,允许最多四名玩家将以太坊存入共享彩池,所有者有权开始和结束游戏并宣布获得总奖金的获胜者。

Solidity区块链游戏开发入门
一键发币: SOL | BNB | ETH | BASE | Blast | ARB | OP | POLYGON | AVAX | FTM | OK

欢迎来到本教程,我们将深入使用以太坊智能合约的编程语言 Solidity 进行区块链游戏开发。 本教程专为区块链 Solidity 和游戏开发的初学者而设计。

我们的重点将是通过名为 PixelBattle 的 Solidity 智能合约构建的简单游戏。 该游戏允许最多四名玩家将以太坊存入共享彩池,所有者有权开始和结束游戏并宣布获得总奖金的获胜者。

1、合约设置

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.22;

contract PixelBattle {
    ...
}
  • SPDX-License-Identifier:此行指定发布此合约所依据的许可证。 在这里使用的是MIT协议。
  • pragma Solidity ^0.8.22:指定 Solidity 编译器版本。

2、状态变量和事件

在 PixelBattle 中,我们有几个状态变量和事件:

mapping (address => uint) private balances;
address public owner;
address[4] private players;
uint private playerCount;
bool private gameStarted;
bool private gameEnded;

event LogDepositMade(address indexed accountAddress, uint amount);
event LogGameEnded(address indexed winner, uint amount);
  • balance:用于跟踪每个玩家余额的映射。
  • owner:游戏所有者的地址。
  • players:最多可存储四名玩家的数组。
  • playerCount:玩家数量的计数器。
  • gameStartedgameEnded:布尔值将跟踪游戏的状态。
  • LogDepositMadeLogGameEnded:记录关键操作的事件。

现在,让我们稍微分解一下。

  • mapping(address => uint) private balances;

这一行声明了一个名为balances的私有状态变量,它是一个映射。

Solidity 中的映射就像其他语言中的哈希表或字典。 它将键映射到值。

这里,key是一个 address,value是一个uint(无符号整数,意味着它只能是非负数)。

address是 Solidity 中用于存储以太坊地址的特殊类型。

此映射跟踪每个地址的余额(例如,以太币)。 它是私有的,因此只能通过合约访问和修改。

  • address public owner;

这是一个名为“owner”、类型为“address”的状态变量。

它被声明为公开的,这意味着 Solidity 自动生成一个 getter 函数。 这允许其他合约和客户端读取其值,但不能直接修改它。

  • address[4] private players;

此行声明一个私有状态变量players,它是一个固定大小的地址元素数组。

数组大小为 4,这意味着它最多可以包含 4 个玩家的地址。

  • uint private playerCount;

这声明了一个uint类型的私有状态变量playerCount。

它可能用于跟踪游戏中有多少玩家。

  • bool private gameStarted;

这是一个名为 gameStarted 的布尔(真/假)状态变量。

它是私有的,这意味着它只能在合约内访问。

它可能用于跟踪游戏是否已经开始。

  • bool private gameEnded;

同样,gameEnded 是一个布尔状态变量,用于指示游戏是否已经结束。

  • event LogDepositMade(address indexed accountAddress, uint amount);

此行声明一个名为 LogDepositMade 的事件。

Solidity 中的事件是合约传达区块链发生情况的一种方式,可以在用户界面中监听。

存款时会触发此特定事件。 它包括一个索引参数 accountAddress,它有助于过滤该特定地址的日志,以及一个常规参数 amount,即存入的以太币数量。

  • event LogGameEnded(address indexed winner,uint amount);

这是另一个事件,LogGameEnded,表示游戏结束。

它包括获胜者的地址(作为索引参数)和赢得的金额。

3、构造函数

    constructor() {
        owner = msg.sender;
        playerCount = 0;
        gameStarted = false;
        gameEnded = false;
    }

构造函数将合约部署者设置为所有者并初始化游戏状态。

4、startGame

function startGame() public {
    require(msg.sender == owner, "Only owner can start the game");
    require(!gameStarted, "Game already started");
    gameStarted = true;
    gameEnded = false;
    playerCount = 0;
}

startGame 由所有者调用以开始新游戏,确保当前没有游戏正在运行。

好的,现在我们也将对此进行分解。

5、deposit

    function deposit() public payable returns (uint) {
        require(gameStarted, "Game has not started");
        require(!gameEnded, "Game has ended");
        require(msg.value == 0.08 ether, "Deposit must be exactly 0.08 ETH");
        require(playerCount < 4, "Game is full");

        for(uint i = 0; i < playerCount; i++) {
            require(players[i] != msg.sender, "Player already joined");
        }

        balances[msg.sender] += msg.value;
        players[playerCount] = msg.sender;
        playerCount++;

        emit LogDepositMade(msg.sender, msg.value);

        return balances[msg.sender];
    }

玩家通过发送 0.08 以太币来使用存款来加入游戏。 它检查游戏是否已开始、是否未完成以及玩家是否仍需要加入。

6、endGameAndPayWinner

    function endGameAndPayWinner(address winner) public {
        require(msg.sender == owner, "Only owner can end the game");
        require(gameStarted, "Game has not started");
        require(!gameEnded, "Game has already ended");
        require(playerCount == 4, "Game is not full yet");

        uint totalPrize = address(this).balance;
        payable(winner).transfer(totalPrize);
        emit LogGameEnded(winner, totalPrize);

        // Reset the game
        for(uint i = 0; i < playerCount; i++) {
            balances[players[i]] = 0;
        }
        gameEnded = true;
        gameStarted = false;
    }

该功能允许所有者结束游戏,宣布获胜者,并将总奖金转移到获胜者的地址。 它还会重置游戏状态。

7、balance

    function balance() public view returns (uint) {
        return balances[msg.sender];
    }

balance让玩家可以查看自己在游戏中存入的余额。

8、结束语

这个智能合约代表了以太坊区块链上的一个简单游戏。 对于初学者来说,最重要的一点是了解如何在 Solidity 中构建简单的比赛,从而能够创建去中心化应用程序 (dApp),以及以太坊区块链如何管理状态并确保公平竞争。


原文链接:Introduction to Building a Blockchain Game with Solidity

DefiPlot翻译整理,转载请标明出处

通过 NowPayments 打赏