title | actions | requireLogin | material | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
時間の単位 |
|
true |
|
level
プロパティは見ればわかるだろう。あとで開発するバトルシステムで勝つことでレベルアップして、より多くの能力にアクセスできるようになる。
readyTime
プロパティは少し説明が必要になる。目的は”冷却期間”を追加することで、一度ゾンビが何かを攻撃・捕食したあとで、次の攻撃・捕食までどれくらい待たなければならないかを規定するものだ。これがないと1日に何千回でも攻撃して増殖できるから、ゲームが成り立たないからだ。
次の捕食までどれだけ待たなければならないかを計算するには、Solidityの時間の単位を使用することができる。
Solidityには時間を扱うための固有の単位がいくつか用意されている。
now
変数は、現在のunixタイムスタンプ(1970年1月1日から経過した秒数のことだ)を返す。これを書いている時のunixタイムスタンプは1515527488
だ。
注:unixタイムスタンプは歴史的に32ビットの数値として格納されています。これは"2038年"問題、つまり、32ビットのunixタイムスタンプがオーバーフローすることによりたくさんの古いシステムが壊れる問題、の原因になります。もしDAppを今から20年以上稼働させたいなら、64ビットの数値を使う必要がありますが、ユーザーはその間ずっとガスコストを多めに支払うことになります。設計上の決断が必要になります!
Solidityには seconds
、 minutes
、 hours
、 days
、weeks
、years
という単位も用意されている。それぞれuint
の秒数に変換されて使用される。つまり、1 minutes
は 60
になり、1 hours
は 3600
(60 秒 x 60 分)になり、1 days
は86400
(24時間 x 60 分 x 60 秒)となる。
時間単位がかなり役立つことを理解するための例をあげるぞ:
uint lastUpdated;
// `lastUpdated` を `now`に設定する
function updateTimestamp() public {
lastUpdated = now;
}
// `updateTimestamp`が呼ばれてから5分経っていれば、`true`が返る。
// 5分経っていなければ、`false`が返る。
function fiveMinutesHavePassed() public view returns (bool) {
return (now >= (lastUpdated + 5 minutes));
}
ゾンビのcooldown
機能にはこの時間の単位を使用するのだ。
DAppにクールダウンタイマー機能を追加し、ゾンビが一度捕食したら、1 day待たなければならないようにしたい。
-
cooldownTime
というuint
を宣言し、1 days
に設定せよ。(英語の文法的には"1 day"が正しいが、それではコンパイルされないので、ここでは気をつけるようにな。) -
前のチャプターですでに
Zombie
structにlevel
とreadyTime
を追加してある。そこで新しいZombie
structを作る場合、正しい引数を使うために_createZombie()
を更新する必要がある。zombies.push
の行を変更し、1
(level
用)と、uint32(now + cooldownTime)
(readyTime
用)の2つの引数を追加せよ。
注:デフォルトで
now
はuint256
を返すため、uint32(...)
が必要になります。そこで明示的にuint32
に変換します。
now + cooldownTime
は、現在のunixタイムスタンプ(秒)と、1日分の秒数を足した数字になる。つまり1日後のunixタイムスタンプとなる。ゾンビの捕食に十分な時間が経ったかを判定するために、あとでゾンビのreadyTime
が now
よりも大きくなっているかを確認することになる。
readyTime
でアクションを制限する機能については、次のチャプターで教えてやるから、しばし待つのだ。