(3) cocos2d-x Tile Map 教程(一)

原文来自http://www.raywenderlich.com/39113/cocos2d-x-tile-map-tutorial-part-1

这是我很喜欢的一个学习网站。在里面能学到很多东西,同时也推荐给小伙伴们。


这是一个两部分的Cocos2d-x Tile Map系列教程,你将会创建一个关于荒漠中忍者寻找可口西瓜的简单游戏。

注意,这是关于Cocos2d-x的教程,它是用C++移植cocos2d-iphone的跨平台引擎。所以这里的代码可以在iPhone,Android或者更多的平台上使用。

在第一部分,你将会学到怎样添加一个图块地图到游戏中,玩家跟随地图移动,使用对象层等,你还会学到怎样使用地图编辑器创建图块地图。

第二部分,涵盖了如何在地图上加入可碰撞区域,怎样用图块属性,怎样收集东西和动态修改地图,还有怎样确保忍者不会吃撑了。

注意,这个教程是类似Cocos2d-iphone教程的移植版,如果你正在寻找Cocos2d-iphone版,你可以点这里

如果你之前不懂Cocos2d-x,那你可以先看看Cocos2d-x:太空游戏教程,它包含了很多基础的东西,有助于你学习这篇教程。

OK,来玩玩图块地图吧!

Getting Started

这篇教程需要最新的cocos2d-x版本(写这篇文章时是2.1.4版),如果你没有.....

我这里用的是2.2.1版本,所以后面没用的就不翻译了。

接着,创建一个名为MyTileGame的工程。(至于创建步骤,大家应该都懂)。

你将在工程中使用ARC,如果这是你第一次使用ARC,我推荐你看一下ARC教程系列,默认创建的工程是非ARC的,修改这个很简单,

点击Edit\Refactor\Convert to Objective-c ARC.展开下拉,选中main.m,AppDelegate.cpp,HelloWorldScene.cpp然后点击Check,完成向导。

编译-》运行,确保一切ok,你就会看到正常的HelloWord程序了。

接下来,下载游戏的压缩包,这里面包含了以下东西:

  • 你要用来做玩家对象的一个精灵,可能看起来眼熟SimpleGame
  • 使用一个不错的声效工具cfxr制作的一些声效。
  • 用Garage Band制作的一些背景音乐
  • 要用的图块集合,实际上地图编辑器自带得有,只是这样做起来更容易些。
  • 一些特殊的图块,呆会再做说明
一旦你下载好之后,解压TileGameResources文件到工程的Resources目录下,在工程菜单中,右键Resources文件夹,选着Add Files to "TileGame"...
选择Resources/TileGameResources文件夹,确认Copy items into desination group's folder(if needed)被选中,然后Create groups for any added folders
也是选中的,最后点击Finish.
上面的都完成好后,所有的文件应该被列到了工程中。就像这样:


是到玩玩地图的时候了。

Make a Map with Tiled

cocos2d-x支持用开源的Tile Map Editor创建的地图,保存为TMX格式。

如果你没有这个工具,可以通过上面的链接去下载,此时最新版是0.9.1.

打开Tiled,文件\新文件,将会出现下面的对话框:

各个参数都保持默认,然后点击OK

接着,就要绘画地图,所以要添加图块集合,在菜单栏上选择地图\新图块,然后按照下面填写内容:

为了得到图像,只需要点击浏览,然后到MyTileGame/Resources/TileGameResources文件件下,选择tmw_desert_spacing.png文件,然后就会自动帮你填好上面的名称。

