使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

使用《红孩儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

使用《红孩儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

 

     大家好,我是红孩儿.经过一年左右业余时间的持续开发,《红孩儿工具箱》已经初步完成了一些不错的功能,大家可以用它来辅助我们基于Cocos2d-x的游戏开发工作,帮助我们提升工作效率,实现一些复杂的场景和动画效果。好啦,废话不多讲,今天我来讲解一下如何使用红孩儿工具箱制作小游戏-《打地鼠》GO

《打地鼠》这个游戏很简单,就是玩家在看到地鼠从土地里钻出来时用挥舞的锤子砸向地鼠就可以了。这个游戏需要做一个简单的场景,然后还需要一些动画,比如地鼠从土里钻出来的动画和锤子落下的动画等,然后还需要有文字显示积分。下面我们来讲解一下如何使用红孩儿工具箱来制做这一切。


一.拼图PLIST生成
     首先我们需要从www.game2z.com  网站,在左上角的 下载红孩儿工具箱最新版 链接处下载最新的0.2.2版本。下载后我们将其解压到自定义的目录。打开后我们可以看到工具箱EXE程序和一个dx9的dll.还有一个资源目录Resource,一个测试设备图片存放目录Dev以及一个配套的SDK目录.红孩儿工具箱只需要这个EXE和对应的这个dll就可以运行在Windows操作系统了.如果你的操作系统中安装了相应的dll,那么也就是说,整个红孩儿工具箱,只需要一个3M多的EXE程序就可以正常运行了.是不是很小巧绿色环保?


    下面我们在工具箱所在目录的资源目录Resource中新建立一个自已的项目资源目录DaDiShu。然后我们从Cocos2d-x的HelloLua工程资源里找到一些农场的图片,还有沙地和植物的图片,把它们拷贝到DaDiShu目录。这将是构成我们场景的重要资源。


