听起来你可能会很好地阅读Model-View-Controller 模式。您不必拘泥于它(例如,在某些情况下,允许模型和视图之间有一些重叠是有意义的),但是对它有很好的理解将有助于您构建任何具有大量图形对象的程序和控制它们的逻辑,以及广播状态或将其保存到光盘(游戏保存)等的需要。
您还必须意识到 cocos2d 提供了一个很好的系统来构建图形场景图并有效地渲染它,但它并没有为编程游戏提供完整的基础设施。从这个意义上说,它更像是一个图形引擎而不是游戏引擎。如果你试图让你的游戏架构适应 cocos2d 的结构,你最终可能不会得到最可维护的结果。相反,你应该把 cocos2d 当作它本来的样子:一个很好的工具来处理你的显示和动画需求。
除了场景之外,你肯定应该有一个对象来维持游戏状态,否则当你在场景之间切换时,所有状态会去哪里?在场景/关卡中,您应该简单地尝试使用良好的面向对象设计来将状态分布在各种类的对象上。每个角色对象都会记住自己的状态等。在这里您可以看到 MVC 的用处:当您将游戏保存到光盘时,您想要记住每个角色的健康水平,但可能不记得精灵动画显示的确切帧索引。所以你需要区分sprite和character(模型)本身。也就是说,正如我之前提到的,对于没有很多附加逻辑的游戏对象,或者不需要保存的游戏对象,只需将模型和视图融合到一个类中就可以了(基本上是通过继承 CCSprite)。
要以应有的方式实现 MVC,您还应该学习 Key-Value Observing 的基础知识。 (而且你最好使用this replacement 作为 Apple 的界面。)在更激烈的实时游戏中,像这样的技术可能太慢了,但既然你正在制作一个 RPG(开始的好选择),你可以可能会为了更易于维护的架构而牺牲性能。
游戏场景(只是另一个 cocos2d 精灵)在 MVC 模式中扮演控制器的角色。它自己不绘制任何东西,而是告诉其他所有东西根据输入和状态绘制自己。将各种逻辑和功能放入游戏场景是很诱人的,但是当您注意到它膨胀时,您应该问自己如何将这些功能分离到其他类中。分析您正在实现的功能类型。它与数据和状态(模型)有关吗?还是关于动画和渲染(视图)?还是将逻辑与渲染联系起来(在这种情况下,您应该尝试让 View 直接观察 Model)?
游戏场景/控制器基本上是一个调度中心,它接受输入事件(例如,来自用户或来自报告他们击中某物的精灵)并决定如何处理它们:它可能会告诉一个或几个例如,模型对象以某种方式更新自己,或者它可能只是触发其他一些精灵中的动画。
在实时游戏中,场景中有一个“tick”或“step”方法,它告诉所有对象进行自我更新。这个方法(游戏循环)是程序的核心,每次绘制新帧时都会运行。 (在现代游戏引擎中有很多多线程,但我们不要考虑这一点。)但在您的情况下,您可能想要创建一个可以“玩游戏”完全独立于游戏场景的模块。想象一下,创建一个可以通过终端下棋的程序,只使用文本输入。如果您以这种方式创建整个游戏系统,然后通过小而干净的界面将其连接到图形引擎,那么您将拥有一个真正可维护的应用程序,其中包含大量可重用的代码供将来的项目使用!
一些好的经验法则:模型(数据)不应该知道关于精灵或显示状态的任何事情;视图(精灵)不应该包含任何游戏的实际逻辑(游戏规则),而只知道如何做一些简单的事情,比如在发生复杂事情时如何移动和弹跳以及向场景报告。只要有可能,视图应该直接对模型中的变化做出反应,而无需控制器干预。