【深入Cocos2d-x】使用MVC架构搭建游戏Four

项目起源

项目Logo:

下面是该游戏的项目地址,各位想参考源代码的同学可以到我的GitHub上下载该项目的源码。

  • 项目主页
  • GitHub地址
  • bug反馈及建议

我做这个项目的原始目的是实验MVC在游戏中的应用。

Model-View-Controller(MVC)是一种组合设计模式,它体现了一种关注点分离(Separation of concerns,SoC)的思想。MVC主要把逻辑层和表现层进行了解耦,将一个问题划分成了不同的关注点。增强了应用的稳定性,易修改性和易复用性。

MVC经常被使用在Web框架中,包括J2EE,RoR和.Net中都对MVC模型进行了框架层面上的封装,以便程序员可以简单方便地作出结构良好的Web应用。

Cocos2d-x本身并没有提供内置的MVC支持,但是,我们还是可以在游戏中基于MVC架构来设计游戏。在这篇博文中,我将向大家展示一下我是如何使用MVC架构来塔尖Four这个游戏的。

游戏情景

Four这个游戏的创意来自一个叫做走四棋的传统游戏,走四棋规则的详细介绍在这里:走四棋的百度百科。

下面我简单谈一下这个面板游戏(board game)的一些特性

  • 一个4行4列的棋盘(Game Board)
  • 棋盘上会有一些“棋子”(Game Piece),每一个方格上只能放一个棋子(Game Piece)。
  • 游戏初始化时,棋盘的上面四格和下面四格分别有4个黑子和四格白子
  • 玩家可以通过话筒使棋子在棋盘上发生移动,从而触发吃子和胜利等事件。
  • 当游戏中出现一个横行或者一个竖列的棋子排布变为两黑一白或者两白一黑时,即可吃掉一子。
  • 当一方(黑或白)的棋子被吃到只剩一个之后,这一方被记为失败
    举个例子,下面这幅图即为游戏过程中的一幅图。在下面的游戏过程中,位于(1,0)位置的黑子向左移动到(0,0)的位置后即可吃掉白子。

**Cocos2d-x提供的工具
**
Cocos2d-x有这样一些主要的类,CCSprite,CCLayer,CCScene,CCNotificationCenter。我们会使用这些类进行游戏中MVC架构的搭建,如果你对这些类的作用不熟,请参考我的这篇博文【Cocos2d-x-基础概念】Director Scene Layer and Sprite。

我们一般的游戏流程是

  • 通过AppDelegate初始化第一个CCScene。
  • 在第一个CCScene创建多个CCLayer。并控制好CClayer的叠加层次(zOrder)。
  • 在CCLayer中添加各种CCSprite或者CCLabelAtlas或者粒子效果。
  • 在CCLayer层注册触摸事件的监听,并且在CCLayer的实现中写出相应的callback函数,对CCLayer的Child Node进行相应的逻辑处理。

这个过程看起来十分简单,并且可以十分快速地做出游戏。但是其缺陷就在于在CCLayer中我们做了太多的事情。CCLayer同时承担了逻辑层和表示层的任务。不符合我们上文中提到的关注点分离的原则。如果游戏中有较为复杂的状态转换时就捉襟见肘了。

项目的文件目录

下面是该游戏项目的目录结构,我们接下来对这几个文件夹进行分别的讲解:

下面是该项目的一个简单的类图

在类图中,虚线代表的是通过消息机制进行沟通,而在Cocos2d-x中,这种沟通是通过CCNotificationCenter来实现的。

Model(模型)

Model在游戏中代表的是消息驱动的有限状态机,Model会接受Controller层发送的消息,并根据消息来更改自己的内部数据,然后把内部数据改变这一消息发送给View,通知它更新。

Model在Cocos2d-x对应的是哪个类呢?

很遗憾,但是Cocos2d-x并没有提供状态机的feature,所以我们需要自己实现一个Model类,在Model类中,需要自己实现诸如状态转换和消息处理等功能。例如在我的Model类中,我提供了如下接口。

<!-- lang: cpp -->
class Model : public CCObject {

public:

    // 添加一条状态转换,from-起始状态,msg-接收的消息,to-终结状态,在msg发生时会发生状态转换
    Model* addTransition(const string& from, const string& msg, const string& to);

