Physics or Time-Based Animation?

I am part way through creating a Doodle Jump clone. I’m currently using the physics engine.

I have encountered a problem that is prohibiting me to carry on, and I’m wondering whether it’s worth re-writing the game using time based animations rather than the physics engine, as it could give me more flexibility.

The problem I’m faced with involves moving the platforms down and the character’s height. If you play Doodle Jump and watch how the character behaves you’ll see that he doesn’t EVER go any higher than a certain point, no matter what height the platform he came off was. The higher he appears to jump is actually the platforms moving down faster. The character also jumps for the same duration every time. If you look at his position on the screen, he may only move up by a few pixels, but he’ll appear to be jumping for a lot longer, the same length of time for each jump.

I cannot grasp how this could have been achieved using the physics engine. I am currently moving the platforms down at the same speed as the character moves up - but this doesn’t stop him gaining height, and doesn’t mean his height on the screen is fixed.

I have an idea how to do it in the physics engine, but it seems VERY complicated for something so simple. It would involve working out a calculation for his current height and then manipulate the gravity and his density so that he always jumps the same height for the same length of time. This would be a trial and error scenario, and to be honest, it’s clutching at straws.

My question is, has anyone achieved this behaviour already, know how it has been achieved, or can shed any light on it? Would I be better with the physics engine, or with time-based animation (see the bouncing ball example in the sample code)?

Here is a link to a YouTube gameplay video of Doodle Jump, hopefully you’ll see what I mean - it’s a difficult concept to describe in text.
http://www.youtube.com/watch?v=kIqG2ICUS-c [import]uid: 61422 topic_id: 15651 reply_id: 315651[/import]

I would say do it with animation not physics. My attempt would be to have a vertical limit on the screen which the character cannot go above. When the character hits that height the background starts moving down.

Once the inertia (your own calculation, of course) of moving up drops too low, the background stops moving and the character is allowed to drop, again using your own dropping calc.

If you were to use physics, I think you’d have to keep tight track of where the character is on the screen and that means using the enterFrame event to ensure that the overall world display group is moved down enough to stop the character from going too high on the screen.

I do think using physics would be a fun way to do it, but I haven’t actually tried coding it yet… [import]uid: 8271 topic_id: 15651 reply_id: 57746[/import]

Honestly, a huge part of the games I see people working on with physics in Corona would be MUCH better off being rewritten with simple math.

I typically create a player character with the following properties:

Hero.xpos
Hero.ypos
Hero.xvel
Hero.yvel
Hero.xaccel
Hero.yaccel (or Hero.gravity if you prefer)
Hero.xfriction

Then what you do each frame is something according to these lines (only for horizontal movement):

-- first update the hero-speed based on touch input  
if (touch == "left") then  
 Hero.xvel = Hero.xvel - Hero.xaccel  
elseif (touch == "right") then  
 Hero.xvel = Hero.xvel + Hero.xaccel  
end  
  
-- then update the hero-position based on his speed  
Hero.xpos = Hero.xpos + Hero.xvel  

This is just a rough basis for the complete framework, but it works for a LOT of situations where physics is unnecessarily used. The vertical movement is typically a bit more complex because you want to incorporate collision detection (for landing on objects), but that’s just a matter of calculating the distance, and if needed adjusting the hero’s vertical position to that of the object landed on plus an offset.

Don’t let the math put you off because it is really simple: every frame you update the Hero-position by adding the Hero-speed to it. And the Hero-speed is updated every frame by adding the acceleration to it. Speed can be positive or negative meaning moving right or left, respectively.

I plan on doing a tutorial on this when I get the time, but for the time being: simple math is your friend - and especially trigonometrics.

Cheers,
Thomas [import]uid: 70134 topic_id: 15651 reply_id: 57749[/import]

Thanks for the response.

That sounds great, I’ll make a start on tackling it without using the physics engine.

One thing though. With the physics engine I use collisions to tell when the platform hits the player, obviously I can’t do that without the physics engine. How should I do it? I don’t really want to loop through all of the platforms on enterFrame and check their positions against the position of the character as it might be quite an overhead - or would it? [import]uid: 61422 topic_id: 15651 reply_id: 57753[/import]

I actually tried this. I previously had a loop that goes through all the objects and checks for all possible collisions. I then switched to physics *only* for the collision. It made the game so much smoother! I say use physics only for collision, and then use your own loop to update the positions of all objects on the screen. That’s exactly what I’m doing now and it seems like the best of both worlds :slight_smile: [import]uid: 51654 topic_id: 15651 reply_id: 57754[/import]

