Reputation: 2815
I'm currently developing a platforming game for iOS, and decided to use SpriteKit.
I've been through this platforming game tutorial, but I would like to use the built-in physics engine instead of making my own. I've been searching the web for days without finding a good tutorial on how to create a platforming game with jumping and movement using SpriteKit, so I decided to ask here. I've also tried many different implementations, but they all "feel" wrong. There's either a problem with the movement, the jumping, or most often, both.
So what is the best way of making a sprite move and jump on the screen? In classic platformer-game style, I want the "camera" to follow the sprite when moving along the x-axis. Would the best way be to change the sprite's x-value, and then immediately center the background on the sprite? Or just move the background? And how do I get nice dynamic movement? Right now it feels very heavy, and the physics engine interferes with the movement when jumping and moving forward/backward simultaneously. And how do I go about the jumping? I want only single-jumps, with a set jump-height. However, when the sprite touches the ground the first time, I want to be able to perform a second jump (even when it's bouncing), and get to the same height.
What I have right now is this: The screen is divided in three parts, the leftmost is for moving back, the middle is for jumping, and the rightmost is for moving forward. When tapping either side, I set a bool _movingForward/_movingBackward to the appropriate value. In the update-loop I change the sprites forward/backward velocity by adding/declining the dx velocity by +/- 15. If the velocity is greater than a maxVelocity, I set it to that max velocity. Then I set the sprites velocity by
_sprite.physicsBody.velocity = CGVectorMake(forwardVel, _sprite.physicsBody.velocity.dy);
If neither _movingForward or _movingBackward is true, I decline/increase the velocity to 0.0 by +/- 4.0 to the dx velocity, to make it come stationary. However, this feels very heavy, and I've noticed that the physics engine automatically takes away some of the velocity as if there was friction or something. Is there a better way of doing this? Preferably using only the physics engine.
The same goes with the jumping. When tapping the middle part of the screen, I set a bool _isJumping to YES. In the update-loop, if _isJumping is YES and the dy velocity is 0, I apply an impulse to the sprite with
CGVectorMake(0.0f, 200.0f);
This feels good, but the problem is that the sprite needs to be totally stationary before I can perform a second jump. I want the sprite to be able to perform a second jump as soon as it touches the ground, even if it is bouncing a bit. However, I do not want this to cause the sprite to jump higher than last time.
I know my question is very broad, but some basic code-examples to what my update-loop should look like, and some tips regarding what built-in methods and functions I could use to achieve this effect would be greatly appreciated! I'm pretty new to gamedev so I'm sorry if this is very basic.
Thanks in advance! :)
EDIT 1: SHORT VERSION:
How do I use the built-in physics engine in SpriteKit to make a sprite move and jump as a result of user input.
Upvotes: 3
Views: 2110
Reputation: 990
Good, but long, question!
Apple provides us with a nifty way to center the camera on a player. You can read about it here: apple docs. Basically, what happens is you can specify at what values of the characters position do you want the camera to move. In other words, if you character moves horizontally, you can make the camera always move after the character (therefore making the character appear in the middle of the screen). You can also specify that if he jumps up, the camera doesn't need to follow him vertically (although you could if you wish, read the docs!).
To check if the player is on the ground, you can have a boolean for canJump
that is set in the update method. For example, if (sprite.position.y < 100) canJump = YES
. Of course, you would have to check which position corresponds to the ground, and add a point to make it smoother. If your character bounces off the ground (and you don't want it to), you can change its .physicsBody.restituion
property, which is basically its bounciness. If you set the property equal to 0, the sprite will not bounce back up after landing.
I would also suggest implementing the jump as an impulse. Add a constant force of gravity on the sprite, lower its friction so it doesn't affect it's speed, and when you need the character to jump up, apply an impulse to the physicsBody by doing [sprite.physicsBody applyImpulse:CGVectorMake(dx,dy)]
. This way, a burst of force is applied in a small timeframe that makes the character look like its jumping. When the impulse is applied, you can set canJump
to NO
and wait for the sprite's y position to be returned by gravity back below 100 (or whatever position your ground is at).
For moving forward and backward, your approach is fine. While _movingForward
is TRUE
, you can have the velocity be a vector with some positive x magnitude, and vice versa for the backward direction.
Upvotes: 2
Reputation: 701
i think platform gaming in sprite kit is quite easy
just try sprite kit collision system to control jump of your hero
suppose you have serval platform in your game set the collision mask and contact mask of those platform now sprite kit provide you all there methods to control your physics
invokes when two physics body contact with each other (Pre solve function invoke)
invokes when two physics body contact with each other (post solve function invoke)
so when you apply impulse to a body and set _jump to true check pre or post and set the jump false clear all forces that will work like a charm for you
Upvotes: 0