Moai SDK でゲームを作ろう (状態遷移の処理について)

前回の記事 にて Android の実機にウィンドウを表示させるあたりまで作成しました。今回はゲームの状態遷移まわりの実現方法について説明します。

ゲームの状態遷移

ここでの状態遷移とは「最初のメニュー画面」「ステージ選択画面」といった、大きく切り替わる単位だとします。今回作っているゲームは、選択したステージをクリアできるようにするタイプで、状態遷移の図は下記のようになります。

dot_inline_dotgraph_1

このような状態と遷移を実現するにあたり、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 に慣れるのを兼ねてゲーム起動直後の画面を作成したいと思います。