使用PureMVC和Cocos2d-JS构建游戏项目

木頭 2014-09-29 10:01:1369 次阅读

需求

刀塔传奇手游中的场景切换非常灵活:玩家可以通过任务窗口跳转至其它界面,甚至可以通过角色界面中缺失的材料顺滕摸瓜进入关卡界面,然后通过战斗获得自己需要的物品,最后重新回到角色界面——之前打开的窗口依然在那里,就像你没有离开过一样。如果你无聊,可以从任务窗口一层又一层的周转于各个界面,然后在任意时刻都能回退到之前的场景,这种无限后退的能力非常有趣。然而手机的内存是有限的,如何组织程序,保存之前的“现场”则是一种考验。显然由cocos2d框架提供的基于Director/Scene的场景管理不足以直接实现这样的需求。


解决办法

我考虑使用MVC模式来构建这样的场景。查阅了一些资料,大体上有两种做法:

  • 直接使用Cocos2d框架现有的组件(CCScene/CCLayer/CCNotification)来实现MVC,例如子龙山人的Cocos2d里面如何实现MVC系列;

  • 使用一套完全独立的MVC框架,而将Cocos2d作为View层的实现。


我尝试了第一种方案,但是没有找到一种合适的方法组织Controller层。如果使用CCScene来作控制器,这在独立的场景下没什么问题。但要如何处理相关联的不同场景,则是个头疼的问题。此外CCScene受到CCDirector的管理,那么谁来控制CCDirector又是个大问题,于是无法实现灵活的场景切换。


对于第二种方案,在网络上的教程中并不多见,但却是一种非常好的思路。幸好在其它语言的开源项目中有许多可以学习的案例。其中PureMVC令我印象深刻:

PureMVC is a lightweight framework for creating applications based upon the classic Model, View and Controller concept.

就像它的名字一样,它是一个不含杂质的纯MVC框架实现。它最早是一个ActionScript项目。但由于它的纯粹性,很容易将它移植到其它主流语言中,于是有了各种语言的实现。

在拜读了PureMVC最佳实践后更是被它的理念所折服。我想如果能用它的javascript版本与Cocos2d-JS擦出火花,那真是太棒了。


PureMVC的Model/View/Controller都是单例,而具体的事务是由Proxy/Mediator/Command完成的,此外有一个Facade提供统一的接口给外部使用。它的内部由观察者模型实现所有消息的发送和接收。


Facade

程序的启动很容易,在Cocos2d-js框架加载完成后,在cc.game.run()中创建一个Facade对象,并编写一个StartupCommand完成Proxies和Mediators的初始化即可。接着由根Mediator完成第一个场景的载入。


View

Mediators负责维护视图组件,以及管理View和Model之间的消息路由。所以理所当然由它来料理Cocos2d-JS

每一个Mediator维护一个viewComponent——即具体的Cocos2d对象,在onRegister的时候创建并显示它;在onRemove的时候移除它。

我创建了一个DirectorMediator负责维护cc.director,用于管理其它SceneMediators的切换,以及一些跨场景的UI组件,例如网络连接标识等。当然,DirectorMediator不会被移除。

SceneMediators主要是一些场景级别的界面,由cc.Scene组成,它们可以包含其它的由cc.Layer组成的SubMediators——这里显然需要一个嵌套结构,于是我设计了一个NestMediator,它可以包含其它NestMediator。于是一个简单的场景树就形成了。

NestMediator提供一个push()接口将另外的SubNestMediator注册并加入到自己维护的Mediator栈中。而SubNestMediator可以使用NestMediator提供的pop()接口将自己弹出栈,以此实现“后退”功能:SceneMediators可以让DirectorMediator将自己push()/pop()实现场景的切换。

SceneMediators在切换后,重新注册自己维护的子Mediators栈,递归调用实现“恢复现场”工作。

由于Mediators的管理是独立于Cocos2d-js的,所以不会受到它的任何影响。“恢复现场”所需要的数据保存在各个Mediators,所以不会因为Cocos2d-js的组件被移除而丢失。至此得以实现与刀塔传奇类似的场景管理——甚至更加灵活,可以直接构造出任意场景树,并显示出来。


Model

Proxies负责管理游戏对象数据,及与服务器进行通讯。可以将不同Model的API封装到相应的Proxy中,并提供一些接口给控制器和视图调用。此外当数据变化时,推送相应的消息给控制器和视图。


Controller

Commands是控制器的主要执行者,用于创建Proxy/Mediator以及集中处理较复杂的逻辑。在实际项目中,由于手机网游的主要逻辑都在服务端,所以前端的控制器基本上被弱化,基本上Model和View的消息机制就足够承担大部分界面逻辑了。


总结

通过这次尝试,我发现将Cocos2d的职责限制在View层之后,它能更好更加专注地完成自己的任务。毕竟它诞生之初的使命就是实现对OpenGL的封装,以便提供一组友好的图形接口供游戏使用。使用外部的框架能够更系统地管理项目的其它部分,实现更复杂的需求。


P.S.

PureMVC.js的源码可以在这里获得。本文所涉及的其它源码用于商业项目不便公开,大家可以根据思路自由发挥。


来源网址:http://blog.mutoo.im/2014/09/build-a-game-with-puremvc-and-cocos2d-js.html

你可能感兴趣的:(使用PureMVC和Cocos2d-JS构建游戏项目)