使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

 

     我们将它们拷到DaDiShu下。然后启动工具箱,这时我们可以看到红孩儿工具箱的登录界面,我们一般查看可以选择离线登录,但离线登录不能导出动画和场景,主要是用于查看和编辑。如果是想导出,那就最好到www.game2z.com论坛注册一个正式用户的账号。在这里我们输入注册账号和密码后,点击“登录”,稍等片刻完成验证后即可进入工具箱主界面。

     使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

 

    我们首先要做的,是先设置一下我们的工程资源目录,点击“设置工程资源目录”按钮,选择我们的资源目录即可,一旦设置完成,工具箱就会开始遍历和登记工程目录下所有的文件资源,这样我们就可以使用工程资源目录下的图片了.下次再使用工具箱时也会自动的设置好资源目录.
    

    我们首先想做的是把crop.png图片进行碎图PLIST生成。Cocos2d-x是可以识别碎图PLIST文件的,工具箱也可以识别带有PLIST文件的PNG图片来使用碎图设置精灵,我们在工具箱主界面的第一个功能编辑页“拼图/切图”中就可以完成这个需求,“拼图/切图”页默认的是“拼图”导出面板,我们点击一下工具箱全局配置信息下面的“切图/拼图-[拼图”复选框,现在切换为“切图”编辑面板。这时候就可以将图片进行切图操作了。


使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

 

    我们点击“选择图片文件”打开crop.png图片,这时候在工具箱的左边图片元件树控件就会显示出crop这个图片树项,同时在视图窗口中会显示这张图片。如图:

 使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

          我们在左边的crop树项上右键,可以弹出菜单,这时候我们选择一下“按行列数切块”,在弹出的对话框中输入块名称crop,行数填1,列数填4即可,也可以在弹出菜单中选择“固定大小切块”,在弹出的对话框中输入切块宽高和间距边距,确定后我们可以看到在crop树项下生成了相应的图块。这时我们可以选择各树项进行查看,也可以在图片上直接点击显示图块项。

 使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       我们可以看到相应的图块会显示出调整矩形编辑框,这种方式是可以让我们通过鼠标点中编辑框结点来修改图块的大小和位置的。不过在这里使用行列数切块就不需要调整了,如果小伙伴们有自已的需求,也可以通过对图片项弹出菜单中的“加入新图块”来手动进行图块的切分。


        我们在编辑好图块后,确认一下图片导出的名称和目录,点击“立即导出”,这时工具箱就可以为我们的图片crop生成相应的PLIST。如图:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


生成的文件:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


在工具箱后面的场景制做中,我们就可以使用这个PLIST来进行各状态植物图片的摆放。

二。场景编辑

现在我们切换到场景编辑页中,如图:


使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       我们点击“创建”,来新建一个地图,这个《打地鼠》游戏场景不需要滚屏,只有一张背景图farm.jpg大小就可以了,在这里我们输入场景名称farm,场景宽800,高800。然后确定,就创建了场景,我们可以看到主视窗里场景大小的一个边框,我们的场景就是要放在这里面的。如图:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


      好,我们现在来规划一下这个场景的分层。我们可以将这个场景分为三层,第一层是农场背景,第二层是沙地格子,第三层是植被。这样将沙地格子放在农场背景中,植被放在沙地格子中,就可以实现一个农场的场景了。下面我们来实现一下。

      在右边的面板下部右键弹出菜单,选择“新增地图层”,然后会弹出一个地图层设置的对话框:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


        我们计划第一层只是放一个农场图片,所以没有必要考虑格子,输入层的名称“BK”后确定即可,之后会增加一个图层页BK,这个图层页中有一个空白树控件,是用来管理放在这一层的各种资源,比如图片,动画,粒子等。


      使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       我们在这个图层页中资源树区域右键点击,选中弹出菜单“增加新图类”项,选中后会弹出一个图片分类对话框,输入图片类名称“farm”,然后就会有一个图片类树项显示出来,我们可以在这个分类项上点击右键,在弹出菜单里我们可以看到很多可以增加的资源选项,我们在这里只加入一张背景图,所以选择“增加新图片”。

          使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


        在弹出的文件选择对话框中我们找到farm.jpg,然后确定,就可以将农场背景图加入到这一层的资源树中了。需要注意的是在浏览框中文件类型我们要选择jpg格式.因为这个图片是jpg的.


      使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


        我们点击图片项,可以看到在右上角的显示窗口中显示出这个资源项,然后我们把鼠标移动到主视窗中场景左上角附近点击一下,这时农场的背景图就被放入到场景中了。

        使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


         右键取消选中的资源,然后我们点选场景中的这个背景图片,在它被选中后我们在右边面板中点击“物件编辑”切换到物件的位置输入面板,输入位置0,0,就可以使其完全与场景框贴合在一起,这样我们第一层背景图就编辑好了。[为了方便查看,这里我按着Ctrl键的同时用鼠标滚轮缩放视图到合适大小.

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       下面我们来创建第二层沙土格子的图层,我们在地图层选项页右边空白处右键,在弹出的菜单中选择“新增地图层”:


      使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏



     之后我们可以看到建立新图层的对话框,我们现在要考虑的是对于沙土格子land.png这张图片,他是要基于网格进行拼合的,而它本身是有斜度的。对于有斜度的网格,我们要选择斜视角的观察方式,在这里我们输入格子的宽度为lan.png的宽高182x94,之后输入网格的位置偏移,这个位置偏移就是以场景左上角为起点向右下进行偏移的距离,结果位置将作为第一个格子(0,0)的起点。这个起点在普通观察方式下就是格子的左上角,在斜视角的观察方式下则是格子左角。我们在这里可以输入X偏移30,Y偏移440,然后设置格子的行数为5,列数为3,点击确定后这一层就创建成功了,我们可以选中视图区左上角的“显示格子”看到在场景的相对偏移位置作为起点显示出了53列的斜视角网格。如图:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

          如果我们觉得格子大小或位置不合适,也可以在相应的图层页项上右键点击,在弹出菜单里点击“修改当前图层”进行反复修改:


    使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


经过反复确认后,偏移位置x设为30,y设为460比较好,能够比较准确的将53列的格子放置在土地区域。

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


   好,我们在这一层的资源树控件中按照之前的方式增加图片类“land”,然后把land.png加入进来选中它,这时候我们就可以在相应的格子上刷图了,我们将鼠标在选中land.png的状态下移到场景中,如果我们选中了视图区左上角的“显示格子”复选框,那么在相应的格子上点击,就会自动在格子中刷上相应的图片。如果我们按下Ctrl键的同时从第1个格子向最后一个格子拖动那么将直接进行区域刷格子。如图:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

      这样,第二层的沙土格子层我们就创建出来了。现在我们要继续创建植物层,植物层不需要格子,所以和第一层背景的建立方式是一样的,在右边面板选项空白处右键,在弹出的菜单中选择“新增地图层”进入到建立新图层的对话框,输入“OBJ”直接确定就可以。下面我们将crop.png加入到这一层的资源树中,这时我们可以看到它会自动的识别所有的图块。我们可以点击图片crop.png来放到场景中,也可以选中其下的crop_0~4来放入到场景中,在这里我们随便选一些图块放到场景沙土地的相应位置上如图:

     

    使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


   

        现在我们第三层也就做好了,是不是很简单?

        最后我们来生成一些事件点来创建地鼠。因为地鼠是从沙土地上生成出来的,所以这些事件点也就放在格子中,我们在右边面板切换到第二层沙土格子层。在图类上右键,选择弹出菜单项“增加事件格”,取中视图区左上角的“显示格子”复选框,同时为了方便查看,我们可以选择显示方式为“高亮当前层”项,这时候只有当前层的元素是高亮显示的。然后我们在场景沙土地的一些位置点击,把创建地鼠的事件格子编辑好后,切换为“显示所有层”,整个场景就算完成了。如图:


       使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏 

          

三.动画制作


首先我从网上找到老鼠,锤子,金币的图片并将它们用photoshop制做成动画序列图。

图一:地鼠钻出来的序列图

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

图二:锤子落下的序列图

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

图三:金币闪现的序列图

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


    好了,现在我们切换到“切图”面板,然后按照之前crop.png的切图方式来为它们生成相应的plist

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

     现在这些序列图已经有图块Plist了,我们开始为它们制做相就原动画.打开动画编辑面板,我们开始制做相应的序列帧动画.首先我们要建立一个图片结点.图片结点本身就是一个独立的精灵,可以表现动画.我们在左边的结点树控件的Root结点上右键单击,在弹出的菜单中选择“增加图片结点”:

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

      工具箱在图片结点和骨骼结点的显示图标是可以自定义的,如果没有定义,此时会弹出提示未设置图片结点默认图标的消息框,确定后会弹出相应的设置对话框,这时我们可以选择Resource下的cocos2d-x.pngBone.png来作为图片结点和骨骼结点的默认图标.

    

   使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

        确定后就会出现cocos2d-x.png来显示在视窗的中心点了.

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

      这时我们在这个图片结点项上右键,在弹出菜单中选择“生成固定帧间隔关键帧动画”就可以为这个图片结点弹出一个设置序列帧动画的对话框.

    使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

     在“创建固定帧间隔的关键帧动画”对话框中,有两种图片源选取方式,第一种是使用图片序列,就是一般多张图片如attack_0.pngattack_1.pngattack10.png这种多张同名使用不同数字后缀的图片进行生成,因为我们的图片是拼在一起的,所以这里我们选中“使用拼合图内图块序列生成”的方式.之后点击“查找图块”,这时会弹出一个新面板.

    使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

    

    这个新面板是做什么用的呢?它就是图片及动画资源库面板.在这里我们可以点击“导入资源文件到当前资源库中”这个按钮来将我们需要的图片加入.如果有时候我们编辑的时候修改了图片,那也可以在这里随时点击刷新资源文件进行重新加载.

    我们现在将锤子图片导入进来.并选中任意一个图块:

     使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


      这时候我们可以看到图片和图块都显示正确,然后我们点击“应用此图块”,这时候资源库对话框就消失了,我们会到之前的“创建固定帧间隔的关键帧动画”对话框中.可以看到图块起始为0,图块结束自动变为了2,我们把动画的间隔时间还使用默认的100毫秒,点击确定后,我们可以看到在动画编辑面板下部的帧显示区有3帧被设为了关键帧我们点击他们可以在主视窗中就显示出相应帧的动画了.

    使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


    

      我们可以在下面的帧显示区右部分点击“播放动画”复选框来直接查看动画的播放.并且可以手动随时调节帧间隔的时间来改变动画的速度.

      这样,这个锤子砸下来的动画就做好了.我们保存一下.在弹出的保存文件对话框里我们可以输入attack,格式仍为ani,确定后会再弹出一个修改动画名称的对话框,我们仍然输入attack后确定.这个动画就被保存为attack.ani文件了.同时会导出一个attack.plist.这个plist我们就可以在cocos2d-x中进行播放了.

      使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       按照上面锤子动画的制做方式我们继续完成老鼠出生的动画和弹出金币的动画,它们对应的图片为laoshu.pngjinbi.png,动画名称可以分别设为borthgoal.导出的动画也就分别是borth.plistgoal.plist.

       现在三个动画和三个序列帧的PLIST就都导出了.我们就把游戏中的场景和动画制做完成了.


四.字图制作


       我们现在还需要一些文字来显示游戏名称和得分.我想做成彩色的文字显示在游戏画面合适的位置.这要用到Cocos2d-x支持的字图.即使用png+fnt的方式显示字库,其中png图片存储文字的显示结果,fnt存储文字的位置信息.强大的红孩儿工具箱也提供了字图的编辑和导出功能.我们来试一下.


        我们现在切换到“字体编辑”面板,然后我们在文档信息框里删除原有文字后输入“打地鼠0123456789”,接下来我们选择自已想要的字体,这里我选的是华文琥珀,字大小为36.确定后我们可以看到文档信息框里文字变成了相应的字体.

         使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


         这时我们点击“开始生成”,即可以很快看到生成出来的字图:


       使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       这黑黑的文字不是我们想要的,现在我们来进行一下美化,点击右上角“编辑文字效果”按钮切换到编辑文字效果的面板。

     使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


        这时我们可以选择字体颜色,调节字的间距,以及选一种自已喜欢的阴影方式。之后我们还可以在图片着色部分中加载一张过渡图片来进行着色.比如这里我们使用font_effect1.png来进行单字应用的叠加着色.同时字体用红,阴影用黑,右下描边,阴影粗细填5,间距为1,一个五彩的字图就出现了:

        使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

       

       感觉玩的差不多了,可以点击导出fntpng字图保存为text.pngtext.fnt.这样我们的游戏就可以使用这个字图来进行游戏名称的显示和积分的显示了.

       使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


         

五.粒子制作

       最后,我还想在农场里加入一个雪花落下的粒子效果,这样可以更加增加场景的气氛感。我们切换到工具箱的“粒子编辑”面板。在这里我们可以看到在主视窗中有一个粒子效果。右边面板有一个可以选择的粒子模版库的下拉列表和一些属性值编辑区域

       使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


          在粒子模版库中放置了一些Cocos2d-x可以支持的粒子系统的样式。我们在这里要做一个下雪的效果,所以直接选择snow就可以了。

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       我们现在能看到下雪效果的粒子系统了,但是它的粒子是没有贴图的,还只是渐变色块,我们点击“更改图片”就可以找一个球体的图片来做为雪花的贴图。


  使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


         这样漂亮的雪点的效果就出现了。


使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


         我们可以根据需要作改一些属性参数。比如横向的粒子系统宽度和起始颜色。

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


      最后,我们点击“保存”,可以将其保存成snow.plist放在资源目录。

  使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


        下雪的粒子系统我们就算做好了,下面再切换到场景编辑部分把下雪的粒子系统加入到场景中。直接在第三个图层下的图类项上右键,在弹出菜单中选择“增加粒子系统”,之后将snow.plist导入就可以了。

        使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


       

    最后保存,并导出地图的XML就完成了场景中的下雪效果

    这样我们就把工具处理部分就算完成了,我们下面进入到代码的编写部分.

六.代码编写


     为了方便工程的建立,我们可以直接将Cocos2d-x中的HelloCpp工程目录复制一份出来,然后修改工程名,之后将工具箱附带SDK中的C++目录中的Map子目录中的代码拷贝到Classes中。

 使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


     然后我们打开工程,将相应文件加入到工程中

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏


   

现在我来介绍一下工具箱开源的场景代码,除了解析xml而加入的tinyxml之外,这里主要就是两个类文件


HHRMapLayer.h/cppHHRMapReader.h/cpp,它们分别是显示场景和解析场景文件的类。这两个类文件可以开源的哦~,大家学习之后就可以自行进行扩展并进行二次开发了。



CHHRMapReader 是用于工具箱的地图XML文件的解析,支持多层场景,任意网格设置,摆放图片和粒子系统,设置事件点,路径点。我们可以用工具箱来制做场景,导出成XML格式后用它来进行解析。


头文件代码:

#ifndef _HHRMAPREADER_H
 
#define _HHRMAPREADER_H
 
//==================================================================//
 
//File:        HHRMapReaer.h
 
//Date:        2013-09-05
 
//Auto:        Honghaier 
//Blog:        http://blog.csdn.net/honghaier
 
//Web:        http://www.game2z.com
 
//Desc:        用于红孩儿工具箱的地图解析,目前只支持图片和粒子系统
 
//==================================================================//
 
#include "cocos2d.h"
 
#include "ccTypes.h"
 
#include <stdio.h>
 
#include <string>
 
#include <vector>
 
using namespace std;
 
using namespace cocos2d;
 

#if (CC_TARGET_PLATFORM != CC_PLATFORM_WIN32)
 
//ANDROID平台上用的,用于位置
 
struct POINT
 
{
 
        int         x;
 
        int  y;
 
};
 
#define _MAX_PATH        256
 

#endif
 

#define BREAK_IF(a)                if(!a)break;
 
//地图头信息
 
struct stMapHeader
 
{
 
        int                m_nVersion;                                                        //版本号
 
        string        m_strMapName;                                                //场景名称
 
        int                m_nSceneWidth;                                                //场景宽度
 
        int                m_nSceneHeight;                                                //场景高度
 
        int                m_nLayerNum;                                                //场景层数
 
};
 

//元素类型
 
enum        enuElementType
 
{
 
        RET_NONE         = 0,        //什么也没有
 
        RET_IMAGE         = 1,        //静态图
 
        RET_ANI                 = 2,        //动画
 
        RET_PARTICLE = 3,        //粒子效果
 
        RET_EFFECT         = 4,        //效果
 
        RET_NPC                 = 5,        //角色
 
        RET_OBSTRUCT = 6,        //阻挡格
 
        RET_EVENT         = 7,   //事件格
 
};
 

//精灵扩展类
 
class  CCSpriteEx        :public CCSprite
 
{
 
public:
 
        //取得四边形顶点指针
 
        inline ccV3F_C4B_T2F_Quad* getQuadPtr(void) { return &m_sQuad; }        
 
};
 

//粒子系统扩展类
 
class        CCParticleSystemQuad_Ex        :public CCParticleSystemQuad
 
{
 
public:
 
        //取得PLIST
 
        const char*         getPListPath()
 
        {
 
                return m_sPlistFile.c_str();
 
        }
 
        //打开相应的粒子PLIST文件
 
        bool  LoadParticleInfoFromPListFile(const char* szPListFile)
 
        {
 
                return initWithFile(szPListFile);
 
        }
 
};
 

//资源信息
 
struct stMapResInfo
 
{
 
        enuElementType                                m_Type;                                                //类型
 
        string                                                m_strFileName;                                //文件名(图片名,动画PLIST名或粒子系统PLIST名)
 
        string                                                m_strBlockName;                                //图块名
 
        CCSpriteEx*                                        m_pSprite;                                        //精灵
 
        CCParticleSystemQuad_Ex*        m_pParticleSystem;                        //粒子系统
 
};
 

//批次结点处理
 
struct stBatchNodeInfo
 
{
 
        string                                m_strFileName;                //文件名(图片名)
 
        CCSpriteBatchNode*        m_pBatchNode;
 
}
 
;
 

//视角
 
enum enuViewType
 
{
 
        VT_NORMAL                = 0,        //普通
 
        VT_SKEW                        = 1,        //斜视角
 
        VT_FREE                        = 2,        //不使用格子
 
};
 

//*物体
 
struct stFreeObj
 
{
 
        stMapResInfo*        m_pResInfo;                                //对应的资源索引
 
        CCSprite*                m_pSprite;                                //排序时加入的精灵
 
        float                        m_fPosX;                                //X位置
 
        float                        m_fPosY;                                //Y位置
 
        float                        m_fLowerHeight;                        //最低位置(用于排序)
 
};
 

//路径
 
struct stPathNode
 
{
 
        bool                        m_bIsTile;                                //是否是格子
 
        POINT                        m_sSrcTile;                                //起点格子,如果是格子,则为格子位置,否则为像素位置
 
        POINT                        m_sDestTile;                        //终点格子,如果是格子,则为格子位置,否则为像素位置
 
}
 
;
 

//事件
 
struct stEventTile
 
{
 
        int                                m_nEventID;                                //事件ID
 
        bool                        m_bIsTile;                                //是否是格子
 
        POINT                        m_sTile;                                //如果是格子,则为格子位置,否则为像素位置
 
};
 

//层结构
 
struct stMapLayerInfo
 
{        
 
        enuViewType                        m_ViewType;                        //视角
 
        int                                        m_nTileWidth;                //格子宽度
 
        int                                        m_nTileHeight;                //格子高度
 
        int                                        m_nTileRows;                //格子行数
 
        int                                        m_nTileCows;                //格子列数
 
        int                                        m_nStartPosX;                //横向格子起点位置
 
        int                                        m_nStartPosY;                //纵向格子起点位置
 
        stMapResInfo**                m_pTileResArray;        //格子对应资源索引
 
        vector<stFreeObj>        m_ObjectVec;                //*物体容器
 
        int                                        m_ObjectNum;                //*物体数量
 
        vector<stPathNode>        m_PathNodeVec;                //路径容器
 
        int                                        m_PathNodeNum;                //路径点数量
 
        vector<stEventTile> m_EventTileVec;                //事件容器
 
        int                                        m_EventTileNum;                //事件点数量
 
};
 

//地图解析类
 
class CHHRMapReader
 
{
 
public:
 
        //构造
 
        CHHRMapReader();
 
        //析构
 
        ~CHHRMapReader();
 

public:
 
        //从文件中载入地图
 
        bool                        LoadDataFromFile(const char* szFileName);
 
        //从内存中载入地图
 
        bool                        LoadDataFromData(const char* szData);
 
        //清空
 
        void                        CleanUp();
 

public:
 

        //取得场景头信息
 
        stMapHeader*        GetMapHeader();
 
        //取得资源数量
 
        int                                GetResInfoNum();
 
        //取得资源指针
 
        stMapResInfo*        GetResInfoPtr(int vIndex);
 

        //取得层数量
 
        int                                GetLayerInfoNum();
 
        //取得层信息指针
 
        stMapLayerInfo*        GetLayerInfoPtr(int vLayerIndex);
 

        //取得相应格子的资源数据
 
        stMapResInfo*        GetTileResData(int vLayerIndex,int vTileX,int vTileY);
 
        
 
        //取得对应层的*物体数量
 
        int                                GetLayerFreeObjNum(int vLayerIndex);
 
        //取得对应层的*物体
 
        stFreeObj*                GetLayerFreeObj(int vLayerIndex,int vObjIndex);
 
        
 
        //取得路径数量
 
        int                                GetLayerPathNodeNum(int vLayerIndex);
 
        //取得对应层的制定路径
 
        stPathNode*                GetLayerPathNode(int vLayerIndex,int vPathNodeIndex);
 

        //取得指定格子是分支路径起点的分支路径数量
 
        int                                GetNextPathNodeNum(int vLayerIndex,int vTileX,int vTileY,vector<int>& vNextPathNodeVec);
 

        //取得事件点数量
 
        int                                GetLayerEventTileNum(int vLayerIndex);
 
        //取得对应层的事件点
 
        stEventTile*        GetLayerEventTile(int vLayerIndex,int vEventTileIndex);
 


private:
 
        //头信息
 
        stMapHeader                                                m_MapHeader;
 
        //资源信息容器
 
        vector<stMapResInfo>                        m_MapResInfoVec;
 
        //地图层信息容器
 
        vector<stMapLayerInfo>                        m_MapLayerInfoVec;
 
        //批次结点信息
 
        vector<stBatchNodeInfo>                        m_SpriteBatchNode;
 

};
 

#endif

        从这个文件里我们可以看到CHHRMapReader能够从XML场景信息文件中读取场景信息,层数,网格信息,*物体信息,路径信息,以及事件点信息,很多信息都是基于图层索引来获取的,这样是为了适应工具箱的多层随意网格的特性。

        CHHRMapLayer是用于使用Cocos2d-x进行场景显示的类。他本身就可以显示出XML地图了。

#ifndef _HHRMAPLAYER_H
 
#define _HHRMAPLAYER_H
 
//==================================================================//
 
//File:        HHRMapLayer.h
 
//Date:        2013-09-05
 
//Auto:        Honghaier 
//Blog:        http://blog.csdn.net/honghaier
 
//Web:        http://www.game2z.com
 
//Desc:        用于红孩儿工具箱的地图显示,目前只支持图片和粒子系统
 
//==================================================================//
 
#include "HHRMapReader.h"
 
using namespace std;
 
USING_NS_CC;
 

//场景的精灵
 
struct stHHRMapSprite
 
{
 
        CCSprite*                                m_Sprite;
 
        CCPoint                                        m_sPosition;                        //位置
 
};
 
//场景的精灵层
 
struct stHHRMapSpriteLayer
 
{
 
        vector<stHHRMapSprite*>        m_MapSpriteVec;                        //精灵
 
};
 

//红孩儿工具箱的地图层显示
 
class CHHRMapLayer        :public        CCLayer
 
{
 
public:
 
        //构造
 
        CHHRMapLayer();
 
        //析构
 
        ~CHHRMapLayer();
 

public:
 
        //加载场景XML文件
 
        bool                                LoadHHRMap(const char* szFileName);
 
        //地图读取器
 
        CHHRMapReader*                GetMapRender();
 
        //设置观察点
 
        void                                SetCameraPos(float fX,float fY);
 
        //取得摄像机的当前位置
 
        CCPoint                                GetCameraPosition();
 
        //移动摄像机的位置
 
        void                                MoveCamera(float vOffsetX,float vOffsetY);
 

        //通过位置取得格子
 
        POINT                                GetClickTile(int vLayerIndex,int vPosX,int vPosY);
 
        //通过格子取得位置(格子中心点位置)
 
        CCPoint                                GetTileCenterPos(int vLayerIndex,int vTileX,int vTileY,bool bIsScreenPos = true);
 

        //放入一个新的精灵到一个格子上
 
        stHHRMapSprite*                AddSpriteToTile(CCSprite*        pSprite,int vShowIndex,int vLayerIndex,int vTileX,int vTileY);
 
        //放入一个新的精灵到场景中
 
        stHHRMapSprite*                AddSpriteToMap(CCSprite*        pSprite,int vShowIndex,int vPosX,int vPosY);
 
        //开启精灵的动画播放
 
        void                                RunSpriteAction(CCSprite*        pSprite);
 
        //取得放入的精灵数量
 
        int                                        GetSpriteNum(int vLayerIndex);
 
        //取得指定的精灵
 
        stHHRMapSprite*                GetSprite(int vLayerIndex,int vSpriteIndex);
 
        //删除指定的精灵
 
        void                                DelSprite(CCSprite*        pSprite);
 
        //删除所有的精灵
 
        void                                DelAllSprites();
 

        //设置使用按下拖放
 
        void                                SetTouchDrag(bool bTouchDrag);
 

public:
 
        //渲染
 
        virtual void                draw(void);
 
        //加载时调用
 
        virtual void                onEnter();
 
        //释放时调用
 
        virtual void        onExit();
 
        //响应触屏事件处理
 
        virtual void                ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
 
        virtual void                ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
 
        virtual void                ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent);
 
        virtual CCObject*        copyWithZone(CCZone *pZone);
 
        virtual void                touchDelegateRetain();
 
        virtual void                touchDelegateRelease();
 

private:
 

        //更新场景
 
        void                                UpdateScene();
 
        //渲染指定格子
 
        void                                RenderTile(int vLayerIndex,int vTileX,int vTileY,ccColor4B color);
 
        //渲染对应的图素
 
        void                                RenderElement(enuViewType        vCameraType,CCSize        vTileSize,stMapResInfo*        pRenderInfo,float vPosX,float vPosY,float vPosZ);
 

private:
 

        //地图读取器
 
        CHHRMapReader                                m_MapReader;
 
        //当前放在场景层中的精灵
 
        vector<stHHRMapSpriteLayer>        m_SpriteLayerVec;
 
        //当前观察点
 
        CCPoint                                                m_sCameraPos;
 
        //按下时记录上一个点的位置
 
        CCPoint                                                m_sTouchLastPos;
 
        //是否响应拖动处理
 
        bool                                                m_bTouchDrag;
 
        //上次更新的时间                
        double                                                m_dwLastTime;
 
        //错误返回字符串
 
        string                                                m_ErrorStr ;
 
}        
 
;
 
#endif

         从这个代码中我们可以看到CHHRMapLayer就是一个CCLayer,它拥有CCLayer的特性,可以直接放在场景中进行显示。它还可以进行进行格子的获取以及将一个精灵放置在格子上。



        我们这现在就使用这两个类来进行《打地鼠》的制做。


         我们打开HelloWorldScene.h,在这里引入”HHRMapLayer.h”,并为HelloWorld创建一个地图显示层的成员指针用于实例化这个地图显示层。并加入基于鼠标位置显示在屏幕上的锤子精灵以及显示分数的字图文字标签。


#ifndef __HELLOWORLD_SCENE_H__
 
#define __HELLOWORLD_SCENE_H__
 
#include "cocos2d.h"
 
#include "HHRMapLayer.h"
 

class HelloWorld : public cocos2d::CCLayer
 
{
 

public:
 
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
 
    virtual bool init();  
 

    // there's no 'id' in cpp, so we recommend returning the class instance pointer
 
    static cocos2d::CCScene* scene();
 
    
    // a selector callback
 
    void menuCloseCallback(CCObject* pSender);
 

        //老鼠出生的回调函数
 
        void LaoShuBorth(float dt);
 

        //渲染
 
        virtual void                draw(void);
 
        //响应触屏事件处理
 
        virtual void                ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
 
        //删除精灵
 
        void                                DelSpriteFunc(CCNode* pTarget);
 
protected:
 
        //地图显示层
 
        CHHRMapLayer*                m_pHHRMapLayer;                        
 
        //锤子
 
        CCSprite*                        m_pChuiZiSprite;
 
    //计分器
 
        CCLabelBMFont*                m_pCountLabel;
 
        //计数
 
        int                                        m_nAttackMouseCount;
 

    CREATE_FUNC(HelloWorld);
 
};
 


#endif // __HELLOWORLD_SCENE_H__

       然后我们打开HelloWorldScene.cpp,在HelloWorld::init函数中加载地图并创建相应的精灵


// on "init" you need to initialize your instance
 
bool HelloWorld::init()
 
{
 
    //////////////////////////////
 
    // 1. super init first
 
    if ( !CCLayer::init() )
 
    {
 
        return false;
 
    }
 
    
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
 
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
 

    /////////////////////////////
 
    // 2. add a menu item with "X" image, which is clicked to quit the program
 
    //    you may modify it.
 

    // add a "close" icon to exit the progress. it's an autorelease object
 
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
 
                                        "CloseNormal.png",
 
                                        "CloseSelected.png",
 
                                        this,
 
                                        menu_selector(HelloWorld::menuCloseCallback));
 
    
        pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
 
                                origin.y + pCloseItem->getContentSize().height/2));
 

    // create menu, it's an autorelease object
 
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
 
    pMenu->setPosition(CCPointZero);
 
    this->addChild(pMenu, 1);
 


        //因为我们要显示的文字是汉字,所以为了避免乱码,我们在这里将文字存入到XML中,然后在Cocos2d-x中读取。
 
        CCDictionary *strings = CCDictionary::createWithContentsOfFile("string.plist"); 
        const char *title = ((CCString*)strings->objectForKey("title"))->m_sString.c_str(); 
        CCLabelBMFont* pLable = CCLabelBMFont::create(title, "text.fnt");
 
    pLable->setPosition(ccp(visibleSize.width - 120, visibleSize.height - 100));
 
    this->addChild(pLable,1);
 

        //显示计数
 
        m_pCountLabel = CCLabelBMFont::create("0", "text.fnt");
 
    m_pCountLabel->setPosition(ccp(visibleSize.width - 120, visibleSize.height - 200));
 
    this->addChild(m_pCountLabel,1);
 
        m_nAttackMouseCount = 0;
 
        //-===载入地图=========================================
 
        m_pHHRMapLayer = new CHHRMapLayer();
 
        if(true == m_pHHRMapLayer->LoadHHRMap("park.xml"))
 
        {
 
                m_pHHRMapLayer->autorelease();
 
                addChild(m_pHHRMapLayer,0,0);
 
                m_pHHRMapLayer->SetTouchDrag(false);
 
        }
 
        else
 
        {
 
                delete m_pHHRMapLayer ;
 
                m_pHHRMapLayer = NULL;
 
        }
 

        CCSpriteFrameCache *frameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
 
        //锤子的拼图
 
        frameCache->addSpriteFramesWithFile("chuizi.plist");
 
        //老鼠的拼图
 
        frameCache->addSpriteFramesWithFile("laoshu.plist");
 
        //金币的拼图
 
        frameCache->addSpriteFramesWithFile("jinbi.plist");
 

        CCAnimationCache::purgeSharedAnimationCache();
 
        CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();
 


        //老鼠出现的动画
 
        animCache->addAnimationsWithFile("dishu_borth.plist");
 
        //锤子击打的动画
 
        animCache->addAnimationsWithFile("attack.plist");
 
        //金币弹出奖励的动画
 
        animCache->addAnimationsWithFile("jiangli.plist");
 

        //锤子
 
        m_pChuiZiSprite = CCSprite::create();
 
        CCSpriteFrame *frame = frameCache->spriteFrameByName("ChuiZi_0");
 
        m_pChuiZiSprite->setDisplayFrame(frame);
 
        m_pChuiZiSprite->setAnchorPoint(ccp(0.8,0.2));
 
        addChild(m_pChuiZiSprite);
 
        //每2秒出现一只老鼠
 
        schedule(schedule_selector(HelloWorld::LaoShuBorth), 2.0f);
 

        srand(time(0));
 
        //设置可以触屏响应
 
        setTouchEnabled(true);
 
        SimpleAudioEngine::sharedEngine()->preloadEffect("hit.mp3");
 
    return true;
 
}

       首先是创建了一个显示《打地鼠》标题的文字标签,然后是显示计数的文字标签。在这里我们使用了中文,为了避免因编码显示错乱,我们创建了一个XML文件string.plist来使用UTF8存储文字“打地鼠”并在Cocos2d-x中使用。

     

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

     

       随后我们实例化地图层,并调用其LoadHHRMap来加载一个工具箱导出的XML地图文件。再后面就是将拼图PLIST和动画PLIST加载进来,创建锤子精灵和动画,设定一个定时器,每2秒调用一次回调函数LaoShuBorth,哈哈,我那烂烂的E语。为了更加生动,我们在这里还预加入一个音乐文件hit.map来播放击中老鼠时的音效。


       之后我们来编写LaoShuBorth,它每2秒被回调的时候,我们可以创建老鼠的精灵和动画并放入到场景的相应事件点格子位置就可以了。事件点即可以基于格子,也可以基于像素,这个最好在代码中判断一下。

    

