免责申明(必读!):本博客提供的全部教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客全部人、发表该翻译稿之人无任何关系。谢谢合做! css
原文连接地址:http://www.raywenderlich.com/1163/how-to-make-a-tile-based-game-with-cocos2d html
教程截图: java
在这个2部分的教程中,我将会教你们如何使用cocos2d来作一个基于tile地图的游戏,固然还有Tiled地图编辑器。(咱们小时候玩的小霸王小学机里面的游戏,大部分都是基于tile地图的游戏,如坦克大战、冒险岛、吞食天地等)咱们将会建立一个忍者在沙漠中找西瓜吃的小游戏。-_- 安全
在第一部分教程中,我将教你们如何使用Tile来建立地图,怎样把地图加到游戏中,怎么让地图跟随玩家滚动,以及怎样使用对象层。 app
在第二部分教程中,我将介绍如何在地图中建立可碰撞的区域,如何使用tile属性,如何制做可拾取的物体和动态修改地图,还有确保忍者不要吃撑了! 框架
若是你尚未准备好的话,你可能须要先从《如何使用cocos2d来制做简单的iphone游戏》系列教程开始学起,由于咱们这个教程使用了大量的基本概念,而这些概念均可以从上面的教程中获取。 iphone
好了,让咱们玩一玩tile地图吧! 编辑器
让咱们首先建立整个工程的骨架,这样能够确保从此咱们须要的文件都包含进来了,而且可以跑起来。 ide
所以,启动XCode,点击“File\New Project...”,选择cocos2d Application template,而且把工程命名为TileGame。 函数
接下来,下载游戏资源文件。这个资源文件包里包含了如下内容:
一旦你得到了这些资源,解压并把它拖到你的工程的“Resources”分组下面。确保复选中“Copy items into destination group’s folder (if needed)”,引用类型为“Relative to Project”,而后点击增长。
若是一切顺利,全部的文件应该都在你的工程里了。是时候制做咱们的地图了!
cocos2d支持使用开源的Tile地图编辑器建立的TMX格式的地图。
(做者给出的网址如今打不开了,这是我在另外一个地方找到的。我把它放到个人网盘里了,而且作了一个连接。若是有人下载不了,请留言。这个tile地图编辑器是java版的,其实还有一个at版的,可是java版的功能强大一些。可是,你们请注意,做者使用的是qt版本的,因此界面会有一些不一致,但这并不影响程序的使用。)
下载完以后,直接双击运行。点击File\New,而后会出现如下对话框:
在 orientation部分,你能够选择Orthogonal(参考: Legend of Zelda)或者Isometric(参考: Disgaea)。咱们这里将选择Orthogonal。
接下来,设置地图的大小。记住,这个大小是以tile为单位的,而不是以像素为单位。咱们将建立一个尽可能小的地图,所以选择50×50.
最后,你指定每一个tile的宽度和高度。你这里选择的宽度和高度要根据你的实际的tile图片的尺寸来作。这个教程使用的样例tile的尺寸是32×32,因此在上面的选项中选择32×32.
接下来,咱们把制做地图所须要的tile集合导入进来。点击菜单栏上面的“TileSets”菜单,“New Tileset...”,而后会出现下面的窗口:
为了得到图片,点击Browse按钮,而后定位到你的TestGame文件夹,选择 tmw_desert_spacing.png文件,而后加到工程中去。它会基于文件名自动填充Name。而后把TileSet name命名为“tmw_desert_spacing.png”.同时,设置下面的Tile spacing和Margin都为1.
你能够保留宽度和高度为32×32,由于tile的实际大小也是这么多。至于margin和spacing,我还没找到任何好的文档解释如何设置这两个值,下面是个人我的见解:
若是你看看 tmw_desert_spacing.png,你将会看见每个tile都有一个像素的空白边界围绕着,这意味着咱们须要把margin和spacing设置为1.
一旦你选择ok,你将会看到Tilesets窗口中显示了一些tiles。如今,你能够制做地图了!点击工具栏上的“Stamp”按钮。点击Tile palette中的tile map,而后选择一个tile,而后再在地图上的任意位置单击,你就会看到你选中的tile出如今点中的地方了。
所以,继续制做地图吧---充分发挥你的聪明才智!确保增长至少一对建筑物在地图上,由于后面咱们须要一些东西来作碰撞。
记住一些方便的快捷方式:
一旦你完成了地图的绘制工做,在Layers选项卡的层上面双击(如今能够说是“Layer1”),而后重命名为“Background”。而后点击“File\Save”而且保存文件到你的工程的资源文件夹中,而且命名为“TileMap.tmx”。
后面咱们将会使用这个tmx来作一些有趣的事情,好了,让咱们把地图加载到游戏中去吧!
首先,第一件事情,右键点击Resources,选择“ Add\Existing Files…”,而后添加TileMap.tmx文件。
打开HelloWorldScene.h,而后添加一些成员变量,而且申明一声属性:
而后在HelloWorldScene.m文件中作以下修改:
这里,咱们调用CCTMXTiledMap类的一些方法,把咱们刚刚建立的地图文件加载进去。
一些简明的CCTMXTiledMap的背景知识。它是一个CCNode,你能够设置它的位置和比例等。这个地图的孩子是一些层,并且提供了一个帮助函数可让你经过层的名字获得层对象--咱们上面就是经过这种方面得到地图背景的。每个层都是一个CCSpriteSheet的子类,这里考虑了性能的缘由--可是这也意味着每个层只能有一个tile集。
所以,咱们这里作的全部这些,就是指向一个tile地图,而后保存背景层的引用,而且把tile地图加到HelloWorld层中。
好了,就这么多!编译并运行工程,你将会看到地图的左下角出如今模拟器中。
还不错!可是,这还不是一个游戏!咱们还须要三个东西:a)游戏主角,b)主角初使位置和c)可以移动视图,这样就好像是第一视角了。
好了,接下来让咱们来解决这些问题。
tiled支持两类层--tile层(就是咱们目前使用的层),还有对象层。
对象层容许你在地图上圈出一些区域,来指定一些事件的发生。好比,你可能想制做一个区域,在那里怪物将会跳出来,或者是一个区域,只要进入就会死掉。这咱们这个例子中,咱们将建立一个区域来显示咱们的游戏主角。
所以,找到Tiled的菜单,点击” Layer\Add Object Group…”,命名为“Objects”,而后选择Ok。若是你绘制了地图,你将会注意到,它并无绘制一个tile,而是画了一个很难看的灰色矩形,这个矩形咱们以后能够扩展,使之可以包含多个tiles或者移动它。
咱们只想要选择一个tile来让主角显示。所以,在你的地图上选择一个tile。这个区域的大小实际上并无关系,由于咱们仅仅使用x、y坐标。
而后,上面的黄色对象上面点右键, 取名为“SpawnPoint",而后选择Ok:
(添加对象方法很简单,看到左边的+号和-号了吗?一个是增长对象,一个是删除对象。点中加号之后,用鼠标能够拖出一个矩阵区域。)
(下面给出一些技巧。如何把一个对象准确放置到Background的空白区域,只须要调整背景的opacity就能够了)
假设,你能够作一些奇思妙想。你把对象的类型命名为cocos2d里面的class的名字,而后它会为你建立那个类型(好比CCSprite),可是,我在cocos2d自带的源代码里面代不到这样的例子。更新:来自GeekAndDad.com的Tyler提供了以前版本的cocos2d里面使用这种“妙想”的方法,可是,因为背景有白色,因此被移除了。
无论怎么说--咱们仅仅把这个类型设置为空就好了,最后cocos2d会为咱们建立NSMutableDictionary,咱们能够从中得到对象的各类属性,包含x,y坐标。
保存地图,而后返回XCode。在HelloWorldScene.h中作以下修改:
一样,修改HelloWorldScene.m,代码以下:
好了,让咱们先歇会儿,来解释一下对象层和对象组。首先,注意你经过CCTMXTiledMap对象的objectGroupNamed方法来得到对象层(而不是layerNamed方法)。它返回一个特殊的CCTMXObjectGroup对象。
咱们而后调用CCTMXObjectGroup类的objectNamed方法来得到一个NSMutableDictionary,这个字典包含了关于对象的大量信息,包括x和y坐标值,宽度和高度。在这个例子中,咱们只关心x和y坐标,所以,咱们提取出这两个信息,而且设置player的位置。
最后,我想设置这个视图为玩家所在的位置。所以,添加下面一个新方法到文件中:
好了,让我解释一下。假设这个函数是设置camera的中心。咱们容许用户传入地图上任何x、y坐标值--可是若是你仔细想一下,有些东西咱们并不想让它显示出来--好比,咱们不想让屏幕超过地图的边界(那些区域仅仅是一个空白区域!)
好比,看看下面这幅图:
看一下,何时camera的中心会小于winSize.width/2或者winSize.height/2,部分视图将会在屏幕以外?相似的,咱们须要检查上面的界限区间,也和咱们这里的情形同样。
所以,咱们把这个函数看做是设置camera的视角中心点。然而。。。那不彻底是咱们想要的。在cocos2d里面有一种方式能够直接操做一个CCNode的camera,可是那会使事情变得更复杂。咱们须要另外一种替代方法,那就是移动整个层。
看看下面的图:
想像一个大的地图,咱们查看从0到winSize.height/width的坐标。咱们的视图的中心点是centerOfView,并且咱们知道咱们要把这个中心设置到哪里(actualPositon)。所以,为了使实际的位置和视图中心相吻合,咱们只须要把地图往左下角移动便可!
这个能够经过使实际的位置减去视图的中心位置来实现,而后设置HelloWorld层到那个点。
唉!太多理论了--让咱们看点实际的吧!编译并运行项目,若是一切顺利,你将会看到忍者在场景当中,然而视角也移过来了。
咱们已经有一个好的开端了,可是咱们的忍者只是站在那儿不动!这可不像真正的忍者!
让咱们使忍者动起来吧,只须要让忍者移动到用户点击的地方就好了。在HelloWorldScene.m中增长如下代码:
首先,在init方法中设置层可以接收touch事件。若是咱们覆盖registerWithTouchDispatcher方法,来使这个层可以处理目标touch事件。这样会致使ccTouchBegan和ccTouchEnded方法被调用(注意是单数形式,而不是复数形式的ccTouchesBegan和ccTouchesEnded方法)
你可能会问,为何我要讲这个,由于咱们在 《如何使用cocos2d来制做简单的iphone游戏》里面使用的是ccTouchesBegan和ccTouchesEnded方法。那两个方法能够,在这个教程里用两种方法均可以。可是,我想向你们介绍一个新方法,由于它有两个优势:
无论怎么说,在咱们的ccTouchEnded里面,咱们转换屏幕touch坐标为局部view坐标,而后再转换成GL的坐标。这两个步骤,在新的cocos2d版本中,只须要一步完成,即调用 [self convertToNodeSpace:touchLocation].就能够了。
这是由于,touch位置只是告诉咱们屏幕视口的坐标(好比100,100)。可是,咱们咱们滚动了地图,这个位置实际可能对应地图的(800,800)。所以,调用这个方法基于咱们当前层的位置来决定touch的偏移。
接下来,计算出touch点和player的位置之差。咱们必须基于touch位置选择一个方向,所以,首先,咱们须要计算出是上下移动仍是左右移动。而后,咱们比较正负值,决定具体的方向。
相应的,咱们再调整player的位置,而且设置player的位置为视口的中心位置,这个在上一节中已经用到了。
更新:注意,咱们不得不添加一个安全检查,来确保咱们的player不会移到地图以外!这一点,是Geek&Dad指出来的,谢谢你!
编译并运行!你如今能够点击鼠标,想让尽者移到哪,它就移到哪儿!
这只是这个教程的一部分。此时,你应该了解一些建立tile地图的基础了,并且知道如何把它导入到游戏当中。
这里有咱们目前为止用的完整源代码。
接下,期待第二部分教程吧!在那里,我将教你们如何在地图中添加碰撞检测,若是使咱们的忍者沿着墙壁快乐的奔跑!