3

I am building a flappy bird game where half of the level is above water, and the other half is below water.

If your bird is in the air, there is regular gravity and when you tap, an impulse is applied going straight up.

If your bird is in the water, gravity should be in the negative direction (going up) and be less. When you tap, an impulse is applied going straight down.

Can I set a scene's gravity in different places?

I thought of using a timer to apply negative forces if the bird is in the water, but it's all over the place.

Also, I can't just change the entire scene's gravity because there are other SKSprite objects in the scene that should have different gravity applied to them (for instance one bird in the air should be flapping up when tapping, and a bird that dove into the water should be swimming down when tapping all at the same time).

CodeSmile
  • 64,284
  • 20
  • 132
  • 217
Kjell
  • 801
  • 7
  • 19

2 Answers2

2

Gravity is the same throughout the world, so you can't have areas of different gravity.

However, just because SpriteKit doesn't offer a higher level abstraction for something doesn't mean it's difficult to do for yourself. SpriteKit's constant gravity does the same thing to a body as if you apply a force to it with the same magnitude and direction every time your scene's update: method runs.

So, you can do different gravity in the upper and lower parts of your scene in your update: method.

  1. Check the y-coordinate of your bird.
  2. If it's below whatever threshold separates water from air, use applyForce: to apply an upward force. If it's above the water, apply a downward force.
  3. Because this happens every frame, the bird will accelerate downward when above the water and upward when below, and you should see a nice loss of momentum effect just after the transition.

You'll need to tweak the magnitude of your forces until it behaves just right for the gameplay you want. When you do, be aware that the units for applyForce: are 150x those of SKPhysicsWorld's gravity (because of what's probably an Apple bug) and depend on the mass of your physics body (because of Newton's second law).

rickster
  • 124,678
  • 26
  • 272
  • 326
  • 2
    Also, does Stack Overflow have a tag for "my first SpriteKit project is a flappy bird clone"? Seems like a lot of such questions lately. :D – rickster Mar 19 '14 at 03:21
  • There is now. ;) [flappy-bird-clone] Didn't think of it before but it's actually semi-serious, considering that flappy bird clone creators might want to look up their peer's problems. – CodeSmile Mar 19 '14 at 09:07
  • PS: it's 58 questions at the time of writing. I'm sure there'll be lots more. ;) – CodeSmile Mar 19 '14 at 09:42
0

I have an idea for how you can do this:

  1. make two rectangles for the top and bottom half (one for water, one for the air)
  2. create a physics body on each rectangle that simulates the gravity you desire
  3. set those rectangles as the contact delagate
  4. add the other objects to the rectangular world they should be in
  5. To handle main bird: - When the anchor point (probably set in middle) contacts one of the rectangles, change the contact delegate of the main player from the first body to the second body in the contact event.

This means that you have two worlds with different gravities with a main character who's gravity switches among contact of a new world(passing through the middle)

Good luck

meisenman
  • 1,818
  • 1
  • 15
  • 25
  • Gravity is an attribute of the world, not individual bodies. There's not one world per scene and one scene per view. You might be able to modify this idea to use two entirely separate views, but you'd have some nasty (literal) edge cases to deal with. – rickster Mar 19 '14 at 02:26
  • You are right, sorry. My only advice would then be to apply gravity only to the player and switch the gravity based on his y-location. For the background use actions like moveTo. They wouldn't work for the gravity world but you could replicate their motions quite well and still detect their collisions and contact. – meisenman Mar 19 '14 at 03:46