c++ - 另一个与设计相关的 C++ 问题

标签 c++ polymorphism virtual design-patterns

您好!

我正在尝试在 C++ 编码模式中找到一些最佳解决方案,这是我的游戏引擎相关问题之一。

看看游戏对象声明(我删除了几乎所有与问题无关的内容)

// Abstract representation of a game object
class Object : 
public Entity, 
       IRenderable, ISerializable {

   // Object parameters
   // Other not really important stuff

public:
   // @note Rendering template will never change while
   // the object 'lives'
   Object(RenderTemplate& render_template, /* params */) : /*...*/ { }

private:
   // Object rendering template
   RenderTemplate render_template;

public:
   /**
    * Default object render method
    * Draws rendering template data at (X, Y) with (Width, Height) dimensions
    *
    * @note If no appropriate rendering method overload is specified 
    * for any derived class, this method is called
    *
    * @param  Backend & b  
    * @return void
    * @see         
    */
   virtual void Render(Backend& backend) const {
      // Render sprite from object's
      // rendering template structure
      backend.RenderFromTemplate(
         render_template, 
         x, y, width, height
         );
   }
};

这里还有IRenderable接口(interface)声明:

// Objects that can be rendered
interface IRenderable {
   /**
    * Abstract method to render current object
    *
    * @param  Backend & b  
    * @return void
    * @see
    */
   virtual void Render(Backend& b) const = 0;
}

以及从 Object 派生的真实对象的示例(经过严格简化:)

// Ball object
class Ball : public Object {
   // Ball params
public:
   virtual void Render(Backend& b) const {
      b.RenderEllipse(/*params*/);
   }
};

我想要的是拥有某种标准函数的能力,如果没有适当的重载,它会为对象绘制 Sprite (这是 Object::Render)。

因此,可以拥有不带 Render(...) 方法的对象,并且如果您尝试渲染它们,则会调用此默认的 sprite-rendering 东西。并且,可以有专门的对象,它们定义了自己的呈现方式。

我认为,这种做事方式相当不错,但我想不通的是—— 有什么方法可以将对象的“正常”方法(如 Resize(...)Rotate(...))实现从它们的渲染中分离出来实现?

因为如果一切都按照前面描述的方式完成,一个实现任何类型对象的通用 .cpp 文件通常会混合 Resize(...) 等方法实现和这个 virtual Render(...) 方法,这似乎是一团糟。我实际上想在一个地方有对象的渲染过程,在另一个地方有它们的“逻辑实现”。

有没有一种方法可以做到这一点(也许是替代模式或技巧或提示)或者这就是所有这些多态虚拟东西在代码放置方面很糟糕的地方?

最佳答案

在这个特定的示例中,我不确定将 ResizeRender 分开是否可取,因为 Resize 对渲染有直接影响渲染图像。

我这样做的方法是让 Entitycontain Renderable。例如。 Entity 会有一个成员变量,它是要渲染的 Sprite 。当实体变得可见时,它将 Sprite 交给渲染系统并说,基本上,“好的,每一帧都画这个,直到我告诉你停止”,尽管渲染引擎会剔除屏幕外的对象和其他疯狂的事情。也许很明显,渲染引擎然后维护一个可渲染的列表(或者如果你想从线或粒子中分离出 Sprite 以提高渲染效率,则可能是几个列表),然后它只是在需要时翻阅那些不那么复杂的项目列表抽签。

这样,实体可以控制可渲染对象,它可以缩放它或旋转它(即操纵它的渲染矩阵),但它不需要决定什么时候适合绘制它它是否“活着”。不过,渲染引擎只知道如何绘制相关项目,不需要了解您的实体图。

关于c++ - 另一个与设计相关的 C++ 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2686429/

相关文章:

c++ - 多边形线碰撞检测

c++ - OpenGL 着色器有时可以编译,有时则不能

haskell - 是否存在使用代数数据类型或多态性的 OOP 抽象类的 Haskell 等效项?

c++ - 发送类实例时是否会调用覆盖,就好像它是没有覆盖的类型一样?

c++ - 如何在 Scintilla 中设置边距蒙版?

c++ - 在没有 c++11 的情况下删除 map 最后插入的元素的正确方法是什么?

c++ - 为什么一个虚类的析构函数没有自动添加到虚表中?

C# - 当 Dog 是 Animal 的子类时,如何将 List<Dog> 转换为 List<Animal>?

c# - 覆盖但不调用

c++ - 模板化子类的无效协变返回类型