void HelloWorld::LaoShuBorth(float dt)
 
{
 
        if(m_pHHRMapLayer)
 
        {
 
                CHHRMapReader*        tpMapReader = m_pHHRMapLayer->GetMapRender();
 
                if( tpMapReader )
 
                {
 
                        int                nEventTileNum                = tpMapReader->GetLayerEventTileNum(1);
 
                        int                nEventTileIndex                = rand() % nEventTileNum ;
 
                        stEventTile*        pEventTile        = tpMapReader->GetLayerEventTile(1,nEventTileIndex);
 
                        if(pEventTile->m_bIsTile)
 
                        {
 
                                //取得事件ID
 
                                int nEventID = pEventTile->m_nEventID ;
 

                                CCSpriteFrameCache *frameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
 

                                CCSprite *dishu = CCSprite::create();
 
                                CCSpriteFrame *frame = frameCache->spriteFrameByName("dishu_0");
 
                                dishu->setDisplayFrame(frame);
 
                                CCSize winSize = CCDirector::sharedDirector()->getWinSize();
 
                                dishu->setAnchorPoint(ccp(0.5,0.0));
 
                                m_pHHRMapLayer->AddSpriteToTile(dishu,1,1,pEventTile->m_sTile.x,pEventTile->m_sTile.y);
 

                                CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();
 
                                CCAnimation *Borth = animCache->animationByName("borth");
 
                                Borth->setRestoreOriginalFrame(true);
 
                                CCAnimate *BorthAni = CCAnimate::create(Borth);
 
                                // run the animation
 


                                dishu->runAction( CCSequence::create( BorthAni,  CCCallFuncN::create(this, callfuncN_selector(HelloWorld::DelSpriteFunc)),NULL));
 
                                m_pHHRMapLayer->RunSpriteAction(dishu);
 
                                //由场景层管理,不需要放入当前层
 
                                //addChild(dishu);
 
                        }
 
                }
 
        }
 
        
 
}
    这里要注意的是,如果我们放入一个精灵到地图中,我们调用地图层的AddSpriteToTile函数,但如果这个精灵本身是个序列帧动画,我们还要在它runAction之后再调用一下地图层的RunSpriteAction 保证它被更新播放。在给它运行一个动画时,最好放入一个动画序列,在这个动画序列的最后再调用一个删除精灵的回调函数以保证精灵可以在合适的时机释放。

