《游戏编程模式》各种模式汇总(二)

  1. 类型对象

当子类过多,并且子类的属性相似时,可以用类型对象来将“类型”模块化,从继承的模式中独立

出来。

例子:我们有一个Monster基类,如果是继承模式,我们需要创建很多个子类来表示具体的怪物,

比如龙子类,史莱姆子类等,但是这些子类都有相似的属性,比如血量攻击力等,只是他们的值

不同。这样会游戏数据耦合进代码中,给修改和添加带来许多麻烦。因此,我们可以使用一个单

一的Monster类,所有怪物都是这个类的实例,在这个Monster类中加入一个Tpye类实例,这

个类包含了怪物的血量、攻击力、种类等信息。

/*---------------------------------类型对象-----------------------------
*/

// -------------------------------Demo-----------------------------//
/*
生成怪物的流程:
1、从JSON文件中读取Type的属性值,如血量、名字啥的
2、组成一个Type对象,保存在某处(这一步是否可以用持久化数据结构来做?)
3、用这个type对象构造Monster
*/
class Monster
{
    friend class Type;

private:
    Monster(Type &type) : _health(type.getStartHealth()), _type(type) {}
    int _health; // 当前的血量
    Type &_type; // 怪物类型

public:
    ~Monster() {}
    int getHealth() const { return _health; }
    Type &getType() const { return _type; }
};

class Type
{
private:
    int _startHealth; // 初始血量
    string _typeName;

public:
    Type(int startHealth) : _startHealth(startHealth) {}
    ~Type() {}
    Monster *newMonster() { return new Monster(*this); }
    int getStartHealth() const { return _startHealth; }
    string &getTypeName() const { return _typeName; }
};
  1. 享元模式

实际上,享元模式类似与类的抽象,将需要共享的属性整合进一个类中,程序运行开始时预先创

建需要的实例对象集合(或许可以用枚举类实现?),访问者只需要构造一个指针数组,指向

这个类的实例对象,即可得到对应的属性。(其实就是某种意义上的继承,区别在于继承会复

制父类的属性到子类,而享元模式用指针实现内存共享访问)

/*---------------------------------享元模式-----------------------------
*/

// -------------------------------Demo-----------------------------//
// 场景:创建一个存在多棵树的世界,树的高度和宽度是固定的
class Tree
{
private:
    int _hight;
    int _width;

public:
    int getHeight() const { return _hight; }
    int getWidth() const { return _width; }
    Tree(int hight, int width) : _hight(hight), _width(width) {}
    ~Tree() {}
};

class World
{
private:
    // 创建一个指针数组,代表在100*100的方格上放置树
    Tree *_tiles[100][100];
    // 树的种类集合
    Tree ATree, BTree, CTree;

public:
    // 在世界创建时,初始化这些对象
    World() : ATree(1, 1), BTree(1, 2), CTree(2, 2) {}
    ~World() {}

    // 生成树
    void genTree()
    {
        for (int i = 0; i < 100; i++)
            for (int j = 0; j < 100; j++)
            {
                _tiles[i][j] = &ATree;
            }
    }
};
  1. 子类沙箱

基类负责与其他所有外部系统耦合,子类只与基类耦合,不调用任何系统外的方法。在基类中提供

各种控制的函数,子类只需要调用这些函数就能完成控制对象的目的。这样构成了一个扁平化的继

承树。

/*---------------------------------子类沙箱-----------------------------
*/

// -------------------------------Demo-----------------------------//
// 基类与其他系统(如物理系统,渲染系统耦合)
class Superpower
{
protected:
    virtual void active() = 0;
    void move(double x, double y)
    {
        // 实现代码,与其他系统耦合
    }
    void playSound(double volume)
    {
        // 实现代码,与其他系统耦合
    }

public:
    virtual ~Superpower() {}
};

class Fly : public Superpower
{
protected:
    virtual void active() override
    {
        move(1, 2);
        playSound(1.0f);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值