你可以将宽度和高度设为32x32,因为这是图块的尺寸。至于边距间距的意思:

  • 边距 是当前图块在搜索实际像素前,应该跳多少像素(适用于宽度和高度)。
  • 间距 是在读取实际像素后得到下一个图块的数据,图块应该前进多少像素(适用于宽度和高度)。
  • 如果你看一下tmw_desert_spacing.png,你就会看到每一图块周围都有1像素的黑色边框,这就解释了边距和间距设置为1。

    点击OK,就会看到这些图块显示在图块窗口,现在可以开始画了!简单的点击一下工具栏上的图章刷,然后点击一个图块,点击地图上的任意一个地方放上图块。

    So,来画一个DIY的地图,确保至少要添加一些建筑物,因为后面要用来做碰撞。

    这里我就随便画了.....

    为了画起来更方便,你可以看一下这些快捷键,下面是一些常用的:

  • 你可以在图块选择器中拖动一个框系列的图块,能够同时放下多个相邻的图块
  • 你可以用工具栏上的填充工具,填充一块区域
  • 你可用视图中的放大和缩小工具
  • 在你用图章刷工具编辑地图时,可用z键来旋转图块
  • 你也许已经注意到在迷你地图中有一些新的功能,很不错的功能,让你能看迷你的地图。

    来看一下在迷你地图的下面我尝试做的简单迷宫。红色的方框表示你在主编辑窗口能看到的地图。

    当你要滚动区域的时候,记得用这个迷你地图功能。

    注意,本教程的资源来自上述地图预先制作——可以免费使用,如果你懒得自己做。如果你要自己做,你应该在Tiled中打开地图,看一下它是怎样建立起来的。

    画完地图后,双击图层窗口中得块层1,改名为Background.然后点文件\保存,保存到游戏工程的MyTileGame\Resources\TileGameResourcese目录,然后命名为TileMap.tmx,覆盖以前存在的那个文件。

    以后你将要用Tiled做更多的东西,现在先让这张地图进入游戏。

    Adding the Tiled Map to the cocos2d-x Scene

    HelloWorldScene.h文件,添加下面一行到#include "cocos2d.h"下面:

    USING_NS_CC;

    这表示编译器使用cocos2d的命名空间,这样就不必每个开头都加上cocos2d::前缀了。

    然后在类定义的做大括号的右后面,添加这些代码:

    private:

    CCTMXTiledMap*_tileMap;

    CCTMXLayer*_background;

    为了跟踪地图本身和背景层地图,创建了两个private变量。以后将会学到更多的图块地图图层。 接下来,用下面代码替换HelloWorldScene.cpp中的内容。

    #include"HelloWorldScene.h"


    USING_NS_CC;


    CCScene*HelloWorld::scene()

    {

    // 'scene' is an autorelease object

    CCScene*scene =CCScene::create();

    // 'layer' is an autorelease object

    HelloWorld*layer =HelloWorld::create();


    // add layer as a child to scene

    scene->addChild(layer);

    // return the scene

    returnscene;

    }

    // on "init" you need to initialize your instance

    boolHelloWorld::init()

    //////////////////////////////

    // 1. super init first

    if( !CCLayer::init() )

    {

    return false;

    }

    //加载地图,背景层

    _tileMap=newCCTMXTiledMap();

    _tileMap->initWithTMXFile("TileMap.tmx");

    _background=_tileMap->layerNamed("Background");

    this->addChild(_tileMap);

    return true;

    }

    这里,你调用了CCTMXTileMap类,让它用你之前用Tiled创建的地图文件来创建一个地图。 快速扫盲:CCTMXTileMap也是一个CCNode,可以设置它的位置,大小等,该节点的子节点是图块地图的图层,并有一个辅助的函数layerNamed;

    按名称查找,让你得到这个背景。考虑到性能的原因,每一个层都是CCSpriteSheet的子类,这也意味着每一层你只能有一个图块集。

    所以,上面的代码保存了图块地图和背景层的引用,然后添加到HelloWorld的层上。

    在ipad模拟器上编译-》运行代码,你应该会看到地图的左下角。

    还不错,但是对于这个游戏,你还需要做3件事:

    1. 一个玩家
    2. 玩家开始位置
    3. 为了能看到玩家需要能够移动地图视图

    而这就变得非常棘手,所以接下来让我们解决它。

    Tiled Object Layers and Setting Tile Map Position

    Tiled支持下面两种类型的图层:

  • 图块图层:这些是你至今一直使用到的。
  • 对象图层:为了识别事情发生的区域,它们允许你在地图上绘制矩形框。例如,你要做一个怪兽出来的地方,或者一个进入就死的地方。在本教程中,你将为玩家的出生点创建一个区域。
  • 所以,在Tiled工具中点击菜单栏上的图层\添加对象层,命名为Objects,为了插入这个Object,选中工具栏上得插入矩形(R)为了知道当前显示的图层可以看Tiled工具的左下角:

    如果你拖动地图,你会注意到并没有画图块,而是,画了个矩形框,你可以覆盖多个图块或是到处的移动。在最新版本中,你还可以其他的类型,如椭圆,多边形,折现等。

    你只需要选择一小块,作为玩家开始的地方,所以在地图上选中一个区域并点击图块,矩形框的大小并不重要,因为我们只用x,y坐标。注意,如果你懒而使用样本地图,这将为你完成。

    然后,右键刚刚添加的这个灰色的对象,选择对象属性...,给它一个名字SpawnPoint,然后点击 在以前的cocos2d-x版本中,你可以设置对象的类型,但是由于会带来问题所以被移除了。所以把类型设为空白。我们创建了一个

    CCDictionary,能够访问这个对象的很多属性,包括x,y坐标。

    保存这个地图,返回Xcode,打开HelloWorldScene.h,添加下面到私有变量声明那里:

    CCSprite *_player;

    接下来,打开HelloWorldScene.cpp,添加下面代码到init()中,在this->addChild(_tileMap)的后面。

    CCTMXObjectGroup*objectGroup =_tileMap->objectGroupNamed("Objects");

    if(!objectGroup) {

    CCLog("tile map has no objects object layer");

    return false;

    }

    CCDictionary*spawnPoint = objectGroup->objectNamed("SpawnPoint");

    intx = ((CCString)*spawnPoint->valueForKey("x")).intValue();

    inty = ((CCString)*spawnPoint->valueForKey("y")).intValue();

    _player=newCCSprite();

    _player->initWithFile("Player.png");

    _player->setPosition(ccp(x,y));

    this->addChild(_player);

    this->setViewPointCenter(_player->getPosition());

    在最后面一行将会有个错误,别担心我们呆会再解决它。 我们停下来解释一下关于这个对象层和对象组。首先注意你得到对象层是通过CCTMXTiledMap对象上的objectGroupNamed方法

    (而不是layerNamed).它返回一个特殊的CCTMXObjectGroup对象。

    然后objectGroup调用objectNamed方法得到一个包含有这个对象一些有用信息的字典,有x,y,width,height.本教程的重点关心的是 玩家精灵的位置。

    在代码片最后,你把player的位置作为这个视图的位置。所以现在添加下面代码到HelloWorldScene.h中:

    void setViewPointCenter(CCPoint position);

    然后在HelloWorldScene.cpp中添加实现方法:

    voidHelloWorld::setViewPointCenter(cocos2d::CCPointposition)

    {

    CCSizewinSize =CCDirector::sharedDirector()->getWinSize();\

    //防止玩家超出边界

    intx =MAX(position.x,winSize.width/2);

    inty =MAX(position.y,winSize.height/2);

    x =MIN(x,(_tileMap->getMapSize().width*_tileMap->getTileSize().width) - winSize.width/2);

    y =MIN(y,(_tileMap->getMapSize().height*_tileMap->getTileSize().height) - winSize.height/2);

    CCPointactualPosition =ccp(x,y);

    CCPointcenterOfView =ccp(winSize.width/2,winSize.height/2);

    CCPointviewPoint =ccpSub(centerOfView,actualPosition);

    this->setPosition(viewPoint);

    ok,来解释下这段代码,想象一下这功能是设置一个照相机的中心,它允许用户在地图上通过任意的 让屏幕超过地图的边界(它只是空白的)。

    例如,看这个图解:

    你看,是否相机的中心不到WinSize.width/2,Winsize.height/2,视图的部分就超出了屏幕。

    同样的,重要的是要检查好上限边界,这正是setViewPointCenter做的。

    这个完成了视图的中心位置减去实际的位置,然后把结果设为HelloWorld图层的位置。

    唷,做了这么多,是时候看它动起来了。

    运行程序,如果没错的话,你将看到一个忍者在屏幕上。

    Making the Ninja Move

    这是个好的开始,但是你的忍者只是站在那里,不像个真忍者。

    你将让你的忍者在用户轻点的方向上做简单的移动,添加下面的代码到HelloWorldScene.hpubic区:

    voidregisterWithTouchDispatcher();

    voidsetPlayerPosition(CCPointposition);

    boolccTouchBegan(CCTouch*touch,CCEvent*event);

    voidccTouchEnded(CCTouch*touch,CCEvent*event);

    然后打开HelloWorldScene.cpp添加这句到init()中,在return前: this->setTouchEnabled(true);

    这设置了让图层能够触摸,所以注意touch事件,再添加下面代码:

    voidHelloWorld::registerWithTouchDispatcher()

    CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this,0,true);

    }


    boolHelloWorld::ccTouchBegan(cocos2d::CCTouch*touch,cocos2d::CCEvent*event)

    {

    returntrue;

    voidHelloWorld::setPlayerPosition(cocos2d::CCPointposition)

    {

    _player->setPosition(position);

    }

    voidHelloWorld::ccTouchEnded(cocos2d::CCTouch*touch,51); font-family:Arial; font-size:14px; line-height:26px"> CCPointtouchLocation = touch->getLocationInView();

    touchLocation =CCDirector::sharedDirector()->convertToGL(touchLocation);

    touchLocation =this->convertToNodeSpace(touchLocation);

    CCPointplayerPos =_player->getPosition();

    CCPointdiff =ccpSub(touchLocation,playerPos);

    if(abs(diff.x) >abs(diff.y) ) {

    if(diff.x>0) {

    playerPos.x+=_tileMap->getTileSize().width;

    }else{

    playerPos.x-=_tileMap->getTileSize().width;

    }

    }else{

    if(diff.y>0) {

    playerPos.y+=_tileMap->getTileSize().height;

    playerPos.y-=_tileMap->getTileSize().height;

    }

    // safety check on the bounds of the map

    if(playerPos.x<= (_tileMap->getMapSize().width*_tileMap->getTileSize().width) &&

    playerPos.y<= (_tileMap->getMapSize().height*_tileMap->getTileSize().height) &&

    playerPos.y>=0&&

    playerPos.x>=0)

    {

    this->setPlayerPosition(playerPos);

    this->setViewPointCenter(_player->getPosition());

    这里,你覆盖了registerWithTouchDispatcher方法,注册自己来处理目标触摸事件。这将导致ccTouchBegan/ccTouchEnded方法被调用。(单触摸的情况下) 而不是ccTouchesBegan/ccTouchesEnded方法被调用(多触摸的情况下)。

    你肯定想知道单触摸和多触摸之间的不同,在这种情况下用这两种都没关系。但是,如果你之前没见过这个方法,我想介绍给大家,因为它有明显的两个优点:

  • 你不需要处理NSSets,调度器做了分离它们的工作。每次只有一个UITouch调用。
  • 你可以“要求”一个UITouchccTouchBegan返回true,要求它们更新只发送给代理。所以,如果你得到一个move/ended/cancelled更新确定是你的触摸,当多点触摸的时候这会检查释放。
  • 接下来,有一大段是讲坐标的,英语水平实在是渣,就不翻译了。

    编译-》运行程序,现在忍者就可以在屏幕上移动了。

    这是第一部分的教程。源码在这里

    版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

    相关推荐


        本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
    Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
    第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
        Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
    1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
       Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
     下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
    分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
    1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
    原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
    2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
    原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
    环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
    1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
    原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
    原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
    为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
    Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
    需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
    v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是