游戏开发论坛

 找回密码
 立即注册
搜索
查看: 13077|回复: 1

设计模式:State模式 ? 状态机在网络游戏中的应用

[复制链接]

1万

主题

1万

帖子

2万

积分

管理员

中级会员

Rank: 9Rank: 9Rank: 9

积分
20515
发表于 2012-2-21 22:22:00 | 显示全部楼层 |阅读模式
博客:愤怒的泡面 ? Angry Powman

  状态(State),指的是对象的某种形态,在当前形态下可能会拥有不同的行为和属性。状态机(State Machine),指控制对象状态的管理器。

  举个形象例子,在网络游戏中常常用到“状态”这一概念,如在WAR3中有 无敌,虚弱,隐身等角色状态,这些状态可以让角色拥有某种特殊能力。游戏角色也有最基本的状态,假想上至少会有两种:正常、死亡。

  游戏角色的状态不可能会无端端改变,它必须在某种条件下才会变换。比如圣骑士有“神圣护甲”这个技能,一旦使用了这个技能,那么角色就会进入了[无敌]状态,“使用技能”这一行为就是触发[无敌]状态的条件(事件)。再比如,角色在[正常]状态下打怪,但不小心被怪物给打死了,此时生命值为0,就会进入[死亡]状态,当然,如果你信春哥的话,那么还可能会拥有[满状态原地复活]这样的状态。

  总而言之,状态会在某个事件触发之后变更。不同的状态也有可能决定了对象的不同属性和行为。

//一般的状态
void handleState()
{
    if (event == "使用神圣护甲")
    {
        state = "无敌";
    }
    else if (event == "被怪物打,生命值为0")
    {
        state = "死亡";
    }
}

  这是一段伪代码,上面可以很清晰地看出状态的变化,event和state之间并没有直接的关系,但state却因为event而变化。这种是“一般状态”。还有一种就是“开关状态”,比如我们平常开灯关灯的,开关按钮就有[按下]和[弹起]两个状态,我们把按钮按下的话,那么按钮就处于[按下]状态,两种状态是相互影响的。如下:

void handleState()
{
    if (press_state == "开")
    {
        press_state = "关";
    }
    else if (press_state == "关")
    {
        press_state = "开";
    }
}

  这也能算是状态机?没错,这也可以说是状态机。但这只是很简单的逻辑处理。但这样的设计缺少弹性和通用性。而且在实际业务里面逻辑并不可能那么简单,于是有了State模式。像上面这种简单的逻辑,如果用上State模式的话就是大材小用了,这样会把事情复杂化。

状态模式的使用场景
  1.大量分支条件,并且这些条件依赖某些常量的情况下。
  2.行为由的状态决定,并且在运行过程中行为会不断随着状态而变化的情况下。

根据这样的特征,大致可以抽象出这样的一个结构:



这个结构总共由三个部分组成:
1.Context (GameRole)
定义用户感兴趣的接口

2.State (RoleState)
定义所有影响状态的行为的接口

3.Subclasses (Fight, Item, Skill)
定义从State继承的子类,子类实现每一个与Context的状态相关的行为接口

逻辑流程如下:
  1.Context(可以以参数的形式)把某个状态相关的请求委托给具体的Subclasses进行处理。
  2.Subclasses根据自身的特征,以决定应该执行哪些状态处理,并给Context返回一个新的Subclasses实例。
  3.Context接收到新的实例,调用自身相关处理函数,更新状态

  Context在此处充当了“状态机”的角色,亦即State Manager. 而Subclasses的实例则充当用户。用户把具体的状态变更结果提交给Context进行转换。

下面设计一段处理状态的程序:
  1.编写一个游戏角色,有站立,跑步,飞行三种状态。
  2.在每种状态下将根据体力是否充足而改变状态。

class GameState
{
public:
    void Stand(GameRole* role);
    void Running(GameRole* role);
    void Fly(GameRole* role);
};

class GameRole
{
public:
    void SetRoleState(GameState* state)
    {
        _state = state;
    }

public:
    void stand()
    {
        this->_state->Stand(this);
    }

    void run()
    {
        this->_state->Running(this);
    }

    void fly()
    {
        this->_state->Fly(this);
    }

private:
    GameState* _state;
};

class StandState : public GameState
{
public:
    void Running(GameRole* role)
    {
        if (role->EnoughPower == true)
        {
            role->SetRoleState(new RunningState());
        }
        else
        {
            role->SetRoleState(new StandState());
        }
    }

    void Fly(GameRole* role)
    {
        if (role->EnoughPower == true)
        {
            role->SetRoleState(new FlyState());
        }
        else
        {
            role->SetRoleState(new RunningState());
        }
    }
};

class RunningState : public GameState
{
public:
    void Stand(GameRole* role)
    {
        if (role->EnoughPower == true)
        {
            role->SetRoleState(new FlyState());
        }
        else
        {
            role->SetRoleState(new StandState());
        }
    }

    void Fly(GameRole* role)
    {
        if (role->EnoughPower == true)
        {
            role->SetRoleState(new FlyState());
        }
        else
        {
            role->SetRoleState(new RunningState());
        }
    }
};

class FlyState : public GameState
{
public:
    void Stand(GameRole* role)
    {
        if (role->EnoughPower == true)
        {
            role->SetRoleState(new RunningState());
        }
        else
        {
            role->SetRoleState(new RunningState());
        }
    }

    void Running(GameRole* role)
    {
        if (role->EnoughPower == true)
        {
            role->SetRoleState(new RunningState());
        }
        else
        {
            role->SetRoleState(new StandState());
        }
    }
};

  这是一段相对而言比较单一的代码,当然,这样的逻辑是不可能用在游戏上的,呵呵。这里只是为了演示一下状态的变更。
  
  Subclasses的内部对状态的变换规则进行了逻辑处理,因此它只关心自己的下一个状态是什么。这样由若干个状态类组合在一起,无形中形成了不同状态之间转换的规则,这样使状态机独立了出来,而不必涉及到状态的使用者。
 

0

主题

1

帖子

3

积分

新手上路

Rank: 1

积分
3
发表于 2012-3-6 06:01:00 | 显示全部楼层

Re:设计模式:State模式 ? 状态机在网络游戏中的应用

文中"event和state之间并没有直接的关系,但state却因为event而变化",请问怎样才算是有直接关系?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-9 14:47

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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