有关游戏架构/设计模式的建议
我一直在研究2D RPG,有一段时间了,我发现自己做出了一些糟糕的设计决定。特别是有些事情引起了我的问题,所以我想知道其他人过去曾使用或将采用哪种设计。 作为一点背景,我从去年夏天的业余时间开始研究它。我最初使用C#进行游戏,但是大约3个月前,我决定切换到C ++。自从我大量使用C ++以来,我一直想对C ++有所了解,并且认为像这样的有趣项目将是一个很好的动力。我一直在广泛使用boost库,并且一直在将SFML用于图形,将FMOD用于音频。 我写了很多代码,但是我正在考虑废弃它并重新开始。 这是我关注的主要领域,并希望就其他人已解决或将要解决的正确方法获得一些意见。 1.周期性依赖 当我做在C#中的比赛中,我并没有真的要这个担心,因为它不是一个问题存在。转向C ++,这已经成为一个相当大的问题,让我觉得我可能设计不正确。我真的无法想象如何解耦我的班级,仍然让他们做我想要的事情。以下是依赖链的一些示例: 我有一个状态效果课。该类有许多方法(应用/取消应用,刻度线等)将其效果应用于角色。例如, virtual void TickCharacter(Character::BaseCharacter* character, Battles::BattleField *field, int ticks = 1); 每当角色受到状态影响时,都会调用此函数。它可用于实现诸如Regen,Poison等的效果。但是,它也引入了对BaseCharacter类和BattleField类的依赖。自然,BaseCharacter类需要跟踪当前对它们起作用的状态影响,因此这是周期性的。《战地风云》需要跟踪战斗方,并且该方类别有一个引入了另一个周期性依赖关系的BaseCharacters列表。 2-活动 在C#中,我大量使用了委托来勾勒角色,战场等事件(例如,当角色的健康状况发生变化,状态更改,状态效果被添加/删除时,都有一个委托。 )和战场/图形组成部分将与这些代表挂钩,以增强其效果。在C ++中,我做了类似的事情。显然,没有直接等效于C#委托的东西,所以我创建了如下代码: typedef boost::function<void(BaseCharacter*, int oldvalue, int newvalue)> StatChangeFunction; 在我的角色课上 std::map<std::string, StatChangeFunction> StatChangeEventHandlers; 每当角色的状态更改时,我都会迭代并调用地图上的每个StatChangeFunction。虽然有效,但我担心这是做事的不好方法。 3-图形 这是大事。它与我正在使用的图形库无关,但更多是概念上的。在C#中,我将图形与很多类结合在一起,我知道这是一个糟糕的主意。这次我想做到这一点,所以尝试了另一种方法。 为了实现我的图形,我将游戏中与图形相关的所有图形想象为一系列屏幕。即有一个标题屏幕,一个角色状态屏幕,一个地图屏幕,一个清单屏幕,一个战斗屏幕,一个战斗GUI屏幕,基本上,我可以根据需要将这些屏幕彼此叠加以创建游戏图形。无论活动屏幕是什么,都拥有游戏输入。 我设计了一个屏幕管理器,可以根据用户输入推送和弹出屏幕。 例如,如果您在地图屏幕上(平铺地图的输入处理程序/可视化器)并按下了“开始”按钮,则会向屏幕管理器发出呼叫,将主菜单屏幕推到地图屏幕上并标记地图屏幕无法绘制/更新。播放器将在菜单中导航,这将酌情向屏幕管理器发出更多命令,以将新屏幕推送到屏幕堆栈上,然后在用户更改屏幕/取消按钮时弹出它们。最后,当播放器退出主菜单时,我将其弹出并返回到地图屏幕,将其标记为要绘制/更新并从那里去。 战斗画面会更加复杂。我将有一个屏幕作为背景,一个屏幕使战斗中的每个参加者形象化,以及一个屏幕来使战斗的UI形象化。UI将挂接到角色事件中,并使用这些事件来确定何时更新/重绘UI组件。最后,每一次具有可用动画脚本的攻击都将在弹出屏幕堆栈之前调用一个附加层来对其自身进行动画处理。在这种情况下,每一层都始终标记为可绘制和可更新,并且我得到了一堆处理我的战斗图形的屏幕。 尽管我还无法使屏幕管理器正常工作,但我认为可以花一些时间。我的问题是,这是否完全值得?如果这是一个糟糕的设计,我想在投入太多时间制作我需要的所有屏幕之前先了解一下。您如何为游戏建立图形?