使用Cocos2D-X进行游戏开发

96
月影檀香
0.1 2017.02.14 17:55* 字数 9198

前言

我选择开发一个游戏有很多原因。我觉得自己是“核心”玩家,过去的大部分时间我都花在玩游戏,自己制作、阅读和游戏有关的项目上面。
  编程,或更具体地说,游戏“改装”,来源于21世纪初的反恐精英1.6。这一切都开始于我加入一个名为“SHMOD服务器20+英雄”的服务器,它让我对超级英雄mod和编程感兴趣。其次,这次项目的开发过程是一次有趣的和具有挑战性的经历,因为我以前从来没有用C++开发过大的工程。
  芬兰的游戏产业正在增长,并且已经发展得相当大,不仅仅是因为最近“愤怒的小鸟”的成功,还因为一些小公司,如Supercell的游戏制作【1】。
  我对游戏开发领域的工作很感兴趣,我认为这将是一个不错的学习机会。不管怎样,这是一个在编程和游戏设计上都很好的学习经历。

缩略语表

IDE 综合开发环境(Integrated development environment),比如Eclipse和
Microsoft Visual Studio
FPS 第一人称射击(first person shooter),以通过第一人称视角看到的射弹型武
器为基础的战斗为中心的游戏。
RPG 角色扮演游戏(role playing game)
Goto 无条件地将控制转移到由指定标识符执行的语句
HUD 作为游戏中用户界面的一部分将信息可视地传递到玩家的方法(head-up
display)

1. 介绍

本论文的主题是用Cocos2D-X进行游戏项目开发。本论文涵盖从游戏的想法到成品原型的整个过程。其中包括对Cocos2D-X的介绍,游戏设计,UI设计,但不限于上述主题。
  本次研究与Linda Karlsson密切合作进行,她是 Novia应用科学大学的平面设计专业的学生。她负责所有和游戏相关的想法,比如说绘画(或者设计)人物、背景、敌人、UI等等。我负责游戏的设计和编程。我们共享观点和反馈,为了达成关于游戏的不同组件的决定的协议,例如视觉外观和游戏玩法。
  本论文首先会介绍Cocos2D-X的基础理论,然后把它和其他流行的框架进行对比。接着着手设计Project Cherry Brawl,研究与它相关的背景。最后介绍游戏开发的不同阶段。

2. Cocos2D-X

Cocos2D-X【2】是iOS的Cocos2D引擎的C ++跨平台端口。它是一个根据MIT许可的开源游戏引擎,使用它开发人员不仅可以开发游戏,还可以开发应用和其他跨平台GUI交互式程序,如动画背景。
  Cocos2D-x允许开发人员利用他们现有的C ++,Lua和Javascript知识, 从原型到高性能游戏(应用程序)开发跨平台游戏(应用程序),从而节省时间和精力。
  虽然Cocos2D-X在西方不像Unity3D那样流行和出名,但在亚洲,它非常受欢迎,可以保持大哥Cocos2D的水准,甚至因为其跨平台的能力而超过Cocos2D【3】。
以下部分详细讨论Cocos2D-X的架构,与Cocos2D-X兼容的工具,并将Cocos2D-X与其他框架进行比较。

2.1 架构

Cocos2D-X的架构可以分为三个主要层,每个主要层包含子层。这三个主要层包括游戏/应用程序,Cocos2D-X提供的组件和它分别运行的平台,如下图1所示。

图 1. Cocos2D-X的架构【4】

绿色图层代表游戏层,是游戏开发者创建的。橙色图层代表了Cocos2D-X提供的所有功能,并让开发者构建自己的产品,最后棕色层代表游戏和Cocos2D-X将运行的平台。本章简要解释了Cocos2D-X最常用的功能。
  导演或CCDirector负责在项目中创建的所有场景。CCDirector是一个共享的单例对象,这意味着它只有一个实例在运行。它知道哪个场景当前是活动的,并处理一堆场景以允许各种场景调用,例如暂停,将场景保持而另一个进入,然后返回到原始场景。简而言之,场景的推送,弹出,替换和终止是由导演发出的。当一个新的场景推入堆栈时,Director暂停前一场景,但将其保留在内存中。 稍后当顶部场景从堆栈弹出时,暂停的场景从其最后状态恢复。
  CCNode是Cocos2D中的主要元素,Cocos2D中几乎所有的东西都继承自CCNode,其中最流行的有CCScene, CCLayer, CCSprite和CCMenu,在这里简要介绍它们,在第三章会进一步详细讨论。CCNode的主要特征是它可以包含其他CCNode,它可以调度周期性回调(调度,非调度等),并且它可以执行动作。
  Cocos2D或CCScene中的场景是应用程序工作流程的独立部分,基本上是“阶段”,“级别”或电影中的一个场景。它是之前说过的CCNode的一个子类。游戏中可以有很多场景,但一次只能有一个场景处于活跃状态。下面的图2说明了CCScene的类图。

