游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4220|回复: 8

分享:大家有没有状态机的简单+实用的封装? 自已写

[复制链接]

14

主题

118

帖子

118

积分

注册会员

Rank: 2

积分
118
发表于 2007-2-22 15:27:00 | 显示全部楼层 |阅读模式
最近写的游戏老是有switch + call function.
于是使用表格把它们包起来,但是写得多了,还是做了个简单的封装:


class CTestState
{
public:
        friend class CStateMachine<CTestState>;
        enum MYSTATE
        {
                EM_S1 = 0,
                EM_S2 = 1
        };

        CTestState () { m_state.SetCaller(this); }//: m_state(this) {}
        CStateMachine<CTestState> m_state;        //状态机对象
       
        void Run();
        void OnEvent();
private:
        void MainState ( const EM_MACHINE_STATE &state ) {}
        void MainState2( const EM_MACHINE_STATE &state );
};

CStateMachine<CTestState>::MYDATA CStateMachine<CTestState>::s_info[] = {
        {CTestState::EM_S1, &CTestState::MainState, false},
        {CTestState::EM_S2, &CTestState::MainState2,true}
};

void CTestState::MainState2 (const EM_MACHINE_STATE &state )
{
        switch (state)
        {
        case EM_MS_INIT:
                cout << "MainState Init!" << endl;
                break;
        case EM_MS_RUN:
                cout << "MainState Running!" << endl;
                break;
        case EM_MS_DESTORY:
                cout << "MainState Destory!" << endl;
                break;
        }
}

int main(int argc, char* argv[])
{
        CTestState test;
        test.m_state.SafeSwitch( CTestState::EM_S1 );
        test.m_state.SafeSwitch( CTestState::EM_S2 );
        test.m_state.SafeSwitch( CTestState::EM_S1 );
        test.m_state.Call();
        return 0;
}

0

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2007-2-27 13:35:00 | 显示全部楼层

Re:分享:大家有没有状态机的简单+实用的封装? 自已写

没看懂

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2007-2-27 23:42:00 | 显示全部楼层

Re:分享:大家有没有状态机的简单+实用的封装? 自已写

不会吧,状态机也用类?
我都是直接编码的。(先画状态转换图再编码很轻松)
LZ不会是写自动机把(勇气~

6

主题

471

帖子

1047

积分

金牌会员

Rank: 6Rank: 6

积分
1047
发表于 2007-2-28 10:20:00 | 显示全部楼层

Re:分享:大家有没有状态机的简单+实用的封装? 自已写

#define EM_BEGIN_STATE_MAP(type)                                        {switch(type){
#define EM_ON_STATE(type)                                                        case type:On_##type(state);return;
#define EM_END_STATE_MAP                                                        }}
#define EM_DECLARE_STATE(type)                                        virtual void        On_##type(const EM_MACHINE_STATE &state);
#define EM_IMPLEMENT_STATE(classname,type)                void        classname::On_##type(const EM_MACHINE_STATE &state)

哈,我比较喜欢这么用.

14

主题

118

帖子

118

积分

注册会员

Rank: 2

积分
118
 楼主| 发表于 2007-3-15 11:43:00 | 显示全部楼层

Re: Re:分享:大家有没有状态机的简单+实用的封装? 自

filx: Re:分享:大家有没有状态机的简单+实用的封装? 自已写了个正在用的.

#define EM_BEGIN_STATE_MAP(type)                                        {switch(type){
#define EM_ON_STATE(type)                                                        case type:On_##...

哈,原来还有人这么用啊,好啊。
不过,尽管你用了宏,但代码不一定比我的那个版本快哦。
至少我要少你一次switch,并且我的那个Call函数是可以inline的,所以多出的一次函数调用也可以减少。

14

主题

118

帖子

118

积分

注册会员

Rank: 2

积分
118
 楼主| 发表于 2007-3-15 11:48:00 | 显示全部楼层

Re:分享:大家有没有状态机的简单+实用的封装? 自已写

to filx:
不过当你的状态转换时,有时需要初始化,你又是如何做的?
我是用一个参数来表示,并在SafeSwitch中加入不同的参数来判断的。

3

主题

24

帖子

24

积分

注册会员

Rank: 2

积分
24
发表于 2007-3-15 17:32:00 | 显示全部楼层

Re: 分享:大家有没有状态机的简单+实用的封装? 自已

一般状态机不用类用结构
比如
struct Menu
{
    char* name;
    void (*fn)();
}
利用结构里面函数指针来选用不同的函数

0

主题

2

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2007-3-25 19:16:00 | 显示全部楼层

Re:分享:大家有没有状态机的简单+实用的封装? 自已写

//状态管理类 StateManager.h
#pragma once

class cStateManager
{
        typedef struct sState{
                void (*Function)();
                sState* Next;
        }sState;

protected:
        sState* m_StateParent;

public:
        cStateManager():m_StateParent(NULL)
        {};
        ~cStateManager()
        {
                sState* StatePtr;
                while(StatePtr = m_StateParent){
                        m_StateParent = StatePtr->Next;
                        delete StatePtr;
                }
        }

        void Push(void (*Function)())
        {
                if(Function)
                {
                        sState* StatePtr = new sState;
                        StatePtr->Next = m_StateParent;
                        StatePtr->Function = Function;
                        m_StateParent = StatePtr;
                }
        }

        bool Pop()
        {
                sState* sStatePtr = m_StateParent;
                if(sStatePtr){
                        m_StateParent = m_StateParent->Next;
                        delete sStatePtr;
                }
                if(m_StateParent)
                        return true;
                return false;
        }

        bool Process()
        {
                if(m_StateParent)
                {
                        m_StateParent->Function();
                        return true;
                }
                return false;
        }
};

大家觉得偶的这个怎么?

0

主题

275

帖子

676

积分

高级会员

Rank: 4

积分
676
发表于 2007-3-25 23:08:00 | 显示全部楼层

Re:分享:大家有没有状态机的简单+实用的封装? 自已写

???是Task 模型..
FSM 比?全面性?用各?情?r
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-4-13 02:19

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表