2024.06.30
#Godot Engine
#Snippets
GDScriptで状態機械を書く
状態機械(ステートマシン)は、自機が普通の状態と空中にいるときで受け付ける入力を変化させる、普通の状態とゴール時の演出でアニメーションを変化させる、といったゲーム内の要素の状態を記述する際に便利なプログラミングのパターンである。
if
文を使った実装
GDScriptで状態機械を書く場合、シーンに割り当てたスクリプト内で状態を表す列挙型 (enum
) を利用するとよい。
extends CharacterBody2D
enum PlayerState { Normal, Jumping, Goal, Died }
var player_state: int
func _ready():
# 初期状態の設定
player_state = PlayerState.Normal
func _physics_process(_delta):
if player_state == PlayerState.Normal:
# なんかする(例:立ってるだけのアニメーションを再生)
pass
elif player_state == PlayerState.Jumping:
# なんかする(例:飛んでるときのアニメーションを再生)
pass
move_and_slide()
enum
型に関する注意
注意点として、enum
型は内部的にint
型として扱われているようで、変数定義時に
var player_state: PlayerState # これはできない
と書くとPlayerState
なんてないぞというエラーが発生する。
enum
型のOR条件
複数種類の状態のいずれかを満たす場合、のような OR条件を記述する際には以下のように書くと大きな条件式でも見通しの良い記述にすることができる:
if player_state in [PlayerState.Normal, PlayerState.Jumping]:
# なんかする
pass
match
文を使った実装
GDScriptではif
文の代わりにmatch
文を用いて分岐を記述することができる。
CやJavaにあるswitch
文にも似ているが、どちらかというとRustのmatch
式に近く、ある程度高度なパターンマッチングも可能らしい。
extends CharacterBody2D
enum PlayerState { Normal, Jumping, Goal, Died }
var player_state: int
func _ready():
# 初期状態の設定
player_state = PlayerState.Normal
func _physics_process(_delta):
match player_state:
PlayerState.Normal:
# なんかする(例:立ってるだけのアニメーションを再生)
pass
PlayerState.Jumping:
# なんかする(例:飛んでるときのアニメーションを再生)
pass
_:
pass
move_and_slide()
match
文の最後にある_
は上のいずれの条件にもマッチしなかった場合にマッチする条件で、CやJava等のswitch
文におけるdefault
に相当するものと考えてよい。
OR条件を記述する際には以下のようにカンマ区切りにする:
match player_state:
PlayerState.Normal, PlayerState.Jumping:
# なんかする
pass