动画架构模式

6
我正在写一个游戏项目作为业余爱好,并且正在寻找一些关于如何最好地组织我的游戏对象及其各种动画的建议。
例如,我有一个叫做“巫师”的类,还有一个叫做“龙”的类。一个巫师至少有10个不同的特定动画与之相关联,取决于它的状态,龙也是如此。
那么我的问题是:有没有标准模式来组织这些对象,使其高效且易于扩展(即应该容易添加新的动画和新的对象)?
我对如何继续推进这个项目有各种各样的想法,但我不想犯错,因为这是游戏架构中非常重要的一部分。对于小游戏,这似乎很容易实现,但随着游戏变得越来越大,我担心它会变得难以管理。

从现有的开源游戏中借鉴创意。 - Hamish Grubijan
std::map <state, animation> - 用于内部状态到动画存储,任何开放格式用于外部存储。 - Sergey Miryanov
2个回答

1
我建议创建一个名为“Character”的接口,它定义了所有这些实体应该具备的功能。然后你的Dragon和Wizard类只是实现。
另一种方法是创建一个基类,从中扩展并使用它来控制与大型项目相关的“分层扩展”,通过绘制对象的层次结构并识别扩展的基类来实现。

0

不,绝对没有标准模式。

我的建议是避免初学者面向对象设计的陷阱,即试图为所有东西找到一个单一的共同“基类”接口。你的龙和巫师大不相同,除了可爱的代码抽象之外,试图合并这两个接口没有任何好处。记住,继承不是代码重用的工具。

最简单的方法是让每个对象维护自己的内部状态(正如你已经描述的那样),并能够绘制该状态。这就是一个老派的 switch 语句可能比使用多态获得相同效果更清晰的地方。例如:

class Dragon {
 enum State { asleep, flying, breathing_fire };
public:
 void draw () { /* old-school switch */
    switch (cur_state){
    case asleep: draw_asleep ();
    case flying: draw_flying ();
    case breathing_fire: draw_breathing_fire();
    }
  }
private:
  void draw_asleep ();
  void draw_flying ();
  void draw_breathing_fire();
};

有经验的C++开发人员会对上面的代码感到惊讶(他们应该这样做),因为switch语句几乎完全可以实现多态方法调用——运行时分派。(甚至更加神秘:一张方法地址表。)我个人认为,对于这种特定类型的类,即封装状态机的单个公共接口,switch语句更清晰、更易维护,因为它使状态机跳转明确。我认为,我也清楚地意识到这通常是不好的C++设计。

这种设计的摩擦是由状态机和单个公共接口之间的分界线引起的。一个正在睡觉的龙显然不同于一个飞行的龙。事实上,它们几乎没有任何共同点。但是高层设计说这两个是相同的龙。真是一团糟!你为每个状态创建不同的Dragon对象吗?不,因为那会向调用者暴露状态概念。你为每个状态创建不同的内部辅助对象并将其分派给它们?可能是,但很快就会变得混乱。上述方法是两者之间的妥协。把switch语句看作是隔离丑陋的方式。公共接口干净,私有接口也是如此。只有switch语句包含肮脏的混乱。考虑这种方法,也考虑其他建议。

最后,为了绘制您的向导和龙,一个简单的包装模板或函数对象就足够了:
struct Draw {
    template <class S>
    void operator()(S& s) { s.draw (); }
};

重点是,您不必合并两个不同的类,只因为它们都支持相同的逻辑操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接