图 2. CCScene类图 【5】.

Cocos2D-X中的一个层称为CCLayer,它是一个CCNode,它知道如何处理触摸事件,绘制自己和添加到它的孩子。 图层最常用于定义游戏的外观和行为。
  Cocos2D-X中的sprite,通常称为CCSprite,像任何其他计算机sprite一样。 它是一个2D图像,可以移动,旋转,缩放,动画等。CCSprite可以把其他sprite作为孩子,这意味着当父节点变换时,子节点也会跟着变换。
  CCAction是给予CCNode对象的命令。 这些操作可用于修改对象的属性,如位置,缩放,旋转等。第3章会进一步详细介绍操作。

2.2 工具

本章简要介绍了与Cocos2D-X兼容并且在社区中广泛使用的工具。这些工具提供给用户一种简单的方式来处理不同的任务,例如打包textures,创建映射或有效管理复杂数据。 这些工具包括第三方程序。
  Tiled Map Editor是一个通用的tilemap编辑器【6】。 它是一个免费的工具,允许轻松地创建地图布局。 它是非常通用的,并允许用户指定更多的抽象的东西,如碰撞区域和对象产生点。 它以TMX格式【7】保存此数据。
  TexturePacker为用户提供了一个GUI和一个命令行工具来创建精灵表或精灵图集。 它是非常多才多艺,并与众多的游戏引擎,如Cocos2D-X和Unity工作。 TexturePacker能产生很好的结果,同时具有很大的可调性【8】。

2.2.1 CocoStudio

CocoStudio【9】是CocosBuilder的对应版本,两者都是游戏开发工具包。
  CocoStudio旨在将游戏开发中的任务分解为几个不需要用户知道如何编程的角色。这些角色包括:用于动画和图形艺术家的动画编辑器,用于UI图形艺术家的UI编辑器,用于游戏设计者的场景编辑器和用于游戏设计者的数据编辑器。 图3显示了如何在CocoStudio中处理角色动画。

图 3. CocoStudio动画部分的屏幕截图

动画编辑器将骨骼动画带到Cocos2D-X。 与传统帧动画相比,骨架动画提供了更低的内存消耗,更小的文本大小,把动画混合在一起,并重用动画。 然而,骨骼动画有限制,例如它不能创建爆炸或等长字符。

2.3 比较

这是符合Project Cherry Brawl标准的游戏引擎之间的一个简短的比较。 游戏引擎的主要区别如下。 下面的图4中的代表提供了本论文作者的个人意见。

图 4. 所选游戏引擎的比较表

LibGDX【10】是一个Java游戏开发框架,提供了一个统一的API,可以在所有支持的平台上工作。 LibGDX框架为快速原型设计和快速迭代提供了一个环境。
  Unity3D【11】是一个完整的游戏开发IDE,它带有一个强大的渲染引擎,完全集成了一组直观的工具,更容易创建3D / 2D内容和轻松的多平台发布。 它还配备了自己的资产商店,用户可以下载或购买由非常大的社区创建的资产。
  Unity2D 【12】是Unity的一个新增加,使开发人员更容易开发2D游戏。 它有很多新的特性,对于2D开发是必不可少的,如一个新的资产类型被称为精灵,sprite包装(专业版),动画窗口等等【13】。
  Cocos2D-X和LibGDX是免费和开源的,而Unity给开发者在免费版和专业版之间的选择。 Cocos2D-X面向2D,而Unity和LibGDX有很大的2D支持,但更侧重于3D。 所有三个竞争者都有非常好的文档,它们在stackoverflow标签流行度搜索中显示非常高,如图5所示。