    // 检查当前状态机能否发生msg对应的状态转换
    bool checkMessage(const string& msg);

    // 触发msg对应的状态转换
    void onMessage(const string& msg);
    void onMessage(const string& msg, CCObject* o);

    // 等待某个CCAction结束后发送一条消息。
    void waitAction(cocos2d::CCNode* node, cocos2d::CCFiniteTimeAction* action, const string& msg);

    // 得到当前状态名称
    const char* getState()
;```  

};
注意以下几点:

- 让Model类继承CCObject,是为了与Cocos2d-x自身的内存管理系统一致。
- onMessage中,我们做的事情就是首先找到当前状态在msg情况下的状态转换。在状态转换后,通过CCNotificationCenter发送一条消息通知游戏中的其他组件更新逻辑。
- waitAction中,我们是在处理一种异步的状态转换,比如一个棋子在移动时就会经历这样的状态转换start->moving->end,那么在移动结束后,View就要发送一条类似END_MOVE的消息来通知Model更新自己的状态。
Model不会持有View,所以View都是通过消息来获得Model更新的事件的。

我们在编写游戏时,应该先编写Model,然后通过测试来保证Model的正确性。

之后,我们去写View的时候,实际就是对Model这个状态机发送的各种消息的回调函数的编写了。

这样就讲表示层和逻辑层分离开,可以方便地单独测试每个模块,可维护性大大提高。

**逻辑数据和实际数据**

在编写Model的时候,我们经常会遇到这样的问题,就是Model中的数据是否应当与View中的数据保持一致。

比如:在View层的棋子的位置信息是否应该和Model层的位置信息保持一致?

其实,真实情况就是,这要看Model层的 计算使用那种数据形式更加方便,比如在Model中,我们会把棋盘转化为一个二维数组,这样在AI运算,逻辑判断时,更加有利,所以棋子的逻辑位置和实际位置必然是不同的。

再比如,很多时候游戏中的物理引擎的计量单位是厘米,米。而不是OpenGL中的坐标。这也是为了逻辑运算的方便。

但是有些数值,我们会让它保持一致,比如人物的属性等等。

**View(视图)**
![image](https://yqfile.alicdn.com/9f974957ffaa418e76d12403f28286beb55b4eaf.png)

View在游戏中代表的是Model消息的接受者,在Cocos2d-x中,View一般是指CCLayer的子节点,即CCSprite,CCLabelAtlas,CCMenuItem,Particle System(粒子系统)等等。

它们会重载onEnter函数,在onEnter中注册自己对某个Message的监听。同时在onExit函数中将所有监听清除。(清除监听很重要,否则会出现很可怕的野指针问题)。

**Controller(控制器)**

![image](https://yqfile.alicdn.com/b44ebf24f5751819b1d02fc5c001831c248e5ee0.png)

Controller在游戏中负责将用户触摸事件转化为逻辑事件(即我们上文中所说的消息),同时要对用户触摸事件中的信息进行正规化,并且通知变更。

Controller在Cocos2d-x中一般用CCLayer 来实现,因为CCLayer自然地继承了CCTouchDelegate这一接口,本身就可以触摸事件,所以我在这个游戏中所有的XXXController都是继承自CCLayer。

Controller另一个很重要的职责,就是创建View和Model,因为Controller相当于Model和View的一个中间层,所以自然Controller会同时持有View和Model的应用,来方便地传递数据。

**Protocol(协议)**
![image](https://yqfile.alicdn.com/2c8a5eb1c6b010a957d84057441c475d3301b84e.png)

Protocol中定义了一些Model,View和Controller中共享的数据,

- 在Message.h中,就定义了游戏中各种类型的消息,
- 在Tag.h中,就定义了游戏中一些Node的Tag,其实Tag这个定义不是很准确,其实这里的Tag指的是唯一标识CCNode的一个ID。
- 在ChessboardProrocol.h中,定义了游戏中期盘的宽,搞和一些常用的数据结构。
时间: 2024-09-17 23:42:42

【深入Cocos2d-x】使用MVC架构搭建游戏Four的相关文章

Intellij IDEA采用Maven+Spring MVC+Hibernate的架构搭建一个java web项目

原文:Java web 项目搭建 Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring+Hibernate的架构搭建一个java web项目 Spring MVC+Spring+Hibernate结构介绍如下: Spring MVCSpring MVC的职责是作为web层框架,实现了我们常见的MVC模式 SpringSpring 作为服务层,利用自身特性IOC.AOP,提供数据从DA

spring mvc 框架搭建及详解

现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理. 一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.comm

《精通Spring MVC 4》——2.5 Spring MVC架构

2.5 Spring MVC架构 让我们从这个新的"Hello World"页面后退一步,尝试去理解在这个Web应用中到底发生了什么.为了做到这一点,需要跟踪浏览器所发送的HTTP请求的行程以及它是如何从服务器端得到响应的. 2.5.1 DispatcherServlet 每个Spring Web应用的入口都是DispatcherServlet.图2-3展现了DispatcherServlet的架构. 图2-3 这个一个典型的HttpServlet类,它会将HTTP请求分发给Handl

Spring MVC 框架搭建配置方法及详解_JSP编程

现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了.不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理. 一.Spring MVC环境搭建:(Spring 2.5.6 + Hibernate 3.2.0) 1. jar包引入 Spring 2.5.6:spring.jar.spring-webmvc.jar.comm

php-使用PHP搭建自己的MVC框架 搭建时出现的问题

问题描述 使用PHP搭建自己的MVC框架 搭建时出现的问题 你好,我按照<使用PHP搭建自己的MVC框架>上面的步骤来进行搭建这个框架,但是把所有的步骤都做完了,最后访问的时候提示找孙到页面,请问这个问题应该怎么解决呢,还是框架本身就有问题呢,求指教,谢谢! 解决方案 看看作者有没有提供完整的源代码,如果没有,这种例子根本不靠谱.看教程一定要找有完整代码的. 解决方案二: 重新核对看看有没有遗漏什么关键步骤.或者重新找个完整的示例代码. 解决方案三: 没有源码的,但是我看到有很多人在转,所以我

Silverlight游戏设计:(四)从零开始搭建游戏主体框架

思路已俨然清晰,接下来要做的是从零开始搭建游戏的主体框架.Silverlight作为RIA界的新宠儿, 不仅在游戏开发方面性能优越,在企业开发领域的优异表现同样日益显著.像我们这些长期从事.NET开发 的程序员们,如何顺利向Silverlight开发转型是入门时要解决的第一个难题. 首先要做的是安装 配置开发环境及开发工具.这里我强烈推荐.NET程序员使用windows2003或更高版本的服务器操作系统以 得到更快的编译速度:以目前开发Silverlight3.0程序应用为例,建议安装的开发工具

Struts开发指南之MVC架构

模型-视图-控制器(MVC)是80年代Smalltalk-80出现的一种软件设计模式,现在已经被广泛的使用. 1.模型(Model) 模型是应用程序的主体部分.模型表示业务数据,或者业务逻辑. 2.视图(View) 视图是应用程序中用户界面相关的部分,是用户看到并与之交互的界面. 3.控制器(controller) 控制器工作就是根据用户的输入,控制用户界面数据显示和更新model对象状态. 开发指南之MVC架构-springmvc开发指南pdf"> MVC 式的出现不仅实现了功能模块和显

浅谈MVC架构模式

   MVC英文即Model-View-Controller,就是把一个应用分为三个层:视图层.模型层.控制层.    模型层(M)用于封装业务逻辑.    视图层(V)也叫表示层,就是与用户实现交互的界面,通常实现数据的输入和输出功能.    控制层(C)起到控制整个业务流程的作用.简单的说就是调用业务逻辑,然后把得到的数据转发给视图显示给用户. 为了熟悉MVC架构模式,特意将学生查询改成了MVC模式的. 1.首先建立客户端页面(student.jsp): 1 <%@ page languag

MVC架构各层责任图

只是翻译一小部分,如有错误,请告诉我. MVC架构各层责任图     View -          展示数据 -          接收事件(如按钮按下事件,选择改变事件)及传递事件 -          基础验证(如email合法性,空文本检验等) -          可能直接接收model的对象 Controller -          处理界面的复杂逻辑 -          改变界面布局 -          与Model层通信 -          复杂验证(如涉及到数据库查询)