扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
今天就跟大家聊聊有关如何进行基于以太坊的Pokemon游戏开发实战,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
成都网站建设哪家好,找创新互联建站!专注于网页设计、成都网站建设、微信开发、微信平台小程序开发、集团企业网站建设等服务项目。核心团队均拥有互联网行业多年经验,服务众多知名企业客户;涵盖的客户类型包括:成都卫生间隔断等众多领域,积累了大量丰富的经验,同时也获得了客户的一致称扬!
我们将学习如何开发一个基于ERC721的妖怪战斗小游戏,它类似于去中心化版本的Pokémon游戏。教程中使用的开发工具为Truffle,开发语言为Solidity,第三方库为OpenZeppelin。
我们使用Truffle开发框架创建这个基于ERC721的Pokemon游戏项目。
首先创建一个新的文件夹,然后初始化Truffle项目:
~$ mkdir ethermon ~$ cd ethermon/ ~/ethermon$ truffle init
为了使用OpenZepplin,我们需要利用npm导入这个库。让我们先初始化npm,然后获取正确版本的OpenZeppelin。我们使用的是2.5.0版本的OpenZeppelin,因此你需要使用0.5.5版本的Solidity编译器:
~/ethermon$ npm init ~/ethermom$ npm install @openzeppelin/contracts@2.5.0 --save
在我们的contracts/文件夹,先创建一个新的文件ethermon.sol。要使用OpenZeppelin代码中的功能,我们需要引入并扩展ERC721.sol。
下面的代码展示了目前为止Ethermon.sol的内容:
pragma solidity ^0.5.5; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; contract Ethermon is ERC721 { }
首先使用truffle compile
检查并确保我们的合约可以正确编译。接下来,我们编写迁移脚本以便将合约部署到本地区块链。在migrations/目录 创建一个新的迁移文件2_deploy_contracts.js,内容如下:
const Ethermon = artifacts.require("Ethermon"); module.exports = function(deployer) { deployer.deploy(Ethermon); };
确保你的truffle-config.js的配置可以正确连接本地区块链,你可以使用truffle test
先测试一下。
我们需要Ethermon合约实现如下功能:
创建新的妖怪
将妖怪分配给主人
主人可以安排妖怪战斗
让我们先实现第一个功能。我们需要在Ethermon合约中用一个数组保存所有的妖怪。需要保存的妖怪相关的数据包括名字、级别等。因此我们使用一个结构。
到目前为止Ethermon合约的代码如下所示:
pragma solidity ^0.5.5; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; contract Ethermon is ERC721 { struct Monster { string name; uint level; } Monster[] public monsters; address public gameOwner; constructor() public { gameOwner = msg.sender; } function createNewMonster(string memory _name, address _to) public { require(msg.sender == gameOwner, "Only game owner can create new monsters"); uint id = monsters.length; monsters.push(Monster(_name, 1)); _safeMint(_to, id); } }
Monster结构在第7行定义,数组在第12行定义。我们也添加了一个gameOwner变量来保存Ethermon合约的部署账户。第19行开始是createNewMonster()函数的实现,该函数负责创建新的妖怪。
首先,它会检查这个函数是否是由合约的部署账号调用的。然后为新妖怪生成一个ID,并将新妖怪存入数组,最后使用_safeMint()函数将这个新创建的妖怪分配给其主人。
_safeMint() 是我们继承的ERC721合约中实现的函数。它可以安全地将一个ID分配给指定的账号,在分配之前会检查ID是否已经存在。
好了,现在我们已经可以创建新的妖怪并将其分配给指定的账号。该进行第三步了:战斗逻辑。
正如之前所述,我们的战斗逻辑决定了一个妖怪可以晋升多少等级。较高等级的妖怪可以获胜并升两级,失败的妖怪升一级。如果两个妖怪处于同一等级,那么进攻者获胜。下面的代码展示了合约中战斗逻辑的实现:
pragma solidity ^0.5.5; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; contract Ethermon is ERC721 { struct Monster { string name; uint level; } Monster[] public monsters; address public gameOwner; constructor() public { gameOwner = msg.sender; } function battle(uint _attackingMonster, uint _defendingMonster) public { Monster storage attacker = monsters[_attackingMonster]; Monster storage defender = monsters[_defendingMonster]; if (attacker.level >= defender.level) { attacker.level += 2; defender.level += 1; } else{ attacker.level += 1; attacker.level += 2; } } function createNewMonster(string memory _name, address _to) public { require(msg.sender == gameOwner, "Only game owner can create new monsters"); uint id = monsters.length; monsters.push(Monster(_name, 1)); _safeMint(_to, id); } }
第19行开始展示了妖怪的战斗逻辑。目前任何账号都可以调用battle()方法。然而我们需要对此加以限制,只允许发起进攻的妖怪的主人调用该方法。为此,我们可以添加一个修饰符,该修饰符利用ERC721.sol合约中的ownerOf()函数来检查调用账号。下面的代码展示了这部分的修改:
pragma solidity ^0.5.5; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; contract Ethermon is ERC721 { struct Monster { string name; uint level; } Monster[] public monsters; address public gameOwner; constructor() public { gameOwner = msg.sender; } modifier onlyOwnerOf(uint _monsterId) { require(ownerOf(_monsterId) == msg.sender, "Must be owner of monster to battle"); _; } function battle(uint _attackingMonster, uint _defendingMonster) public onlyOwnerOf(_attackingMonster) { Monster storage attacker = monsters[_attackingMonster]; Monster storage defender = monsters[_defendingMonster]; if (attacker.level >= defender.level) { attacker.level += 2; defender.level += 1; } else{ attacker.level += 1; attacker.level += 2; } } function createNewMonster(string memory _name, address _to) public { require(msg.sender == gameOwner, "Only game owner can create new monsters"); uint id = monsters.length; monsters.push(Monster(_name, 1)); _safeMint(_to, id); } }
好了!我们完成了一个ERC721版本的类似Pokemon的妖怪战斗游戏,虽然还很粗糙!
看完上述内容,你们对如何进行基于以太坊的Pokemon游戏开发实战有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注创新互联行业资讯频道,感谢大家的支持。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流