图 5. Stackoverflow.com每月标记问题 【14】.

Cocos2D-X和LibGDX提供了一个非常容易访问和灵活的UI实现,Unity则没有,与前两个相比非常有限。 Cocos2D-X,Unity和LibGDX提供了极好的跨平台适应性,并具有非常相似的开发周期。 Cocos2D-X的主要编程语言是C ++,也支持使用Javascript和Lua的脚本,LibGDX使用Java,Unity支持C#,Javascript和Boo中的脚本。
  Cocos2D-X和LibGDX背后有一个庞大的社区和大量的用户生成的教程和第三方加载项,而Unity有它的资源商店。 这些功能迅速缩短开发时间,并使图形艺术家和游戏设计师可以从可下载的模板创建游戏。

3. Project Cherry Brawl

Project Cherry Brawl是一款动作游戏。 通常这种动作游戏是主角(Cherry Lyn)和大量的能力低下的敌人之间的近身作战。 游戏的运行方式和大多数的动作游戏一样,玩家向前移动(向右),与敌人战斗,击败他们,最后击败boss完成关卡。 游戏通过详细阐述它的背景故事将玩家置于正确的心态。
  Cherry Lyn,一个有着超能力的女孩,因为感冒而从学校回家了一个星期。当Cherry Lyn回到学校时,事情变得有些不太对劲。在她请假的时候,学校的科学俱乐部开发了一台可以用作耳机的电脑。 在耳机的帮助下,学校的学生将变得更有效率,所以校长允许生产这样的耳机。没有人知道的是,在耳机生产之前,科学俱乐部对它进行了改变。他们增加了一个额外的功能,来洗脑学生,从而控制学校。Cherry Lyn现在必须从科学俱乐部的控制中解放学校的其他学生。

3.1 背景研究

自从游戏机和诸如任天堂娱乐系统之类的旧游戏机开始运行以来,动作游戏就一直存在。 必须完成的研究是关于如何在手持设备上正确地模拟一个动作游戏。 研究分为两个不同的类别,第一个是如何正确使用移动设备屏幕和适合游戏的所有组件。 第二类是如何在移动设备上模拟控制器。
  第一步是在谷歌Play商店中,尝试尽可能多的被标记为动作、格斗类型的游戏。 注意到所有测试的游戏都有一些共同的关键因素。 每个游戏都是横向模式,给玩家一个更广泛的视野。 如果手机处于纵向模式,它会缩小播放器的视野,并不适合于一个动作类型的游戏。
  如图6所示,大多数移动抓取游戏都有非常杂乱的屏幕。 这意味着当玩家将他的拇指放在屏幕上时,它将使玩家的视野重新减少大约40%。 另外,在屏幕上具有其他用户界面组件进一步减少了视野或者仅仅混淆了玩家。 另外,在屏幕的两侧周围有按钮会混淆玩家,因此它们将与背景混合。

图 6. Google Play商店中游戏Street Fight【15】的屏幕截图

图7展出了之前说的关于玩家视野减小的情况。 玩家视野将受到玩家自己的手和UI组件以及背景的阻碍。 当背景和敌人/ UI组件混合在一起时,可能发生进一步的混乱,使玩家不能区分它们,导致糟糕的游戏体验。

图 7. Google Play商店中游戏Street Fight【15】的屏幕截图,玩家的视角

在游戏中有不同类型的UI,通常分为四类。 分别是叙事,非叙述,空间和元。
  包括在游戏世界中的界面是叙事的,即玩家的角色可以看到,听到它。 比如任务指挥官的全息图片,他解释了玩家角色的使命。
  非叙述意味着UI被呈现在游戏世界之外,并且仅对玩家本身而言是可见的或可听见的,而不是角色。 比如Project Cherry Brawl的平视显示器。
  空间UI元素在游戏世界中呈现,但不必是游戏世界中的实体。 比如当玩家的光标悬停在任何物品或敌人上时,该物品将得到不同的轮廓。
  元表示可以存在于游戏世界中,但不被归类为空间。 元表示的示例可以是玩家的相机上的血溅,以指示损害。 图8反映了我以前的陈述。

