Cocos2d-x之瓦片地图 Tiled

Cocos2d-x之瓦片地图 Tiled

首先使用 瓦片地图编辑器(Tiled) 制作一个瓦片地图,并将其放入工程的Resources目录下

 

功能实现:

将地图显示在窗体中

将精灵添加到地图定义的对象层中的一个对象上

移动精灵,使其可以和碰撞图层上的精灵发生碰撞

碰撞后碰撞图层上的精灵消失,label字体改变

代码部分:

HelloWorldScene.h

 1 #ifndef __HELLOWORLD_SCENE_H__
 2 #define __HELLOWORLD_SCENE_H__
 3 
 4 #include "cocos2d.h"
 5 
 6 class HelloWorld : public cocos2d::Layer
 7 {
 8 public:
 9     // there's no 'id' in cpp, so we recommend returning the class instance pointer
10     static cocos2d::Scene* createScene();
11 
12     // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
13     virtual bool init();  
14     
15     // a selector callback
16     void menuCloseCallback(cocos2d::Ref* pSender);
17     
18     // implement the "static create()" method manually
19     CREATE_FUNC(HelloWorld);
20 
21     virtual bool onTouchBegan(cocos2d::Touch *touch, cocos2d::Event *event);
22 
23     // 坐标转换,opgl 坐标转换为 Tiled 地图坐标(每块小地图的坐标)
24     cocos2d::Vec2 tileCoordForPosition(cocos2d::Vec2 position);
25 
26     void judgeCollide();    // 判断碰撞
27 
28 private:
29     cocos2d::Size visibleSize;
30     cocos2d::Sprite *sprite;
31     cocos2d::TMXTiledMap *map;
32     cocos2d::LabelTTF *label;
33 };
34 
35 #endif // __HELLOWORLD_SCENE_H__

 

 

 

HelloWorldScene.cpp

 

  1 #include "HelloWorldScene.h"
  2 
  3 USING_NS_CC;
  4 
  5 Scene* HelloWorld::createScene()
  6 {
  7     // 'scene' is an autorelease object
  8     auto scene = Scene::create();
  9     
 10     // 'layer' is an autorelease object
 11     auto layer = HelloWorld::create();
 12 
 13     // add layer as a child to scene
 14     scene->addChild(layer);
 15 
 16     // return the scene
 17     return scene;
 18 }
 19 
 20 // on "init" you need to initialize your instance
 21 bool HelloWorld::init()
 22 {
 23     //////////////////////////////
 24     // 1. super init first
 25     if ( !Layer::init() )
 26     {
 27         return false;
 28     }
 29     
 30     visibleSize = Director::getInstance()->getVisibleSize();
 31     Vec2 origin = Director::getInstance()->getVisibleOrigin();
 32 
 33 
 34 
 35     /////////////////////////////
 36     // 2. add a menu item with "X" image, which is clicked to quit the program
 37     //    you may modify it.
 38 
 39     // add a "close" icon to exit the progress. it's an autorelease object
 40     auto closeItem = MenuItemImage::create(
 41                                            "CloseNormal.png",
 42                                            "CloseSelected.png",
 43                                            CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
 44     
 45     closeItem->setPosition(Vec2(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
 46                                 origin.y + closeItem->getContentSize().height/2));
 47 
 48     // create menu, it's an autorelease object
 49     auto menu = Menu::create(closeItem, NULL);
 50     menu->setPosition(Vec2::ZERO);
 51     this->addChild(menu, 1);
 52 
 53     /////////////////////////////
 54     // 3. add your codes below...
 55 
 56     // add a label shows "Hello World"
 57     // create and initialize a label
 58     
 59     label = LabelTTF::create("Hello World", "Arial", 24);
 60     
 61     // position the label on the center of the screen
 62     label->setPosition(Vec2(origin.x + visibleSize.width/2,
 63                             origin.y + visibleSize.height - label->getContentSize().height));
 64 
 65     // add the label as a child to this layer
 66     this->addChild(label, 1);
 67 
 68 
 69 
 70     ///////////////     瓦片地图 Tiled     ///////////////
 71 
 72 
 73     map = TMXTiledMap::create("map.tmx");
 74     addChild(map);    // 默认添加的位置是左下角
 75 
 76     // 获取 objLayer 对象层
 77     TMXObjectGroup *objGroup = map->objectGroupNamed("objLayer");
 78     // 获取 hero 对象
 79     auto vm = objGroup->objectNamed("hero");
 80 
 81     // 获取 hero 对象的 x,y 坐标
 82     float x = vm.at("x").asFloat();
 83     float y = vm.at("y").asFloat();
 84 
 85     //// 获取 hero 的 id 属性值
 86     //auto id = vm.at("id").asInt();
 87     //log("  sprite id is   %d  ", id);
 88 
 89     // 获取 hero 的名字
 90     String name = vm.at("name").asString();
 91     log(" name %s ", name);
 92 
 93     // 在 hero 的位置处添加精灵
 94     sprite = Sprite::create("button.png");
 95     sprite->setPosition(Vec2(x, y));
 96     // 因为地图的锚点是左下角,所以设置精灵的锚点也为左下角,这样位置才能对应上
 97     sprite->setAnchorPoint(Vec2::ZERO);
 98     addChild(sprite);
 99 
100     // 设置可以获取触摸
101     setTouchEnabled(true);
102     setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
103 
104     return true;
105 }
106 
107 bool HelloWorld::onTouchBegan(Touch *touch, Event *event){
108 
109     Vec2 pos = touch->getLocation();
110     ActionInstant *func = CallFunc::create(this, callfunc_selector(HelloWorld::judgeCollide));
111     sprite->runAction(Sequence::create(MoveTo::create(1, pos), func, nullptr));
112     return true;
113 }
114 
115 
116 Vec2 HelloWorld::tileCoordForPosition(Vec2 position){
117 
118     // 用 x 坐标(opgl中的)除以 每个小地图的宽度,就可以得出 这个点 的 x 轴坐标(瓦片地图中的)
119     int x = position.x / map->getTileSize().width;
120     // 使用 瓦片地图的高度 * 瓦片地图每个的高度 - 点的 y 坐标) / 每个瓦片地图的高
121     int y = (map->getMapSize().height * map->getTileSize().height - position.y) / map->getTileSize().height;
122 
123     return Vec2(x, y);
124 }
125 
126 void HelloWorld::judgeCollide(){
127 
128     TMXLayer *collisionLayer = map->layerNamed("collisionLayer");    // 获取瓦片地图的碰撞层
129     Vec2 tiledPos = tileCoordForPosition(sprite->getPosition());    // 将精灵坐标转换为瓦片地图的坐标
130 
131     if (collisionLayer->tileGIDAt(tiledPos)){
132         collisionLayer->removeTileAt(tiledPos);
133         log("collisionLayer->tileGIDAt(tiledPos)  =  %d ", collisionLayer->tileGIDAt(tiledPos));
134         label->setString("you eat me");
135     }
136     else{
137         label->setString("HelloWorld ~~~ ");
138     }
139 
140 }
141 
142 
143 void HelloWorld::menuCloseCallback(Ref* pSender)
144 {
145 #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
146     MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
147     return;
148 #endif
149 
150     Director::getInstance()->end();
151 
152 #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
153     exit(0);
154 #endif
155 }

 

 

 

posted @ 2015-06-07 10:08  silent-bobo  阅读(1049)  评论(0编辑  收藏  举报