《游戏编程模式》读书笔记 (一)

设计模式

命令模式

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

命令就是面向对象的回调。

对应代码c++

// 基类
class Command
{
    public:
    virtual ~Command(){}
    virtual void execute(GameActor& actor)=0;
};
class JumpCommand: public Command
{
    public:
    virtual void execute(GameActor& actor){
        actor.jump();
    }
}
class FireCommand :public Command
{
    virtual void execute(GameActor& actor){
        actor.fireGun();
    }
}
// ...
// 空值命令对象模式
class NullCommand: public Command
{
    virtual void execute(GameActor& actor){}
}
// 输入处理
class InputHandler
{
    public:
    Command* handleInput();
    // 绑定其他命令
    private:
    Command* buttonX_;
    Command* buttonY_;
    Command* buttonA_;
    Command* buttonB_;
}
void InputHnadler: handleInput()
{
    if (isPressed(BUTTON_X)) return buttonX_;
    else if (isPressed(BUTTON_Y)) return buttonY_;
    else if (isPressed(BUTTON_A)) return buttonA_;
    else if (isPressed(BUTTON_B)) return buttonB_;
    
}

// 角色执行命令
Command* command = inputHandler.handleInput();
if(command)
{
    command->exectue(actor);
}

在命令与角色之间加入间接层,可以使得玩家以及AI操控任意的角色。如果我们把命令序列化,便可以通过网络发送数据流,这个是多人游戏中主要的一部分。

撤销与重做

c++:

// 基类
class Command
{
    public:
    virtual ~Command(){}
    virtual void execute(GameActor& actor)=0;
    virtual void undo()=0;
};
class MoveUnitCommand: public Command
{
    public:
    MoveUnitCommand(Unit* unit,int x,int y): unit_(unit),x_(x),y_(y)
    {}
    virtual void execute()
    {
        unit_->moveTo(x_,y_);
    }
    private:
    Unit* unit_;
    int x_;
	int y_;
}

与备忘录相比,节约内存。

重做在游戏中不常见,但回放很常见。

JS实现(使用闭包)

function makeMoveUnitCommand(unit,x,y){
    var xBefore,yBefore;
    return function(){
        execute:function(){
            xBefore = unit.x();
            yBefore = unit.y();
            unit.moveTo(x,y);
        },
        undo: function(){
            unit.moveTo(xBefore,yBefore)
        }
    }
}
  • 如果有很多不同的命令类,可以定义一个具体的基类来实现更高层次的方法。命令主要的execute()变成了子类沙盒。
  • 如果在对象分层等那些不明确执行命令的角色情况下,可以将命令下放給其从属对象。可以参考责任链。
  • 同样的命令实例重复,可以使用享元模式。

享元模式

class TreeModel
{
    private:
    Mesh mesh_;
    Texture bark_;
    Texture leaves_;
}
class Tree
{
    private:
    TreeModel* model_;
    
    Vector position_;
    double height_;
    double thicknes_;
    Color barkTint_;
    Color leafTint_;
}

与类型对象模式对比:

​ 类型对象通过把“类型”对象化,可以尽可能较少定义新类型的数量,而享元模式却更加注重效率。

应用:

TiledMap

* 一般来说,享元对象总是不可变的。

  • 按需创建享元。在接口体上封装,来隐藏构造函数。可以参考工厂方法模式。
  • 查找实例化的享元,对象池模式。
  • 状态模式下,使用享元。以及上一章节提到的命令模式。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值