图 8. 四类UI设计【16】

Project Cherry Brawl 的UI主要属于非叙述类,因为UI在游戏世界之外,角色不知道它存在。 有一个例外,即当他们受到伤害时,出现在角色上方的数字。 这些数字属于空间接口的类别,因为它们出现在游戏世界中,而人物仍然不知道数字【16】的存在。
  在创建并测试了一个原型之后,其中Project Cherry Brawl的UI组件用Street Fight相同的方式显示,我放弃了这个想法,因为玩家自己有时会用手阻挡屏幕的两端。
  当前UI布局的想法来自希望尽可能清晰地向玩家显示所有内容。 在与Linda Karlsson会面之后,得出结论,UI如图9所示。通过这种设计,玩家的信息显示在他的前面,同时他的手在屏幕的每一侧。 这不仅保持屏幕不混乱,而且给玩家更多的使用实际控制器的复古感觉。 此外,没有一个UI元素将出现在实际的游戏玩法上,并且玩家不会如图9和图10所示的那样阻止他自己的视线。

图 9. Project Cherry Brawl的UI原型

根据目前的设计,玩家失去了很少的活动空间,与之交换的是,角色和地图略有缩小。 这样玩家有更多的空间来玩,同时保持屏幕整洁,如图10所示。

图 10. Project Cherry Brawl完整UI的截图

下一个问题是,游戏资产必须创建。 通常移动游戏必须提供不同的资产以支持多种宽高比。 这样,同样的游戏可以在流行的移动设备,如平板电脑和手机上享受。 由于资源和时间有限,项目必须关注某种类型的移动设备。 所选的宽高比为15:9,使游戏分辨率为480x800像素。 这样,如果设备分辨率大于所选的480x800像素,设备将添加与上述类似的黑色边框。 这是用Cocos2D-X[17]的多分辨率支持来实现的。

3.2 场景

本章进一步阐述了之前关于场景的说明,以及如何在Project Cherry Brawl中使用它们。 使用CCScene作为所有游戏不同CCNode的父级是一个很好的做法,如图层。
  在Project Cherry Brawl中有三种不同的场景,分别是初始场景,菜单场景和游戏场景。 它们用于包含不同的图层和其他CCNodes,并对其进行排序。 在下面的章节中将简要讨论每个上述场景的创建过程。
  Cocos2D-x和Cocos2D中init方法的区别在于Cocos2D-X中init方法返回一个布尔值,而在Cocos2D中它返回一个id。 现在做的是促进防御性编程。 以前,Cocos2D-X 【18】的开发人员编写代码来管理它的goto的清理:

define check(ret) if(!ret) goto cleanup; 
    void func() { 
        bool bRet = false;
        bRet = doSomething();
        check(bRet); 
        bRet = doSomethingElse();                              
        check(bRet); 

        bRet = true; 
        cleanup:
          // Do clean up here
        return bRet;
   }

代码段1. 第一个版本的初始函数的实现

从上面的代码可以发现,如果出现了任何错误,它将跳转到函数结尾的清理功能。 每个对函数的调用都返回它是否成功。 然后,检查宏用于查看bRet是否为true,如果不是,则直接跳转到清除标签。 从技术上讲,这没有什么问题,但是他们遇到了一个问题,因为脚本语言没有goto指令。 这就是为什么它改为:

define CC_BREAK_IF(cond) if(!cond) break; 
    void func() { 
        bool bRet = false;
        do {        
          bRet = doSomething();
          CC BREAK IF (bRet);
          bRet = doSomethingElse();       
          CC_BREAK_IF (bRet);                       

          bRet = true; 
        } while (0)
        // Do clean up here
        return bRet;
   }

代码段2. 跨平台的初始函数的实现

这有与以前完全相同的效果,但使用break作为goto机制跳到do while循环后的代码。 尽管不可预见地使用所述软件,但是一般来说,确保软件的持续功能是良好的实践。 这是因为Cocos2D-HTML5 / JS 【19】。
  这可能略微偏离了主题的场景,但它是场景的一个必不可少的部分,必须详细阐述。 为了防止出现不可预见的错误和错误,每个CCNode应该以上述方式初始化。

3.2.1 初始场景

