前回の記事 にて 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 に慣れるのを兼ねてゲーム起動直後の画面を作成したいと思います。