区块链游戏开发-僵尸大战

第一课你将创造一个"僵尸工厂", 用它建立一支僵尸部队。

  • 我们的工厂会把我们部队中所有的僵尸保存到数据库中
  • 工厂会有一个函数能产生新的僵尸
  • 每个僵尸会有一个随机的独一无二的面孔

在后面的课程里,我们会增加功能。比如,让僵尸能攻击人类或其它僵尸! 但是在实现这些好玩的功能之前,我们先要实现创建僵尸这样的基本功能。

pragma solidity ^0.4.19;
//建立僵尸工厂,属性,方法全部放在这个工厂中
contract ZombieFactory {

    // 这里建立事件
    event NewZombie(uint zombieId, string name, uint dna);
    uint dnaDigits = 16;
    uint dnaModulus = 10 ** dnaDigits;
    //一个僵尸结构体
    struct Zombie {
        string name;
        uint dna;
    }
    //僵尸数组
    Zombie[] public zombies;
    //根据名字,dna创建僵尸,可以由事件触发
    function _createZombie(string _name, uint _dna) private {
        //zombies.push(Zombie(_name, _dna));
        // 这里触发事件
        uint id = zombies.push(Zombie(_name, _dna)) - 1;
        NewZombie(id, _name, _dna);


    }

    function _generateRandomDna(string _str) private view returns (uint) {
        uint rand = uint(keccak256(_str));
        return rand % dnaModulus;
    }
   //根据名字,产生DNA,再创建僵尸
    function createRandomZombie(string _name) public {
        uint randDna = _generateRandomDna(_name);
        _createZombie(_name, randDna);
    }

}

在第一课中,我们创建了一个函数用来生成僵尸,并且将它放入区块链上的僵尸数据库中。 在第二课里,我们会让我们的 app 看起来更像一个游戏: 它得支持多用户,并且采用更加有趣,而不仅仅使用随机的方式,来生成新的僵尸。

如何生成新的僵尸呢?通过让现有的僵尸猎食其他生物!

第二课-多玩家模式

知识点:

1:require语句

function sayHiToVitalik(string _name) public returns (string) {
  // 比较 _name 是否等于 "Vitalik". 如果不成立,抛出异常并终止程序
  // (敲黑板: Solidity 并不支持原生的字符串比较, 我们只能通过比较
  // 两字符串的 keccak256 哈希值来进行判断)
  require(keccak256(_name) == keccak256("Vitalik"));
  // 如果返回 true, 运行如下语句
  return "Hi!";
}

2:接口

现在假设我们有一个外部合约,使用 getNum 函数可读取其中的数据。

首先,我们定义 LuckyNumber 合约的 interface 

contract NumberInterface {
  function getNum(address _myAddress) public view returns (uint);
}

继续前面 NumberInterface 的例子,我们既然将接口定义为:

contract NumberInterface {
  function getNum(address _myAddress) public view returns (uint);
}

我们可以在合约中这样使用:

contract MyContract {
  address NumberInterfaceAddress = 0xab38...;
  // ^ 这是FavoriteNumber合约在以太坊上的地址
  NumberInterface numberContract = NumberInterface(NumberInterfaceAddress);
  // 现在变量 `numberContract` 指向另一个合约对象

  function someFunction() public {
    // 现在我们可以调用在那个合约中声明的 `getNum`函数:
    uint num = numberContract.getNum(msg.sender);
    // ...在这儿使用 `num`变量做些什么
  }
}
pragma solidity ^0.4.19;
import "./zombiefactory.sol";
contract KittyInterface {
  function getKitty(uint256 _id) external view returns (
    bool isGestating,
    bool isReady,
    uint256 cooldownIndex,
    uint256 nextActionAt,
    uint256 siringWithId,
    uint256 birthTime,
    uint256 matronId,
    uint256 sireId,
    uint256 generation,
    uint256 genes
  );
}
contract ZombieFeeding is ZombieFactory {

  address ckAddress = 0x06012c8cf97BEaD5deAe237070F9587f8E7A266d;
  KittyInterface kittyContract = KittyInterface(ckAddress);

  function feedAndMultiply(uint _zombieId, uint _targetDna, string _species) public {
    require(msg.sender == zombieToOwner[_zombieId]);
    Zombie storage myZombie = zombies[_zombieId];
    _targetDna = _targetDna % dnaModulus;
    uint newDna = (myZombie.dna + _targetDna) / 2;
    if (keccak256(_species) == keccak256("kitty")) {
      newDna = newDna - newDna % 100 + 99;
    }
    if (keccak256(_species) == keccak256("kitty")) {
      newDna = newDna - newDna % 100 + 99;
    }
    _createZombie("NoName", newDna);
  }

  function feedOnKitty(uint _zombieId, uint _kittyId) public {
    uint kittyDna;
    (,,,,,,,,,kittyDna) = kittyContract.getKitty(_kittyId);
    feedAndMultiply(_zombieId, kittyDna, "kitty");
    feedAndMultiply(_zombieId, kittyDna, "kitty");
  }

}

 

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页