初始场景是打开任何程序/游戏时大多数时间看到的。 它显示信用,公司名称等,例如当启动windows时,会显示Windows问候窗口,接着是登录屏幕。
  初始场景是Project Cherry Brawl的第一个组成部分,因为它充当的是一个欢迎的部分。 在这个场景中,将加载一个标志,显示它,并在一定的时间后,调用director,切换到菜单场景。
  上诉步骤按照以下顺序完成。 初始化Splash图层后,继续创建CCScene,并将上述Splash图层作为子级添加到它。 添加Splash图层后,调用CCDirector更改场景不是最佳解决方案,因为这会立即更改场景。 我们期望的结果是让Splash屏幕保持足够长的时间,以便玩家读取标志,然后改变场景,如代码段3中所示。

CCCallFunc* changeScene = CCCallFunc::create (this, cal-func_selector (SplashScene::DisplayScene));
CCDelayTime* delayAction = CCDelayTime::create (2.0f); 
this->runAction (CCSequence::create(delayAction, changeScene, NULL));

代码段 3. 在Project Cherry Brawl初始场景中更换场景的操作

此外,通过给Splash层一个CCAction,可以给予所有CCNode对象,使用delayAction实现所需的效果,使得动作在延迟两秒后运行。

3.2.2 菜单场景

不像其他具有复杂菜单系统的游戏,这款游戏的菜单场景非常简单。 菜单场景有两个按钮,它们将显示Project Cherry Brawl的控件或切换场景到游戏场景。 用Splash场景相同的方式创建菜单场景被证明是有问题的。 问题在于,一些孩子CCNodes,如粒子效果和标志,会以我们不希望的方式重叠。
  图11显示了完成的菜单场景,演示了子节点的排序。

图11. Project Cherry Brawl主菜单屏幕,演示场景的不同元素的不同Z值

该问题通过将所有菜单的组件作为子节点添加到菜单场景中来解决。 这样,孩子的显示顺序可以重新排序。 值越高,特定节点高于其他节点的越多。

3.2.3 游戏场景

这是整个游戏进行的主要场景。 创建的方法类似于前两个场景。 与之前的初始场景和菜单场景不同,游戏场景中有很多子节点,用一层管理它不是一个选择。 从长远来看,它会导致代码变得非常混乱,难以理解,最重要的是它将很难维护。
  因此,需要创建单独的层以包含更多的游戏对象,诸如HUD对象或游戏对象。 创建HUD层和游戏层是游戏的一个重要组成部分。 HUD层将处理与UI相关的一切,而游戏层维护与实际游戏世界相关的一切。 在下一章中进一步阐述了两个层。

3.3 图层

CCLayers是保持代码清晰和容易理解,同时定义你的游戏外观的必要条件。 图层是CCNode类的子类,因此它们可能包含图像,动画,标签,按钮,sprite等。关于图层的定义因素是它们实现TouchEventsDelegate协议,这意味着玩家可以与触摸事件 进行交互,如敲击,滑动,保持和移动。
  Project Cherry Brawl利用三个不同层的实现,每个层代表游戏的一个组成部分,如图12所示。

图 12. Project Cherry Brawl的图层样本

HUD,游戏和D-Pad层完整的构建以及如何放置它们可以在上图中看到。 此外,它显示了即使只有两个主要层,也可以在一款游戏中有很多视觉深度。 蓝色和绿色层代表游戏层,红色代表HUD层,黄色代表D-Pad层,更多的细节在下面的章节中阐述。

3.3.1 HUD图层

在设计HUD布局时,必须考虑以下因素: 轻松访问的玩家的技能按钮,回到菜单场景按钮和对话部分点击继续按钮, 玩家和敌人名称标签的图标,以及他们的肖像纹理。 动态处理游戏的对话状态,意味着隐藏和显示HUD层的特定子节点。 玩家健康条和能量条,并处理其更新。
  因为HUD严重依赖于游戏层,所以解决方案是在HUD层中创建子节点,并根据它们的依赖关系初始化它们。 初始化HUD层中的用户技能按钮将使我创建游戏层对象的参考,并将其传递给HUD层。 这样做的话,代码将变得很难解释,非常混乱。
  在HUD层中初始化对象,例如对话框,命中点的背景,命中点的边界,游戏对话和名称标签以及D-Pad层。 而退出按钮,玩家按钮,玩家健康和能量条在游戏层中初始化,并作为孩子添加到HUD层。 这样,只有一个HUD层对象的引用必须传递给游戏层。 这提供了从游戏层轻松访问所有HUD层组件。 图13分别示出了命中点的背景,命中点和命中点的边界的顺序。

