時間経過とともに繰り返し実行するイベントを作るには
たとえば、「毒」のステータス異常を受けた場合に歩数ダメージだけでなく、時間経過で少しずつダメージを与えたい場合があるかもしれません。
逆に、特定のアイテムを持っていれば時間経過とともに少しずつHPが回復していくというのも面白いでしょう。
さらにスクリプトを扱える上級者の方なら、update処理に一定間隔で繰り返し行う処理を追加したいという事はよくあるんじゃないかと思います。
特にスクリプトで「○秒ごとに実行するコード」を実装しようとすると「Graphics.frameCount」の値を参照してしまいがちですが、これには大きな落とし穴があります。
- 並列処理イベントで実装する方法
- スクリプトでupdate処理に追加する方法
の2種類の方法で説明してみます。なお、どちらの場合にも利用できる制作補助プラグインを作成しましたので手っ取り早く実装したい方は以下をダウンロードしてご利用下さい。
並列処理イベントで実装する方法
一番簡単なのは「並列処理」で実装する方法ですが、一つだけ注意があります。
まず、ツクールMVのゲームは基本的に1秒間に60回の計算を行っています。イベントコマンド「ウェイト」の単位が1フレーム=1/60秒なのもそういう理由ですね。
なので「並列処理」イベントの内容も、メッセージやウェイトをはさまない限り、1秒間に60回、繰り返し実行されています。
つまり、1秒に1回繰り返すイベントを作りたければ、1秒に60回実行される「並列処理」に59フレーム分のウェイトを入れて60フレームに1回実行されるようにしてやればいいのです。
これでハロルドが「毒」状態の時、1秒に1回ダメージを1ずつ受けるイベントが作れます。
でもここで一つ疑問が生まれますよね?なぜウェイトが60フレームではなく59フレームなんでしょうか。
これは、並列処理イベントを1回実行するために1フレーム必要とするためと考えられます。並列処理自身の1フレーム+ウェイト59フレームで合計60フレーム(1秒)というわけですね。
つまり並列処理で繰り返しイベントを作るには、一定間隔に指定したいフレーム数-1のウェイトを入れれば良いという事です。
ちなみに、並列処理イベントにウェイトを入れると毎フレーム実行しなくて良くなるのでゲームの負荷も下がります(^-^)
スクリプトでupdate処理に追加する方法
少し上級者向けの記事です。
例えば $gameMap.update() 処理の中にオリジナルの繰り返し処理を組み込みたいとします。
その時、○秒に1回だけ実行する処理を書きたい時によく紹介される方法としては、「Graphics.frameCount」の値を利用する方法があります。
つまり、「 if( Graphics.frameCount % 60 === 0 ) 」という条件分岐なら60フレームに1回だけtrueが返るので、1秒に1回だけ実行する処理が作れるというものです。
(「%」は余剰演算子といい、割り算の「余り」を計算する演算子)
ただしこの方法には大きな落とし穴があります。
それは、「Graphics.frameCount」に記録されているフレーム数はあくまで「ゲーム画面を実際に描画した回数」であって、「計算処理を行った回数」ではないという事です。
ツクールMVは処理の追いつかない低スペックな端末では、1秒間における計算の回数を自動で調整します。つまり描画回数と計算回数にはズレが生じる事が多いのです。
先ほどの「 if( Graphics.frameCount % 60 === 0 ) 」が$gameMap.update()の中で計算されるとすれば、その時点でGraphics.frameCountの値は「 余剰 === 0 」のタイミングを通り過ぎている可能性があります。すると1秒に1回どころか、2秒に1回になったり3秒に1回になったりとバラバラになってしまいます。
これを解決するには、少々面倒ですが「update処理が行われる度にその回数を記録する変数」を自分で用意しておく事です。その変数の値を利用すれば確実に「 余剰 === 0 」のタイミングを逃しません。