Cocos2d-x之瓦片地图 Tiled

时间:2023-02-09 14:57:43

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 }

 

Cocos2d-x之瓦片地图 Tiled

 

Cocos2d-x之瓦片地图 Tiled