I see things differently, and don’t see the need for physics here at all, if you program things right.

Mike, what you suggest is exactly how I would do it, and how it will work, if you optimize things - which you always should.

I can imagine that you would only have 5, maximum 10 objects onscreen, right? Obviously you would only loop through the objects that are visible, and I would suggest only checking if the vertical position would cause a collision. Then if you find an object for which this is true, you check this single object to see if the horizontal position of these two objects would cause a collision, an handle it as needed.

Your math is supersimple here, and should execute in a split second, so things should run smoothly. If you’re keeping a lot of display objects alive, even when not visible, that’s a sign that your code is unoptimized. One way to tackle this is to use a table or array of all your objects, even if there are a hundred, and only instantiate a display object when they are on screen.

How is your game set up at the moment? [import]uid: 70134 topic_id: 15651 reply_id: 57756[/import]

Again, thanks for the comments.

The code is pretty well optimised. I generate platforms about 10 pixels above the ‘ceiling’ of the screen, and destroy them about 10 pixels below. There are only every around 8 platforms on the screen at any one time.

I was just concerned with the hit of looping through the object on enterFrame, which would be running 60 times every second. If it’s a standard practice though, then that’s great and I’ll crack on :slight_smile:

Thanks again [import]uid: 61422 topic_id: 15651 reply_id: 57757[/import]

Hi Mike,

That sounds good, but I think 30 fps should be plenty. Registering touch events seems to take quite a hit on the Corona framework, I have to say, and running at 30 fps makes the hit half the size, relatively speaking.

Let me know when you have some code to show! [import]uid: 70134 topic_id: 15651 reply_id: 57759[/import]

@ thomas6

I did heavily optimize everything, but I still noticed a performance improvement when using the physics to register objects for collision events. I used to have about 100 enemies on the screen (coming from top to bottom) and then my character is at the bottom shooting with his gun (which also shoots *extremely* fast. Using loops to go through the array of enemies and then compare with each individual bullet was having a bigger performance hit that just using physics. I guess YMMV depending on the type of app you’re creating. [import]uid: 51654 topic_id: 15651 reply_id: 57761[/import]

@thomas6 I completely agree with you, however when I was writing my game (“Tiltopolis” - basically Blocks with a seesaw) I tried using regular maths. Calculating natural acceleration/deceleration seemed very hard and then there were issues with angles - so it ended up being much easier to use the physics engine. I’m terrible with maths, so I can imagine the lure of the physics being strong for everyone… [import]uid: 8271 topic_id: 15651 reply_id: 57928[/import]

Naveen, you might have a point there. I haven’t used physics for collision testing, but since Box2D is running on much lower level code it might be faster for some stuff - especially when the number of objects is in the hundreds.

Horacebury, yeah, I can imagine that math can be daunting. It was for me too, until I realise that you can split up most motions into a horizontal and vertical component real easy (even a circular motion: that’s just setting x to the sine of value TIME and y to the cosine of value TIME). It’s cool what you can achieve this way! [import]uid: 70134 topic_id: 15651 reply_id: 57930[/import]

SINE, COS… Ok, there you go, you’ve done it. I don’t want to sound extremely dumb, but I tried very, very hard at school (seriously, you wouldn’t believe what I went through) to understand A-level maths and just could not do it. I really wish I could… [import]uid: 8271 topic_id: 15651 reply_id: 57932[/import]

Hi Horace,

I read you loud and clear: I had the luck of having a very visually inclined smart older brother who made the best drawings of real life examples of math concepts. That’s what made the click happen in my head. I remember high school textbooks as being so convoluted compared to how I learned that stuff.

I’ll keep you posted on that tutorial then eh? :wink: [import]uid: 70134 topic_id: 15651 reply_id: 57933[/import]

If you do want to get started, here’s a really simple bit of code that I like:

[lua]local image = display.newImage(“image.png”, 200,200)

local function MakeImageFloatVertically()

local sinespeed = 100 – bigger value is slower movement
local amplitude = 80 – bigger value is bigger movement

image.y = 200+(math.sin(event.time/sinespeed)*amplitude)

end – MakeImageFloatVertically

Runtime:addEventListener(“enterFrame”, MakeImageFloatVertically)[/lua]

Let me know how this works for you (hope it’s without typos).

Cheers,
Thomas

[import]uid: 70134 topic_id: 15651 reply_id: 57934[/import]