|
有限状態機械の実装です ゲームなどではタイトルのシーンからゲームのシーンに移り変わるというように メンバ関数ポインタを使えばクラス内のメンバ関数に自由に飛び移れるような形で実装することができます 今回の全ファイル 以下に有限状態機械クラスの実装を示します // シーン内遷移を行うテンプレートクラス
// メンバ関数ポインタによる実装
#pragma once
template <typename T>
class StateMachine {
public:
StateMachine( StateMachine<T> (T::*f)() ) : func_( f ) {};
StateMachine<T> Exe( T* obj )
{
return (obj->*func_)(); // 現在のメンバ関数を実行して、StateMachineクラスのオブジェクトを返す
}
private:
StateMachine<T> (T::*func_)(); // Tクラスメンバ関数ポインタ
};
実装例は次のようになります #include "statemachine.h"
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
class GameFramework
{
private:
// 自分のクラスのテンプレート型の有限状態機械を作る
typedef StateMachine<GameFramework> STATE; // 長ったらしいのでtypedefで省略型作る
STATE m_State;
// 自分のクラスのメンバ関数ポインタを戻り値に返す
STATE TitleScene(){
printf("タイトルシーンです\n");
return &GameFramework::GameScene;// 次に実行したいメンバ関数のポインタを渡す
}
STATE GameScene(){
printf("ゲームシーンです\n");
if(rand() % 2 == 0){
return &GameFramework::GameOverScene;
}
return &GameFramework::EndingScene;
}
STATE GameOverScene(){
printf("ゲームオーバーシーンです\n");
return &GameFramework::TitleScene;
}
STATE EndingScene(){
printf("エンディングシーンです\n");
return &GameFramework::TitleScene;
}
public:
// コンストラクタ
GameFramework():m_State(&GameFramework::TitleScene){}
// デストラクタ
virtual ~GameFramework(){}
void Execute(){
m_State = m_State.Exe(this);
}
};
int main()
{
GameFramework game;
while(true){
// 処理が早すぎるので1秒休む
Sleep(1000);
// ゲーム実行
game.Execute();
// キー入力でループ抜ける
if(_kbhit())
break;
}
return 0;
}
この仕組みを導入すれば |