代码之家  ›  专栏  ›  技术社区  ›  Emiliano

基于混合组件的设计与模型视图(控制器)模式

c++
  •  0
  • Emiliano  · 技术社区  · 14 年前

    我正在开发一个二维游戏,我想把游戏引擎和图形分开。 我决定使用模型视图模式,方法如下:游戏引擎拥有游戏的实体(enemy model、bullet model、explosion model),这些实体实现接口(敌人、子弹、爆炸)。

    创建实体时,视图接收事件,获取指向接口的指针:这样,视图只能使用接口方法(即请求信息以执行绘图),并且不能更改对象状态。视图有自己的onw类(enemyview、bulletview、explosionview),这些类拥有指向接口的指针。 (还涉及到一个事件基模式,因此模型可以通知视图有关实体的更改,因为纯查询方法是不正确的,但我不会在这里讨论它)。

    *模型类使用编译时组件方法:它们使用boost::fusion库来存储不同的状态组件,如positioncomponent、healthcomponent等。

    目前,视图不知道基于组件的设计,只知道模型视图部分:为了得到敌人的位置,它调用敌人::get xy()方法。实现接口的enemymodel将此调用转发到positioncomponent并返回结果。

    由于项目符号也有位置,所以我也必须将get-xy方法添加到项目符号中。然后,bulletmodel使用与enemymodel类相同的实现(即,它转发调用)。

    这种方法会导致有很多重复的代码:接口有很多相似的方法,*模型类都有很多转发方法。

    所以我基本上有两个选择:

    1)公开基于组件的设计,使每个组件也有一个接口:视图可以使用这个接口直接查询组件。它使视图和模型保持分离,只在组件级别而不是实体级别。

    2)放弃模型视图部分,转而进行基于组件的纯设计:视图只是一个组件(renderablecomponent部分),基本上可以完全访问游戏引擎。

    根据你的经验,哪种方法最好?

    3 回复  |  直到 14 年前
        1
  •  1
  •   Eli Iser    14 年前

    我会给我两分钱的。从您描述的问题来看,在我看来,您需要一个抽象类来执行所有类中常见的操作(如 get_xy 适用于子弹、敌人、爆炸等)。这个类是一个执行基本咕噜工作的游戏实体。如果需要,继承类可以重写它。

    这个抽象类应该是所有接口的核心(幸运的是,你在C++中,在类、抽象类和接口之间没有物理差异)。因此,视图将了解特定的接口,并且仍然具有通用的实体方法。

    我设计的经验法则——如果多个类具有相同的数据成员或方法,那么它可能是它们继承的单个类。

    无论如何,暴露模型类的内部结构不是一个好主意。说你想用别的东西代替Boost?你必须重写整个程序,而不仅仅是相关部分。

        2
  •  1
  •   Wernight    14 年前

    MVC 对游戏来说并不容易,因为当游戏变得更大(包括菜单、敌人、关卡、图形用户界面…)和转换时,游戏就会中断。

    组件或 实体系统 很适合玩游戏。

    作为一个简单的例子,您可以考虑使用 高分子量聚乙烯 . 转换仍然有问题,但至少您的代码将以更干净的方式组合在一起。您可能希望您的坦克的代码(渲染和逻辑)紧密结合在一起。

        3
  •  1
  •   user429921    14 年前

    已经有专门为基于代理的系统设计的表示体系结构,例如表示抽象控制。在设计这样一个系统时,最困难的部分就是你最终会在代理之间形成一系列的硬连接。

    您可以这样做,但不要使用OO继承来建模消息传递层次结构。你会后悔的。如果您考虑一下,您真的对使用OO继承关系不感兴趣,因为定义的接口实际上只是对象可以响应的“函数记录”。在这种情况下,您最好对通信协议进行正式建模。

    如果你有问题,请提问——这不是一个显而易见的解决方案,很容易出错。