图 13. Project Cherry Brawl中命中点的条的顺序。 分别显示命中点的背景,命中点和命中点的边界

对话状态也在HUD层中处理。 通过创建两个叫dialogModeOn和dialogueModeOff的函数,子节点可以动态设置不可见并回到可见。 玩家和敌人的对话图片和名称标签也在HUD层中处理。 当调用dialogMode时,可以让想要看到的的人谈话,例如让主角谈话,此时会调用:

_hud->cherryTalks (true, 1); // frames from 1-4

代码段 4

这些参数分别用于设置子节点可见和图像框架,对敌人也有类似的功能。

3.3.2 游戏图层

设计游戏层是本项目中颇具挑战性的部分之一。 即使一切都在游戏场景内播放,游戏层必须处理游戏的所有逻辑,角色运动,瓷砖地图和游戏效果。 以下功能必须存在于游戏图层中:
  游戏的循环和所有游戏对象和一些HUD层对象的初始化。 它必须处理加载瓷砖地图和管理剪切的场景和对话。 显示和更新所有子节点,如玩家的角色,敌人和HUD层组件,如玩家的角色健康状态。 处理D-Pad上的玩家输入,重新排序所有的孩子演员精灵位置,并更新玩家视点。 所以游戏层可以被认为是这个游戏的核心。 它拥有一切,并处理对象之间的交互。
  幸运的是,CCLayer节点支持scheduleUpdate,它将一个调度更新添加到图层。 通过重写它将会提供的更新(deltaTime)函数,可以创建一个游戏循环。 从编程的角度来看,游戏循环[20]是游戏的中心组成部分。 它允许游戏保持运行,而不管是否有任何用户输入。
  使用TexturePacker帮助保持Project Cherry Brawl的所有资产,并重新创建他们将使用的空间。 从图14中可以看出,即使这样的小游戏原型通常也可以具有许多纹理和资产。 通过将所有资产压缩成一个图片,可以实现批量节点的使用。

图14. 由TexturePacker创建的Project Cherry Brawl的资产Sprite表

将所有资源添加到TexturePacker后,创建了一个sprite表。一旦加载了在共享精灵帧缓存中可用的资源,不仅会加快游戏加载纹理的时间,而且它也是使用CCSpriteBatchNode的一个重要部分。
  在Project Cherry Brawl的早期迭代中,诸如玩家角色,敌人等游戏对象作为孩子被添加到游戏层。这使得代码很难维护和更新。此外,即使在屏幕上一次只有十个敌人,游戏也会表现不佳。
  批处理节点提供的是,如果它包含子节点,它将在一个单独的OpenGL调用中绘制它们。这通常被称为“分批抽取”。在没有批处理节点的情况下,OpenGL绘制调用将被调用的次数与孩子的次数一样多,如玩家角色和敌人这样的sprite。
  一个CCSpriteBatchNode只能引用一个纹理,图像文件,纹理图集或一个精灵表。将所有actor sprite添加到CCSpriteBatchNode中可以大大提高游戏的性能,即使在游戏可能提供给手机的最大可能压力下,也可以给玩家所需的帧数。
  首先重新排序精灵很难掌握。 在早期迭代的一个版本中,精灵设置了z值,这看起来非常不现实,如图15所示。

图15. Project Cherry Brawl,没有z排序。 红色圆圈表示错误。

该问题的另一迭代根据每个actor sprite在创建时的位置来设置它们的z值,但是产生了一样的不想要的结果。 因为每个单独的actor sprite是CCSpriteBatchNode的子节点,所以子节点的动态重定向是可能的,如在代码段5中可以看到的。结果可以在图16中看到。

