游戏设计模式-命令模式

游戏中,玩家的输入方式有很多种,例如键盘、鼠标等。玩家输入操作,游戏需要调用相应的逻辑,最简单的处理方式是:

if (Input.GetKeyDown("Q"))

        Jump();

else if (Input.GetKeyDown("T"))

        Idle();

else if (Input.GetKeyDown("A"))

        Attack();

else if (Input.GetKeyDown("Z"))

        Skill();

对应每一个按钮的输入,直接调用相应的操作函数。

但这样的处理有一个问题:不支持玩家改键,假如玩家想要用按键Q来调用Skill,而不是Jump,那么上面的代码就有些麻烦。

命令模式可以解决这个问题。

命令模式的定义:

将一个请求封装成一个对象,从而允许你使用不同的请求、队列或日志将客户端参数化,同时支持请求操作的撤销与恢复。

将操作函数进行封装,我们可以改造上面的代码:

定义命令基类

class Command

{

public:

virtual void Run() = 0;

}

定义攻击命令

class AttackCommand:public Command

{

public:

virtual void Run(){Attack();}

}

定义跳跃命令

class JumpCommand:public Command

{

public:

virtual void Run(){Jump();}

}

……(依次定义剩余的命令)

这样,我们使用对象,将直接的行为函数调用,封装在其内部。然后我们定义一个管理类,来管理整个游戏中的所有按键

定义操作管理类

class InputHandler

{

public:

//默认按键

void Init()

{

input_map["Q"] = new JumpCommand();

input_map["T"] = new IdleCommand();

input_map["A"] = new AttackCommand();

input_map["Z"] = new SkillCommand();

}

//用户自定义按键

void ChangeButton(std::string button_name,int type)

{

//根据type,将按键映射到对应的命令

//注意内存释放

}

//处理玩家输入

void HandleInput(std::string input)

{

input_map[input]->Run();

}

private:

std::unorder_map input_map;

}

命令模式,不单只是解决了按键的映射问题,还有别的好处:

可以将行为的对象解耦,调用对应的函数,这样,同样一份攻击代码,既可以用于玩家角色,也可以用于NPC,敌人等。

player->attack();

enemy->attack();

npc->attack();

 实例是可以存储的,因此,我们可以按照时间戳的方式,将命令依次存放起来,用于撤销和回放。(只需要记录命令的参数,实现对应的run函数和cancelrun函数)

定义命令基类

class Command

{

public:

virtual void Run(Parameter && p) = 0;

virtual void CancelRun() = 0;

private:

Parameter parameter;

CancelParameter parameter;

}

你可能感兴趣的:(游戏服务器,游戏,架构,命令模式)