見出し画像

【GMS2 Knowledge】イベントの実行順について(2)

前回に引き続きイベントの実行順についてのお話。
ただ、今回はかなり使うStepイベントのお話なので、小技なんかも紹介しながら書いていきます。

ステップイベントとは?

ステップイベントというのは、毎フレーム呼び出されるイベントの事です。
フレームってなんだよ!って方は、別で調べてください。

ステップイベントにはStep Begin/Step(Normal)/Step Endの3種類があります。

その名の通りなのですが、具体的にどんな効果があるのかというと…知っておくとすごーーーーく便利なので覚えて帰ってくださいね。

3つのステップイベントの「実行順」

はい、また出ました実行順。
いや、それがこのシリーズの目玉ですから、嫌な顔しないでください。

まず、ルームに配置しているすべてのインスタンスのStep Beginイベントが実行されます。
全インスタンスのStep Beginイベントが終了したら、その時ルームに配置されているすべてのインスタンスのStepイベントが実行されます。

もう言わなくても分かるって?
そうです。全インスタンスのStepイベントが終了したら、その時ルームに配置されているすべてのインスタンスのStep Endイベントが実行されます。

よくある認識違い

上記で説明したように、すべてのインスタンスのStepイベントの終了を待って、次のStepイベントが実行されます。

よくある間違いは…

インスタンスA: Step Begin→Step→Step End
インスタンスB: Step Begin→Step→Step End

と思っていると大変です。
実際は以下です。

Step Begin: インスタンスA→インスタンスB→……
Step: インスタンスA→インスタンスB→……
Step End: インスタンスA→インスタンスB→……

大違いでしょ?

何に使うのさ!

そう思うでしょう。私もそう思います。
インスタンスの組み込み変数であるhspeedやvspeedはStep Endの前、Stepの後で書き換わります。
xprevious/yprevious(前のフレームの座標)も同様にStep Endから情報が書き換わります。
Stepイベントで座標へ配置され、Step End以降で情報が更新されている状態になるのです。

逆に言うと、Step Endまでは情報が更新されておらず、Stepまでは配置も行われないわけです。

ということはStep Beginで事前の計算や変数への代入などを行っておくと、情報としては書き換わる前なので、安心して計算ができるわけです。

これがインスタンスの生成順に行われてしまうと、何が最新の情報なのかがわからない状態で計算することになるので、バグが出やすくなるでしょう。

CreateではなくStep Beginで初期化する方法

上記の通り、Step Beginでは初期化したりするには便利なイベントです。
しかし「毎フレーム呼び出される」事に注意しなければなりません。

変数を宣言してしまうと、毎フレーム初期化されます。

これを回避する方法は、variable_instance_exists()を使用すると便利です。

if(!variable_instance_exists(id, "initialize")
{
    initialize = true;
    hsp = 0;
    vsp = 0;
}

variable_instance_exists()はインスタンスに変数があるかをチェックする関数です。
これにより、「initialize」が存在してなければif文の中で初期化する という作りです。

毎フレーム呼び出されても、2フレーム目以降は既に「initialize」が存在しているので、if文の中の初期化はされずにスルーされます。

GMLではこういったチェックでスクリプト呼び出しがあったりするので、ちょっとした小技として覚えておくと便利かもしれません。