Help me, Parallax Node and Box2D

Hello guys.
I managed to make collision from tileMap thanks to help of our fellow in forum.
Tilemap body Creator by @egordm

I set up gravity and its world.

b2Vec2 gravity;
gravity.Set(0.0f, -10.0f);
world = new b2World(gravity);

I used parallax Node.

//added Tile Map as TMXTileMap object
map = TMXTiledMap::create("test.tmx");
map->setAnchorPoint(Point::ZERO);
map->setPosition(0, 0);
voidNode = ParallaxNode::create();
voidNode->addChild(map, 1, Vec2(0.5f, 0.5f), Vec2(0, 0));

I called it in the function made by @egordm.

TiledBodyCreator::initCollisionMap(map, world, “Coll”);

Update it:

int velocityIterations = 8;
int positionIterations = 10;
world->Step(dt, velocityIterations, positionIterations);
for (b2Body *body = world->GetBodyList(); body; body = body->GetNext())
{
    if (body->GetUserData() != NULL)
    {
        Point pos = Vec2(body->GetPosition().x * (PTM_RATIO), body->GetPosition().y * (PTM_RATIO));
        hero->setPosition(pos);
    }
}

But honestly, why the collision made within Tile Map is not moving along as Tile Map move?


The green box won’t move to the left as it should be.

Hey gOzaru,

I am glad TiledBodyCreator is useful to you. its been a long time since I had my hands on Cocos2d-x but if I understand you correctly, you create a body for your tilemap, add it to world and add the tilemap to a parallax node which makes the tilemap scroll but the problem is, the body of the tilemap isn’t going along with it. If that’s the case i think I know what’s the problem.

I think because the ParallaxNode moves the children within itself but as far as I can remember TiledBodyCreator does not bind them onto the map. So parallaxnode only creates an illusion that the tile map is moving but the positions all stay the same and so does the world. I can remember in my games I created a tilemap along with its body and let the camera move forward.

It really depends on what game you are making if its a platformer it may be better to move the camera, if it’s a side scroll parallax runner game it would be better mayby just spawn in the obstacles which move with a velocity towards the player or create multiple instances of the TilemapBody and move them with the same speed as TiledMap and after they quit the view just recycle them.

Sorry I can’t really provide any code examples and I hope this might have helped you a bit.

Thank you very much for helping me out.
It’s a platformer mobile game.
No problem.
The important thing I know what my problem is from your point of view.
I think I must use camera.
Thank you for your suggestion.
I’d give you a credit in my game.

No problem, I am glad it helped you.
There is no need to give me a credit for your game, but I would love to see it when it’s done :slight_smile:

@gOzaru if you think of a parallax node as it’s own object like a sprite, you can move it around like a sprite, except everything you add as a child to it (addChild) will follow it but in a specific ratio that you set. So if you set a parallax ratio of
Vec2(0.5f, 0.5f)
for a child “childA” it will follow the parallax node at half it’s movement.

Parallax node pos = (100, 100)
ChildA pos = (50, 50)

That’s the only reason you should need a parallax node, to move things in a ratio compared to other things. If you want to move the view around over a map/background then you need a camera yes, but you can use a camera in conjuction with parallax node.

uhm…
So basically I have to move the objects’ collision (child) along with parallax node.
And the value of (0.5f, 0.5f) is actually the scale.
I see now.

It seems difficult to me.
how can I move the objects inside the tile map?
I looked on cpp-tests, no sample about it.
Could you help me about this?

@gOzaru you have to be more specific exactly what you’re trying to move?

Also you don’t move any (childs) of a parallax node, you only move the parallax node and the parallax node will handle the movement of the child nodes.

The value of float parallaxRatio when you add a child to a parallax node is the scale. (0.5f, 0.5f) is just an example. It could be (2.0f, 2.0f) it could be (14.5f, 6.12f). Do you understand?

I am trying to move the objects group inside tilemap (contain collision).
Maybe I’d try to move the layer instead.
I’d find out how.

@gOzaru with my parallax node I create a few layers add them to the parallax node. Like a foreground layer, background layer. etc.
Then I add all the child nodes for the background to the background layer and so on. It would be helpful to see a screenshot of your game so I can see what you’re trying to achieve?

This is my preview of background.
I have no foreground layer.
Just one picture of tilemap and objects group named: Coll.

This is the function I used to move the dynamic body.

void MainMenu::right(Ref *pSender)
{
b2Vec2 force = b2Vec2(15, 0);
bodyHero->ApplyLinearImpulse(force, bodyHero->GetPosition(), true);
map->runAction(MoveBy::create(0.5, Vec2(-15, 0)));
}

void MainMenu::left(Ref *pSender)
{
if (map->getPosition() < Vec2(15,0))
{
this->runAction(MoveBy::create(0.0, Vec2(0, 0)));
}
else if(map->getPosition() > Vec2(15,0))
{
b2Vec2 force = b2Vec2(15, 0);
bodyHero->ApplyLinearImpulse(force, bodyHero->GetPosition(), true);
map->runAction(MoveBy::create(0.5, Vec2(15, 0)));
}
}

@gOzaru So you’re moving your map left as you move your character right? First of all I can see a very common mistake here. You’re moving your map using pixel coordinates 15 pixels, which is fine. Because Cocos2D uses pixel coordinates. However Box2D does not use pixels it uses meters. It’s not an easy concept to grasp.

Anything you do with Box2D has to be converted in to Box2D coordinates using a pixel to meter ratio. I’d suggest 30 as it works quite nicely. So when you create a body such as bodyHero. When you set the shape for it you have to divide the size you want it to be in pixels by the ptmRatio (30.0f). So if the hero has a sprite of 100x300px. When you create the heroBody you want it to be shape.setAsBox((100/2) / ptmRatio, 300/2 / ptmRatio).

Same with the forces, when you apply a force you need to divide it by the ptmRatio, b2Vec2 force = (15/ptmRatio,0);

I don’t know much about Tiled, are you creating the box2D stuff in your cocos code or loading them in from a Tiled project?

yep.
you are right. I forgot about that.
heroBody must use Box2D unit.
I see. The force has to be divided too.
I make the Box2D static collision from tiled map objects then process it using @egordm function on the link above.

Actually that is not a problem.
I still don’t know how to move the layer.
So I just need to add the tile map & hero into layer.

You only need to move the layer if you don’t have a camera, why don’t you add a camera and then move the hero and have the camera follow the hero position?

Ok, I’d try to use camera.
Hope it works…
Thank you.