//删除精灵
 
void        HelloWorld::DelSpriteFunc(CCNode* pTarget)
 
{
 
        if(m_pHHRMapLayer)
 
        {
 
                CCSprite        *pMouseSprite = dynamic_cast<CCSprite*>(pTarget);
 
                if(pMouseSprite)
 
                {
 
                                m_pHHRMapLayer->DelSprite(pMouseSprite);
 
                }
 
        }
 
}

     这样我们运行一下就可以看到我们前面用工具箱制做的地图了,也可以发现每2秒会从事件点对应的沙地格子上生成一个老鼠。

     现在我们希望在鼠标移动时,锤子能跟随移动,怎么做呢?我们需要重载一下HelloWorlddraw函数,并在此中加入获取鼠标位置的代码,然后将鼠标位置设置给锺子。


//渲染
 
void HelloWorld::draw(void)
 
{
 
        
 
        POINT        tCurrPos;
 
        ::GetCursorPos(&tCurrPos);
 
        CCEGLView*        pGELView = CCDirector::sharedDirector()->getOpenGLView();
 
        ::ScreenToClient(pGELView->getHWnd(),&tCurrPos);
 
        if(m_pChuiZiSprite)
 
        {
 
                CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
 
                m_pChuiZiSprite->setPosition(ccp(tCurrPos.x/pGELView->getFrameZoomFactor() ,visibleSize.height - tCurrPos.y/pGELView->getFrameZoomFactor()));
 
        }
 

        CCLayer::draw();
 
}

    下面就只有点击鼠标时,播放锤子打击老鼠时弹出金币,和加分的处理了,在Cocos2d-x中我们可以重载HelloWorldccTouchesBegan函数来实现对鼠标按下的响应并设置HelloWorld层开启触屏事件响应。如果是在手机或Pad上,那就是我们点击屏幕时的响应函数。

        

