Player can not move throught tilemap ? help

how my character cannot move through “notmove” name layer tiles
This is my code and tiledmap.

Player.h

    #ifndef _PLAYER_H_
    #define _PLAYER_H_
    #include "cocos2d.h"
    using namespace cocos2d;
    class Player : public Sprite
    {
    public:
    	Player(Layer *layer);
    	int direction;
    	bool moving;
    	void _idle();
    	void update();
    	void move();
    private:
    	Sprite *player;
    };
    #endif // _PLAYER_H_

player.cpp

#include "player.h"
#include <stdio.h>
#include <string>

using namespace std;
USING_NS_CC;

Player::Player(Layer *layer)
{
	Vec2 origin = Director::getInstance()->getVisibleOrigin();
	auto visibleSize = Director::getInstance()->getVisibleSize();
	player = Sprite::create("0.png");
	player->setScale(0.3);
	player->setPosition(Vec2(500, 500));
	
	layer->addChild(player, 100);
}
void Player::update()
{
	if (moving = true)
	{
		if (direction == 0)
		{
			player->setScaleX(-0.3);
			player->setPositionX(player->getPositionX() - 5);
		}
		else if (direction == 1)
		{
			player->setScaleX(0.3);
			player->setPositionX(player->getPositionX() + 5);
		}
		else if (direction == 2)
		{
			player->setPositionY(player->getPositionY() + 5);
		}
		else if (direction == 3)
		{
			player->setPositionY(player->getPositionY() - 5);
		}
		else if (direction = -1)
		{
			moving = false;
		}
	}	
}
void Player::_idle()
{
	direction = -1;
}

Helloworld.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
#include "player.h"
using namespace cocos2d;

class HelloWorld : public cocos2d::Layer
{
public:
	static cocos2d::Scene* createScene();
	void update(float dt);
	virtual bool init();
	void onkeypress(EventKeyboard::KeyCode keycode, Event *event);
	void onkeyrelease(EventKeyboard::KeyCode keycode, Event *event);
	Player *player;
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

helloworld.cpp

#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"


USING_NS_CC;
using namespace std;

Scene* HelloWorld::createScene()
{
    auto scene = Scene::create();
    
    auto layer = HelloWorld::create();
    
    scene->addChild(layer);

    return scene;
}


bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }
    
    auto visibleSize = Director::getInstance()->getVisibleSize();
    Vec2 origin = Director::getInstance()->getVisibleOrigin();

	player = new Player(this);

	auto map = TMXTiledMap::create("map.tmx");
	addChild(map,99);

	auto listener = EventListenerKeyboard::create();
	listener->onKeyPressed = CC_CALLBACK_2(HelloWorld::onkeypress, this);
	listener->onKeyReleased = CC_CALLBACK_2(HelloWorld::onkeyrelease, this);
	_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
	scheduleUpdate();
    return true;
}
void HelloWorld::update(float dt)
{
	player->update();
}
void HelloWorld::onkeypress(EventKeyboard::KeyCode keycode, Event *event)
{
	CCLOG("press key %d press ", keycode);

	if (keycode == EventKeyboard::KeyCode::KEY_D)
	{
		player->direction = 1;
	}
	else if (keycode == EventKeyboard::KeyCode::KEY_A)
	{
		player->direction = 0;
	}
	else if (keycode == EventKeyboard::KeyCode::KEY_W)
	{
		player->direction = 2;
	}
	else if (keycode == EventKeyboard::KeyCode::KEY_S)
	{
		player->direction = 3;
	}
}
void HelloWorld::onkeyrelease(EventKeyboard::KeyCode keycode, Event *event)
{
	player->_idle();
}

Did you read the only tiled maps tutorial we have had in years? :smiley:
Part 1: https://www.raywenderlich.com/2684-cocos2d-x-tile-map-tutorial-part-1
Part 2: https://www.raywenderlich.com/2683-cocos2d-x-tile-map-tutorial-part-2

To detect collisions (without using physics engines), the tutorial uses the method setPlayerPosition (in Part 2) for move the player if it can move…
If the player can’t move, the method doesn’t move the player.

2 Likes

The tutorial is very old.
Here you’ve a tutorial adapted to cocos 3.x (It is also old, but not so much :smiley: )

And here you’ve cpp-examples:

However, I also have many doubts.
For example, in my case, getTileGIDAt always returns 0 and i don’t understand why. I think it’s because tileCoordForPosition is returning wrong tile positions.

Also, getProperty not works for me.
For example, i want to get this property: tileMap->getProperty("Width");
And i can’t. cc @drelaptop