CCObject *pObject = NULL; 
CCARRAY_FOREACH (_actorsAtlas->getChildren (), pObject)
 { 
   ActorSprite *sprite = (ActorSprite*) pObject; 
   _actorsAtlas->reorderChild (sprite, (_tileMap->getMapSize ().height * _tileMap->getTileSize ().height) - sprite->getPosition ().y); 
}

代码段 5. Project Cherry Brawl中的重新排序子函数

图16. Project Cherry Brawl,敌人/阴影sprite重排。.

从0.8.1版本开始,Cocos2D-X提供了CCTMXTiledMap,它是一个知道如何解析和渲染TMX映射的CCNode。 在渲染每个图块时,它们将被创建为CCSprites。 这意味着每个图块可以随意旋转,移动,缩放,着色等。 由于瓦片地图是从瓦片图像创建的,因此它将被加载到自己的CCTextureCache中,从而加速加载时间和性能。 tilemap的每一层将使用CCTMXLayer CCSpriteBatchNode的子类创建。 通过在Tiled中创建tilemap,可以使用CCT-MXTiledMap节点轻松实现地图的解析。
  游戏地图是在Tiled中创建的,使用两层,墙壁和地板层。 就像Cocos2D-X中的图层一样,图层中的图层为用户提供了在对象的顶部绘制对象的能力,使地图具有深度感,如图17所示。

图17. Project Cherry Brawl中Tiled和墙壁的演示层

如图17所示,所有的墙砖被绘制在墙层上。 在图18中,创建了游戏的地板组件。 因为该层在壁层下面,所以添加到地板层中的任何物质都将在壁层下面。

