前回の記事 にて Android の実機にウィンドウを表示させるあたりまで作成しました。今回はゲームの状態遷移まわりの実現方法について説明します。
ゲームの状態遷移
ここでの状態遷移とは「最初のメニュー画面」「ステージ選択画面」といった、大きく切り替わる単位だとします。今回作っているゲームは、選択したステージをクリアできるようにするタイプで、状態遷移の図は下記のようになります。
このような状態と遷移を実現するにあたり、Lua で State_machine クラスと state モジュールを作成します。State_machine クラスと state モジュール、状態の一つである first_menu_state.lua を順に示します。
state_machine.lua
-- 状態遷移の処理
_G.State_machine = {}
function State_machine:new ()
?? local members = {
????? states_ = {},
????? current_state_ = nil,
?? }
?? State_machine.__index = State_machine
?? setmetatable(members, State_machine)
?? return members
end
function State_machine:set_state (state)
?? self.current_state_ = nil
?? self:change_state(state)
end
function State_machine:change_state (state)
?? if self.current_state_ ~= nil then
????? self.current_state_["Exit"]()
?? end
?? self.current_state_ = state
?? self.current_state_["Enter"]()
end
function State_machine:execute ()
?? if self.current_state_ ~= nil then
????? self.current_state_["Execute"]()
?? end
end
state.lua
-- 状態遷移の初期化
module("state", package.seeall)
require("state_machine")
require("first_menu_state")
require("stage_select_state")
require("stage_play_state")
require("option_state")
require("credit_state")
local state_machine_ = nil
function initialize ()
?? state_machine_ = State_machine.new()
end
function set_state (state)
?? state_machine_:set_state(state)
end
function start ()
?? local thread = MOAIThread.new()
?? local function update_function ()
????? while true do
???????? state_machine_:execute()
???????? coroutine.yield()
????? end
?? end
?? thread:run(update_function)
end
function change_state (state)
?? state_machine_:change_state(state)
end
first_menu_state.lua
-- 最初のメニュー
_G.First_menu_state = {}
First_menu_state["Enter"] =
?? function ()
-- 画面の作成などのセットアップの処理
-- ...
?? end
First_menu_state["Execute"] =
?? function ()
????? -- !!! ボタンが押された時の処理とか
?? end
First_menu_state["Exit"] =
?? function ()
-- システムのクリーンアップの処理
-- ...
?? end
このような仕組みについては O’Reilly から出版されている「ゲーム開発者の AI 入門」や「ゲーム AI プログラミング」に詳しく説明してあります。お勧めです。
簡単に説明すると、状態毎に Enter, Execute, Exit という名前に関数を登録しておき、その状態に入ったときに Enter の関数を実行し、状態から出るときに Exit の関数を実行します。また Execute の関数は、その状態にいる間に毎回呼び出されます。この関数を登録しているのが例えば first_menu_state.lua で、実際に状態遷移の処理をしているのが state_machine.lua です。state.lua では、first_menu_state.lua などを読み込む処理をしています。
ここまででゲームの全体的な状態を管理するコードが作成できたので、次回の記事では Moai SDK に慣れるのを兼ねてゲーム起動直後の画面を作成したいと思います。
