snorge
snorge

Reputation: 134

SpriteKit physics: How to make a player sprite follow the (sloped) ground

I am creating a tilemap platform game in SpriteKit. I assigned collision paths to the physics body of all ground tiles and made them non-dynamic. To the player I assigned two collision polygons: a circle on the bottom and a rectangle on the top.

The player sprite has a fixed position on screen, while the level is scrolling from right to left. Now, as long as the player sprite is on flat ground, the collisions work perfectly and the player is walking on the ground. However, I also have some sloped terrain tiles that I want the player to follow (e.g. walking uphill). But when the player reaches a sloped tile, he simply bounces off of it, being unable to "climb" it.

screenshot

Similarly, when I drop the player from above on a sloped tile, he slides down the "hill", instead of remaining in position.

I have both restitution and friction set to 0.

So how can I make the player sprite follow the ground regardless of its shape and how can I make the player stay on a sloped tile instead of sliding down?

I tried using SKConstraints with positionX set to a constant value. At first it seemed to work, but then the player got stuck in the middle of a sloped tile and eventually fell through it.

I also tried different shapes of collision polygons on the player (e.g. a rectangle instead of a circle at the bottom) but that changed nothing.

Any help is appreciated!

Upvotes: 2

Views: 1818

Answers (2)

sangony
sangony

Reputation: 11696

This has more to do with your game logic instead of your map properties. You need to have several "states" for your player. For example, if your player is idle you can set the CGVector to 0,0. This will stop the player from moving in any direction.

To give you some examples on movement. Let's say you want to make your object move right:

// move node's physics body to the right while leaving vertical movement as is
// 160 is just an example
myNode.physicsBody.velocity = CGVectorMake(160, self.physicsBody.velocity.dy);

// do not allow right movement to exceed 160
if(myNode.physicsBody.velocity.dx > 160)
    myNode.physicsBody.velocity = CGVectorMake(160, self.physicsBody.velocity.dy);

To move left you inverse the dx value:

myNode.physicsBody.velocity = CGVectorMake(-160, self.physicsBody.velocity.dy);

if(myNode.physicsBody.velocity.dx < -160)
    myNode.physicsBody.velocity = CGVectorMake(-160, self.physicsBody.velocity.dy);

Allow myNode to be affected by gravity and it should remain in contact with the ground as it moves down a slope.

Upvotes: 1

Jake Crastly
Jake Crastly

Reputation: 462

It's a tilemap platform game...

Then gravity isn't important, put gravity to a very low value and then change all your impulses for the jumps and such in relation to the change in gravity...

OR,

Possibly, if the game isn't randomly generated you can set up a uibezierpath, and turn the path off if he stops moving up the hill.

But then if he stopped mid-hill or was starting from the top, he would still slide down...

And increasing friction (not setting it to 0) may help. Try friction at 1?

Upvotes: 0

Related Questions