[Tutorial Series] Use the Cocos2d-x-3.0 game engine. Write a Tile Map Game.(part02)

Previous: http://www.cocos2d-x.org/forums/6/topics/50789

  1. Upload the map
        Like the Object-C language, The C++ has the head files and the implementation files (I learn Object-C first.). We now register the files which will be used in the head file.
    Open the ‘HelloWorldScene.h’ , add some member variables:
class HelloWorld : public cocos2d::Layer
{
private:
	cocos2d::TMXTiledMap *_tileMap;
	cocos2d::TMXLayer *_background;
};

    Then open the ‘HelloWorldScene.cpp’, make some changes. (You can delete the old code in ’bool HelloWorld::init()’.)

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    std::string file = "01.tmx";
auto str = String::createWithContentsOfFile (FileUtils::getInstance()->fullPathForFilename(file.c_str()).c_str());
    _tileMap = TMXTiledMap::createWithXML(str->getCString(),"");
    _background = _tileMap->layerNamed("Background");

    addChild(_tileMap, -1);
    
return true;
}

    Here, we have called the class of the TMXTileLayer to upload our tile map. Now run the VS2012 debug function. We will get the map, or more preciously, part of the map. ( Because the map size which we have created is too big and the window size is not large enough to hold the whole scene. The default setting only shows the lower left corner of the tile map. ) So if there is no problem happens when VS is debugging, everything is OK. And then, we will create the sprite, our character, and let the window set the view on the character. (It will solve the problem above, or you can build your map on the lower left corner.)

Image Title
Part of the map

  1. Character and the View
        Right-click on the ‘Layer Section’ of the Tiled Map editor. Select the ‘Object layer’ to create a new one. Then choose the ‘rectangle’ button. And draw a rectangle on the map where you want your character shows up. Right-click on this rectangle and setting some properties for it. (Only change the name.)
    Image Title
    Character position & Properties
        Return to the VS. In the ‘HelloWorldScene.h’, we now do some coding:
class HelloWorld : public cocos2d::Layer
{
private:
	cocos2d::Sprite *_player;
};

    In the ‘HelloWorldScene.cpp’:

bool HelloWorld::init()
{
	TMXObjectGroup *objects = _tileMap->getObjectGroup("Object-Player");
	CCASSERT(NULL != objects, "'Object-Player' object group not found");
	
	auto playerShowUpPoint = objects->getObject("PlayerShowUpPoint");
	CCASSERT(!playerShowUpPoint.empty(), "PlayerShowUpPoint object not found");

	int x = playerShowUpPoint["x"].asInt();
	int y = playerShowUpPoint["y"].asInt();

	_player = Sprite::create("029.png");
	_player->setPosition(x + _tileMap->getTileSize().width / 2, y + _tileMap->getTileSize().height / 2);
	_player->setScale(0.5);

	addChild(_player);
	setViewPointCenter(_player->getPosition());
}

    We add the judgment statement to decide whether the object has been uploaded. By using the ‘getObjectGroup’ function, we get the object layer. And we get object’s position from the map and set the position coordinate to our sprite. Next, we add a new function, ‘setViewPointCenter’.
In the ‘HelloWorldScene.h’:

class HelloWorld : public cocos2d::Layer
{
public:
	void setViewPointCenter(cocos2d::Point position);
}

    In the ‘HelloWorldScene.cpp’:

void HelloWorld::setViewPointCenter(Point position) {
    auto winSize = Director::getInstance()->getWinSize();

    int x = MAX(position.x, winSize.width / 2);
    int y = MAX(position.y, winSize.height / 2);
    x = MIN(x, (_tileMap->getMapSize().width * this->_tileMap->getTileSize().width) - winSize.width / 2);
    y = MIN(y, (_tileMap->getMapSize().height * _tileMap->getTileSize().height) - winSize.height / 2);
    auto actualPosition = Point(x, y);

    auto centerOfView = Point(winSize.width / 2, winSize.height / 2);
    auto viewPoint = centerOfView - actualPosition;
    this->setPosition(viewPoint);
}

Image Title
View correct & Character show up
    Now, the view has been corrected, and the character has been showed up. But the character can’t move. And the screen also freezes.

  1. The Movement:
bool HelloWorld::init(){
......
	auto listener = EventListenerTouchOneByOne::create();
	listener->onTouchBegan = [&](Touch *touch, Event *unused_event)->bool {return true;};
	listener->onTouchEnded = CC_CALLBACK_2(HelloWorld::onTouchEnded, this);
	this->_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
......
}

And:

void HelloWorld::onTouchEnded(Touch *touch, Event *unused_event)
{
	auto actionTo1 = RotateTo::create(0, 0, 180);
	auto actionTo2 = RotateTo::create(0, 0, 0);
	auto touchLocation = touch->getLocation();
	
	touchLocation = this->convertToNodeSpace(touchLocation);

	auto playerPos = _player->getPosition();
	auto diff = touchLocation - playerPos;
	if (abs(diff.x) > abs(diff.y)) {
		if (diff.x > 0) {
			playerPos.x += _tileMap->getTileSize().width / 2;
			_player->runAction(actionTo2);
		}
		else {
			playerPos.x -= _tileMap->getTileSize().width / 2;
			_player->runAction(actionTo1);
		}
	}
	else {
	 if (diff.y > 0) {
	    playerPos.y += _tileMap->getTileSize().height / 2;
	 }
		else {
		 playerPos.y -= _tileMap->getTileSize().height / 2;
		}
 }

	if (playerPos.x <= (_tileMap->getMapSize().width * _tileMap->getMapSize().width) &&
	 playerPos.y <= (_tileMap->getMapSize().height * _tileMap->getMapSize().height) &&
	 playerPos.y >= 0 &&
	 playerPos.x >= 0)
	{
	 this->setPlayerPosition(playerPos);
		
 }

	this->setViewPointCenter(_player->getPosition());
}
void HelloWorld::setPlayerPosition(Point position)
{
    _player->setPosition(position);
}

And don’t forget the ‘HelloWorldScene.h’:

class HelloWorld : public cocos2d::Layer
{
public:
void onTouchEnded(cocos2d::Touch *touch, cocos2d::Event *unused_event);
void setViewPointCenter(cocos2d::Point position);
void setPlayerPosition(cocos2d::Point position);
}

Image Title
Sprite & View move

To be continue…

Next: http://www.cocos2d-x.org/forums/6/topics/51141


00.png (75.5 KB)


01.png (104.4 KB)


02.png (530.2 KB)


04.png (243.2 KB)

2 Likes

Good thank u for u tutorials

TMXObjectGroup *objects = _tileMap->getObjectGroup(“Object-Player”);

It did not work on Android.
plz, help

in androidMenifest.xml

i add it
android:allowBackup=“true”
android:vmSafeMode=“true”
android:allowClearUserData=“true”
android:hardwareAccelerated=“true”

and works.

@pitilesslove Wow~my appreciation. I’m just start wondering whether someone will notice my tutorials. My thanks. By the way, the resources I used have already been released in the first tutorial in 4 floor.(http://www.cocos2d-x.org/forums/6/topics/50789)

Thanks for the tutorials, they’ve been really helpful.

thanks and done everything runs fine :;ok

Thanks! Very helpful! :smiley:

I am on step 1: Upload the map. But when I debug on my device I don’t see a map instead it force closes. I have only added the code changes to the helloWorld files. I am running android on Eclipse if that helps

Thanks

@thejet238 The android system probably is not the problem. My colleagues already pack the file into the apk. And it works perfectly. As for your problem, it seems strange. Is it just simply close the window that supposed to show the map without any warning?

how to access custom properties of objects?

[edit]: Oh saw that while accessing the enemy types thanks: :slight_smile: . Still looking how to do it in 2.2.x tho … :slight_smile:

i cant follow this in v3.3 . it says my picture newyorktown.png is missing when it’s right there in my resources folder.

Hi Suigintou,

Great tutorial, thanks.
I was trying to create my own map and used in my sample app for windows phone + visual studio.
Most tmx files provided by Cocos2d work (some did not work and show same error as in the following links). If I create my own map it never work with visual studio.
I get the following problem, can you point me where it could be and how to solve it?

@siddharthshekar and other guys! please help

Why are you double multiplying it? And at other places also you are doing this!
It should be simply

 _tileMap-&gt;getMapSize().width

I mean, since it is just the normal position comparison so why are you comparing position of the player with the square of the dimensions?

Thanxx :smile:

we are not doublemultiplying anything. Here the map size is not the size in pixels. It is the numbers of tiles there in the horizontal or vertical direction. Then tile size is the size of each tile you have specified like 32x32, 64x64 etc. So to get the total size of the map in pixels you multiple no of tiles by the tilwidth and height. so for example if you have a 20 x 12 map size (no of tiles) and each tile is 64 x 64. Then the size of the map pixels is width = 20 x 64 and height 12 x 64 => 1280 x 768.

mapSize is the no of tile count and tileSize is the size of each tile in pixels. Hope this helps.

1 Like

I have been searching for this kind of tutorial. I profoundly thank you so so much for making this tutorial. Thxxxxx

I find this tutorial to be hugely helpful as its worded and done in such a way i easily understand everything that is happening with it. that being said i am having a huge issue that i cannot for the life of me figure out. everything works fine accept for movement, for the first couple (or touches) movement appears fine, but each touch makes the character jump further and further than the last, after about a dozen or so touches the character is jumping end-to-end on then map and beyond causing the program to freeze. Any idea what might be happening? code was a direct copy/paste after understanding how it works…
Thank you…