Here i found how to fix the method tileCoordForPosition for cocos2d-x

And now the detection of collisions (without physics engine) works.
Tip: Be sure to add custom properties to the tile, otherwise, this line will give error:
tileMap->getPropertiesForGID(tileGid).asValueMap();

EDIT:
As i could test…
getTileGIDAt returns 0 when the tile coord is out of the layer.
Then, you could do something like this:

TMXLayer *layerNotMove = tileMap->getLayer("notmove");
Point tileCoord = tileCoordForPosition(sprite->getPosition());
auto tileGid = layerNotMove->getTileGIDAt(tileCoord);

if(tileGid == 0)
{
   log("move");
}
else
{
  log("notMove");
}

In this way you do not need to set custom properties.
Hope it helps :wink:

1 Like

Is there any way for 2 box2d to not move through each other? I added box2d to the tiledmap object.

Here you’ve a class for manage tiled maps with box2d:

1 Like
TMXObjectGroup *collision_rectangles_object_layer = _map->getObjectGroup("ground");
	ValueVector &rectangles_array = collision_rectangles_object_layer->getObjects();
	for (cocos2d::Value &rectangle_box : rectangles_array)
	{
		cocos2d::ValueMap rectangle_box_properties = rectangle_box.asValueMap();

		Node* node = Node::create();

		PhysicsBody *box = PhysicsBody::createEdgeBox(Size(rectangle_box_properties["width"].asInt(), rectangle_box_properties["height"].asInt()), PhysicsMaterial(0.f, 0.f, 0.f));
		node->setPhysicsBody(box);
		
		box->setGroup(-1);
		box->setContactTestBitmask(2);
		box->setContactTestBitmask(true);

		node->setPosition(Vec2(rectangle_box_properties["x"].asInt() + rectangle_box_properties["width"].asInt() / 2, rectangle_box_properties["y"].asInt() + rectangle_box_properties["height"].asInt() / 2));

		box->setGravityEnable(false);
		box->setDynamic(false);

		this->addChild(node, 20);
	}

This is how I use it

@tranthor I think the TileMap documentation needs some updating. Can I use some info in your posts to build out the docs?

Of course, no problem.
If I can help in something else, just tell me :slight_smile:

@slackmoehrle despite of you will update the documentation, there are any plans for update tiled maps in cocos2d-x? For example, i’m using Tiled tool (last version 1.2.1) for design the map.
Everything works fine but I always see this msg in the console:
cocos2d: TMXFormat: Unsupported TMX version: 1.2

As @mars3142 said:

So, it sounds like “Tiled” is being updated and cocos not. There are any plans for update tiled map classes in cocos soon? To include the latest features that “Tiled” has (and fix bugs, why not).
Thanks :smiley:

Also, i think cocos team should evaluate how to manage big tiled maps (IMHO).
At the moment, the map limit is 128x128. If i want to create a big map (example 512x512), i should create different tmx files and “concatenate” them (this is annoying for very big maps).

It would be great if all this work is managed by the framework.
For example, i would like to create 1024x1024 map in “Tiled” and the framework analyze how to create and load it. For example, create and remove new Tiles / SpriteBatchNode depending on the current visibility of the screen, etc. cc @stevetranby @drelaptop @zhangxm

I repeat, it’s only my humble opinion :slight_smile:

EDIT:
I read that this topic has been discussed:

But i’m using the last version of cocos2d-x and i continue with the problem. The max size is 128x128 using cocos2d::TMXTiledMap.

@tranthor may be you can try fast tilemap.

What exactly is the name of the class? cocos2d::experimental::TMXTiledMap ?
If yes, why “experimental”? It sounds like it’s in beta. Will the final version be released soon?

What advantages does it have? I’m sorry but I don’t find documentation about this.
If I want to use a stable version, should i use cocos2d::TMXTiledMap instead of cocos2d::experimental::TMXTiledMap ?

It is been named experimental for a long time. And i don’t remember why it has the name, may be i have to ask Ricardo or Harisson for it. It is designed to have big map, only draw visible map and have int type for index which can hold more indices.

You can try it first. As i know it now has the same feature as normal tilemap, may be it doesn’t implement more features as wanted, so named experimental.

Currently, i am busy with metal support, so i can not put more energy on it right now. Sorry about it.

1 Like

I think I remember that we used experimental until it was tested on all platforms we support?

We should probably write about this. I think there is an example in TileMapTest2.cpp

Yep, i agree with it. Could you please add an issue in doc repo?

I have it in an issue