//响应触屏事件处理
 
void HelloWorld::ccTouchesBegan(CCSet *pTouches, CCEvent* event)
 
{
 
        CCSetIterator iter = pTouches->begin();
 
        for (; iter != pTouches->end(); iter++)
 
        {
 
                CCTouch* pTouch = (CCTouch*)(*iter);
 
                CCPoint        tClickPt = pTouch->getLocation();
 


                CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();
 
                CCAnimation *Borth = animCache->animationByName("chuizi");
 
                Borth->setRestoreOriginalFrame(true);
 
                CCAnimate *AttackAni = CCAnimate::create(Borth);
 
                // 运行击打动画
 
                m_pChuiZiSprite->runAction(AttackAni);
 

                // 点击位置,做一个(100,50)的偏移,将攻击点移到锤子头部位置附近
 
                POINT        tCurrPoint;
 
                tCurrPoint.x = tClickPt.x ;
 
                tCurrPoint.y = tClickPt.y ;
 

                CCPoint        tCameraPos = m_pHHRMapLayer->GetCameraPosition();
 
                //击中的老鼠
 
                int                nLaoShuNum = m_pHHRMapLayer->GetSpriteNum(1);
 
                for(int s = 0 ; s < nLaoShuNum ; s++)
 
                {
 
                        stHHRMapSprite*                tpHHRMapSprite = m_pHHRMapLayer->GetSprite(1,s);
 
                        if(tpHHRMapSprite)
 
                        {
 
                                if(tpHHRMapSprite->m_Sprite)
 
                                {
 
                                        int nScreenPosX = tpHHRMapSprite->m_sPosition.x - tCameraPos.x;
 
                                        int nScreenPosY = tpHHRMapSprite->m_sPosition.y - tCameraPos.y;
 

                                        RECT tClickRect;
 
                                        tClickRect.left                = nScreenPosX ;
 
                                        tClickRect.top                = nScreenPosY ;
 
                                        tClickRect.right        = nScreenPosX + tpHHRMapSprite->m_Sprite->getContentSize().width ;
 
                                        tClickRect.bottom        = nScreenPosY + tpHHRMapSprite->m_Sprite->getContentSize().height;
 

                                        if(PtInRect(&tClickRect,tCurrPoint))
 
                                        {
 
                                                m_pHHRMapLayer->DelSprite(tpHHRMapSprite->m_Sprite);
 
                                                m_nAttackMouseCount++;
 
                                                char szTemp[10];
 
                                                sprintf(szTemp,"%d",m_nAttackMouseCount);
 
                                                m_pCountLabel->setString(szTemp);
 
                                                SimpleAudioEngine::sharedEngine()->playEffect("hit.mp3");
 
                                                
 
                                                //击中的格子
 
                                                POINT        tClickTile = m_pHHRMapLayer->GetClickTile(1,nScreenPosX,nScreenPosY);
 
                                                if(tClickTile.x >= 0 && tClickTile.y >= 0)
 
                                                {
 
                                                        CCSpriteFrameCache *frameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
 

                                                        CCSprite *jinbi = CCSprite::create();
 
                                                        CCSpriteFrame *frame = frameCache->spriteFrameByName("JinBi_0");
 
                                                        jinbi->setDisplayFrame(frame);
 
                                                        CCSize winSize = CCDirector::sharedDirector()->getWinSize();
 
                                                        jinbi->setAnchorPoint(ccp(0.5,0.0));
 

                                                        m_pHHRMapLayer->AddSpriteToTile(jinbi,2,1,tClickTile.x,tClickTile.y);
 

                                                        //跳金币动画
 
                                                        CCAnimationCache *animCache = CCAnimationCache::sharedAnimationCache();
 
                                                        CCAnimation *pAnimation = animCache->animationByName("jiangli");
 
                                                        Borth->setRestoreOriginalFrame(true);
 
                                                        CCAnimate *JiangLiAni = CCAnimate::create(pAnimation);
 
                                                        //渐隐消失动画
 
                                                        CCActionInterval*  action1 = CCFadeOut::create(1.0f);
 
                                                        //运行动画序列,先跳金币后消失
 
                                                        jinbi->runAction( CCSequence::create( JiangLiAni, action1,  CCCallFuncN::create(this, callfuncN_selector(HelloWorld::DelSpriteFunc)),NULL));
 
                                                        //设置这个精灵运行动画
 
                                                        m_pHHRMapLayer->RunSpriteAction(jinbi);
 
                                                }
 
                                                
 
                                                break;
 
                                        }
 
                                }
 
                        }
 
                }
 

        }
 

}        

          

       这里面的代码较多,主要流程就是先获取到鼠标点位置,然后遍历场景中的所有地鼠的精灵,之后通过点与矩形的位置判断来确定是否击中地鼠。如果击中,增加分数并播放地鼠的精灵并播放击中的音效。同时在相应的格子上创建金币的精灵动画并播放。


       好了,这样《打地鼠》游戏就算完成了,运行一下,嘿嘿,还不错嘛~

使用《红娃儿工具箱》开发基于Cocos2d-x的《打地鼠》游戏

结束语

谢谢大家的对工具箱的支持和关注,我会继续完善工具箱并编写更多的游戏实例。敬请期待!

另外有任何关于工具箱的问题可以到http://www.game2z.com工具箱专版与我进行交流!

我的新浪微博:http://weibo.com/u/1834515945 工具箱用户群:20970366