![图 18. Project Cherry Brawl中Tiled和地板的演示层].](http://upload-images.jianshu.io/upload_images/4086459-5c4fddc1eecd7f37.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

在规划Project Cherry Brawl时,我的意图是把它看做一个原型。它将展示游戏的核心力量。原型设计大约需要一到三分钟的游戏时间来完成。进入项目的后期后,游戏的气氛似乎相当沉闷。Cherry Lyn没有了战斗的欲望,因此产生了为游戏创建故事前传的需要。游戏的故事是通过在游戏中的战斗或检查点之间的小剪辑场景中进行的。
  决定添加剪辑场景后,我为游戏创建了两个状态。对话状态意味着敌人,玩家和老板会有脚本化的动作,而不是玩家控制输入。运行状态意味着敌人将根据他们的AI移动,玩家角色将基于玩家的输入移动。
  处理不同的剪切场景很棘手,但是当游戏处于对话状态时,在检查点的帮助下,剪切的场景将无缝地从一个转换到另一个。图19展示了Cherry Lyn和敌人咕噜之间游戏对话的转换。

Figure 19. Project Cherry Brawl中, 从对话状态到游戏状态的过渡.

设置视点的中心被证明是自己的问题。 尝试不同的方法来解决这个问题,最佳的方法似乎如下:
  通过确定玩家角色的当前位置,并将它与屏幕的宽度用MAX宏除以2进行比较,返回两个上述变量之间的较大值。 可以使用上述值,并使用MIN宏将其映射到tilemaps宽度减去屏幕宽度除以2,该宏返回两个变量中较小的值。 对视点的高度进行相同的过程。 使用ccpSub宏,它将减去屏幕中心和先前计算的变量x中的点,如代码段6中所示。

int x = MAX(position.x, SCREEN.width / 2); 
int y = MAX(position.y, SCREEN.height / 2);
 x = MIN(x, (_tileMap->getMapSize ().width * _tileMap->getTileSize ().width) - SCREEN.width / 2); 
y = MIN(y, (_tileMap->getMapSize ().height * _tileMap->getTileSize ().height) - SCREEN.height / 2);
CCPoint actualPosition = ccp(x, y);
 CCPoint centerOfView = ccp (SCREEN.width / 2, SCREEN.height / 2); 
CCPoint viewPoint = ccpSub (centerOfView, actualPosition); 
this->setPosition(viewPoint);

代码段 6. 相机位置更新

这样,游戏的视角不会在HUD布局下,并且相机将跟随玩家。

4. 讨论和结论

在这篇论文中,Linda Karlsson和作者创建了一个游戏,从一开始到可以上架到Google Play商店,让人们尝试。在这个项目的过程中,面临很多困难,因为这是一件以前没有做过,没有任何经验的工作。
  当用Cocos2D-X开发Project Cherry Brawl时,v2.2.3是Cocos2D-X最稳定的版本。在游戏开发两个月后,Co-cos2D-X团队发布了v3.0的Cocos2D-X和更新的功能【21】,这是对以前版本的一个重大更新。不幸的是,由于这个项目的时间约束,有必要坚持使用v2.2.3。
  在Project Cherry Brawl运行时,会出现随机崩溃的情况。当Eclipse被用作主要的IDE时,它给出的错误堆栈跟踪是不可读的,唯一的解释是它与内存分配有关。这就是为什么选择继续使用Visual Studio 2012开发的原因。使用Visual Studio,可以调试项目并摆脱随机崩溃事件。 Cocos2D-X提供了关于游戏引擎如何工作及其工作流程的观察。该信息可以被携带到诸如Unity或LibGDX的其他游戏引擎中。
  Project Cherry Brawl的创造过程中是一个宝贵的经验,但这个项目可能做成不同的样子。它试图模仿使用一个控制器,在手机上玩一个控制台游戏的感觉。但这已经被证明了很多次,在移动设备上似乎并没有很好的奏效。手机触摸和手势功能没有被利用,但这是创作者的个人喜好,因为它的目的是模仿老式的游戏与控制器的游戏。
  我不确定Project Cherry Brawl是否应该在几个Android市场(如Google Play Store和SlideMe [32])上发布后继续运行,但是在游戏结束一周后,我们的团队收到了很多正面反馈。起初,教学者只教导游戏在控制台或电脑平台上运行,但很明显,移动平台上也存在需求。它在PC上运行得非常好,因为有一个键盘和鼠标工作。因此,Project Cherry Brawl的开发者决定继续为Android平台开发,并最终扩展到其他移动设备,如iOS和Windows Phone。此外,由于最近发布的Cocos2D-X 3.0及其对C ++ 11和OpenGL 2.0的支持,该游戏将在低端设备上表现更好,为玩家提供更流畅的体验。

参考

1 http://yle.fi/uutiset/suurmenestys_supercellin_toimitusjohtaja_kaikki_lahtee_tekijatiimista/6584310 , 1.1.2014.
2 http://www.cocos2d-x.org/ , 5.1.2014.
3 http://www.cocos2d-x.org/wiki/Cocos2d-x , 7.1.2014.
4 http://www.cocos2d-x.org/wiki/Engine_Architecture, 3.2.2014.
5 http://www.cocos2d-x.org/reference/native-cpp/V2.2/d1/da4/classcocos2d_1_1_c_c_scene.html#ae3c0dadfbfae64c9dd1d5d9a6bec3d42, 3.3.2014.
6 http://www.mapeditor.org/, 4.3.2014.
7 https://github.com/bjorn/tiled/wiki/TMX-Map-Format, 15.4.2014.
8 http://www.codeandweb.com/texturepacker, 15.4.2014.
9 http://www.cocos2d-x.org/docs/tutorial/parkour-game-with-cocostudio/chapter1/en, 2.2.2014.
10 http://libgdx.badlogicgames.com/, 15.4.2014.
11 https://unity3d.com/, 15.4.2014.
12 http://unity3d.com/pages/2d-power?gclid=CLvjgp-j470CFasLcwodUp0A9g, 15.4.2014.
13 http://unity3d.com/unity/whats-new/unity-4.3, 15.4.2014.
14 http://www.learn-cocos2d.com/2013/11/mobile-game-engine-popularity-index/, 15.4.2014.
15 https://play.google.com/store/apps/details?id=com.letang.game103pp.cn, 22.3.2014.
16 http://www.gamasutra.com/view/feature/132674/game_ui_discoveries_what_players_.php, 16.1.2014
17 http://www.cocos2d-x.org/wiki/Multi_resolution_support, 3.1.2014.
18 http://www.cocos2d-x.org/forums/6/topics/16774, 4.3.2014.
19 http://www.cocos2d-x.org/wiki/Cocos2d-JS, 12.4.2014.
20 http://entropyinteractive.com/2011/02/game-engine-design-the-game-loop/, 16.4.2014.
21 http://slideme.org/ 1.5.2014.

日记本