美文网首页
设计模式

设计模式

作者: 叫我颜先生 | 来源:发表于2018-06-21 22:43 被阅读0次

    简介

    Game Programming Patterns,游戏编程模式,大致看完了点,记录一下,以后再看再次深入学习时再补充,电子书地址


    命令模式

    译者原话:“命令是具现化的方法调用”。意味着将概念变成数据 ——一个对象——可以存储在变量中,传给函数。 所以称命令模式为“具现化方法调用”,意思是方法调用被存储在对象中。听起来像是回调

    命令模式是一种回调的面向对象实现。

    function makeMoveUnitCommand(unit, x, y) {
      // 这个函数就是命令对象:
      return function() {
        unit.moveTo(x, y);
      }
    }
    
    //行动以及撤销
    function makeMoveUnitCommand(unit, x, y) {
      var xBefore, yBefore;
      return {
        execute: function() {
          xBefore = unit.x();
          yBefore = unit.y();
          unit.moveTo(x, y);
        },
        undo: function() {
          unit.moveTo(xBefore, yBefore);
        }
      };
    }
    

    更多的使用回调函数实现,将方法封装好

    在按键控制角色移动跳跃等按键控制上 可以实现更多的自定义 而不是很多的绑定,每一个按键的事件都是一个回调


    原型模式

    三个怪物,基本,弓兵,长矛兵

    不用建一个怪物基类,然后下面创建三种

    而是在基本兵的基础上,衍生出弓兵与长矛兵,以基本兵为原型


    单例模式

    游戏中,很多例如声音,声音管理器,特效,特效管理器,模型,模型管理器等

    很多的管理器都成了单例类

    例如,一个子弹,子弹管理器

    class Bullet
    {
    public:
      int getX() const { return x_; }
      int getY() const { return y_; }
    
      void setX(int x) { x_ = x; }
      void setY(int y) { y_ = y; }
    
    private:
      int x_, y_;
    };
    
    class BulletManager
    {
    public:
      Bullet* create(int x, int y)
      {
        Bullet* bullet = new Bullet();
        bullet->setX(x);
        bullet->setY(y);
    
        return bullet;
      }
    
      bool isOnScreen(Bullet& bullet)
      {
        return bullet.getX() >= 0 &&
               bullet.getX() < SCREEN_WIDTH &&
               bullet.getY() >= 0 &&
               bullet.getY() < SCREEN_HEIGHT;
      }
    
      void move(Bullet& bullet)
      {
        bullet.setX(bullet.getX() + 5);
      }
    };
    

    子弹需要管理器嘛

    class Bullet
    {
    public:
      Bullet(int x, int y) : x_(x), y_(y) {}
    
      bool isOnScreen()
      {
        return x_ >= 0 && x_ < SCREEN_WIDTH &&
               y_ >= 0 && y_ < SCREEN_HEIGHT;
      }
    
      void move() { x_ += 5; }
    
    private:
      int x_, y_;
    };
    

    这样直接就可以了

    单例有时候会增加其他类的代码量,最好的是OOP(对象自己管理好自己)

    所以,游戏中很多的声音管理器,特效管理器,模型管理器等等,可以都放到一个Game管理器中,通过这个game来获取每一个管理器下方法

    class Game
    {
    public:
      static Game& instance() { return instance_; }
    
      // 设置log_, et. al. ……
    
      Log&         getLog()         { return *log_; }
      FileSystem&  getFileSystem()  { return *fileSystem_; }
      AudioPlayer& getAudioPlayer() { return *audioPlayer_; }
    
    private:
      static Game instance_;
    
      Log         *log_;
      FileSystem  *fileSystem_;
      AudioPlayer *audioPlayer_;
    };
    
    Game::instance().getAudioPlayer().play(VERY_LOUD_BANG);
    

    观察者模式

    观察者模式,也就mvc架构,C#将其嵌入了语法event

    例如游戏中的成就系统,要是摸个环节达成成就 就调用成就 这样就太乱了

    成就单独分隔开

    //观察者 监听
    class Observer
    {
    public:
      virtual ~Observer() {}
      virtual void onNotify(const Entity& entity, Event event) = 0;
    };
    
    //成就作为观察者处理消息
    class Achievements : public Observer
    {
    public:
      virtual void onNotify(const Entity& entity, Event event)
      {
        switch (event)
        {
        case EVENT_ENTITY_FELL:
          if (entity.isHero() && heroIsOnBridge_)
          {
            unlock(ACHIEVEMENT_FELL_OFF_BRIDGE);
          }
          break;
    
          // 处理其他事件,更新heroIsOnBridge_变量……
        }
      }
    
    private:
      void unlock(Achievement achievement)
      {
        // 如果还没有解锁,那就解锁成就……
      }
    
      bool heroIsOnBridge_;
    };
    

    此时还需要一个添加删除观察者的管理类 通知下发给每个注册的管理者

    class Subject
    {
    protected:
      void notify(const Entity& entity, Event event)
      {
        for (int i = 0; i < numObservers_; i++)
        {
          observers_[i]->onNotify(entity, event);
        }
      }
    
      // 其他代码…………
    };
    

    享元模式

    抽象出共有的属性 修改不同的属性

    渲染一片森林,每棵树都有网格贴图位置颜色等,这样GPU消耗会大

    class Tree
    {
    private:
      Mesh mesh_;
      Texture bark_;
      Texture leaves_;
      Vector position_;
      double height_;
      double thickness_;
      Color barkTint_;
      Color leafTint_;
    };
    

    一个老方法就是使用相同的网格和纹理,只改变不同树位置颜色信息

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

    相关文章

      网友评论

          本文标题:设计模式

          本文链接:https://www.haomeiwen.com/subject/obchyftx.html