Thrust and Gravity...

Hello there,

First post at these 'ere forums, so hi everyone. :smiley:

I’m trying to implement the following and have no real idea on how to do this, especially because of the lack of floating point under J2ME and also because my math sucks.

What I want to do is have a sprite at the bottom of the screen that when you press UP thrusts into the air up the Y axis up to a maximum acceleration. When letting go of the UP button, I’d like him to fall back down again until he either hits a platform or the “ground” which is (getHeight()).

Any pointers, hints, advice on how to achieve this? This is actually (from my point of view) the hardest part of my game…after this, its plain sailing. :slight_smile:

Thanks.

As far as no floats, used fixed number math:


final int PRESICION = 16;

// convert int(5) to fix point:
int fixedFive = 5 << PRESICION;
// convert fix point to int:
int fiveAgain = fixedFive >> PRESICION;

// 1
final int FIXED_ONE = 1 << PRESICION;

// addition and subtraction of fixed points:
int fixedSix = fixedFive + FIXED_ONE;
int fixedFour = fixedFive - FIXED_ONE;

// for multiplication you need to downshift the result (watch for overflow too)
int fixedTwenty = (fixedFive * fixedFour ) >> PRESICION;
// the shift accounts for moving the point. It's kinda like
//   5.0
// * 4.0
// -----
// 20.00 (only hear presicion = 10 instead of 2^16)

// for division you have to upshift
int fixedFourAgain = (fixedTwenty / fixedFive) << PRESICION;

Now you can do the acceleration using the equations you learn in physics:


y(t) = a*t^2 + v0*t + y0
v(t) = a*t + v0

or use integration:


int dt = timePassedSinceLastFrame();
v += a * dt;
y += v * dt;

shmoove

Or if you just want to keep it really simple, just have the sprite’s y-velocity be a certain number of pixels-per-frame, e.g. -1 goes up slowly, or 1 goes down slowly (since MIDP’s Graphics object has its origin at top left).

Then your acceleration is in (pixels-per-frame)-per-frame. The code for each frame ‘tick’ is now really simple:


if (keyPressed) vy -= KEY_PRESS_ACCELERATION;
vy += GRAVITY;
y += vy;

For instance, GRAVITY could be 1, and KEY_PRESS_ACCELERATION could be 2 (1 to counter gravity plus 1 to accelerate the other way).

Instead of ‘y += vy’, you might want:


int abs = Math.abs(vy);
int sgn = (vy > 0 ) ? 1 : ((vy < 0) ? -1 : 0)
for (int i = 0; i < abs; ++i) {
    y += sgn;
    // detect collisions
}

…so that your sprite doesn’t jump through objects.

Thanks :slight_smile:

For the fixed floating point, I’ve used ShiftFP2D in the past and been happy with the results. It helps manage the data and makes the code a little easier, but as you can see above, it’s still pretty simple to do by hand.

I’m not sure of the status on ShiftFP2D as the author said he would post it on sourceforge/java.net last year. here is a link to a hopefully working version.

http://209.145.252.10/other/newsletter/newslett132.txt

Wood

Thanks. At the moment, I’m trying to get MathFP to work with EclipseME, but had no luck. Is this FP lib easier to work with?

I would suggest to use Float & FLoat11 class from:

http://henson.newmail.ru/j2me/Float11.htm
http://henson.newmail.ru/j2me/Float.htm

Everything is there. Small, simple, fast, easy to use.

Franck

[quote]fast
[/quote]
it is anything but fast =|

Simulating floating point maths is complete overkill for nearly all games.

Okay. Could you please explain how I can get my little spaceman to move more slowly around the screen whilst using a speed that is less than 1 pixel per cycle?

If I can avoid FP, I certainly will.

use counter, and limit counter patter, so you update your stuff every ‘limit counter’ is reach
but this is not good at all if you use integer counter, because you’ll have different behavior with different CPU cell phone…

so the best is to use System.currentTimeMillis() (as a counter)

Franck

[quote] Okay. Could you please explain how I can get my little spaceman to move more slowly around the screen whilst using a speed that is less than 1 pixel per cycle?
[/quote]
Using the fixed floating point math (two methods listed above), you are really only using the upper 16 bits for your current position. Shifting the number down before using it as the current position. The lower 16 bits are the fractional component. So your thrust would be less than 32000 and you add it to your position everytime through your loop. If the thrust is around 8000, your position would move by 1 pixel every four ticks.

You should also multiply your thrust by the number of milliseconds since the last tick before adding it to the position. This will allow you to base your movement on pixels per millisecond and the game will have similar performance across different platforms. Your thrust values will have to be adjusted down accordingly, but this is a very important aspect in order to make the game work better across different speed phones.

Wood

Its either fixed point, or floating point, “fixed floating point” is a contradiction.

Basing your animation loop on time deltas has a number of problems.

  1. Many phones (in particular all Samsung phones) do not handle call interupts correctly.
    Consequently, there is often no way for an app. to know a call interupt has occured.
    If the game relies on time deltas, a huge time delta (the length of the phone call) can accumulate between concurrent frames.
    There are hacky work-arounds (check for time deltas in excess of some constant value), however they often have unwanted side effects.

  2. The precision of System.currentTimeMillis() is not specified in cldc - therefor you cannot rely on its accuracy being 1ms.
    It so happens that nearly all phones I have come across do report timings to 1ms accuracy, however im quite sure there will be exceptions. (im still waiting to find a phone with a win98 accuracy of 50~60ms :D)

  3. time based animation is NOT suitable for 2D animation.

Due to the way the human brain percieves motion, time based animation loops are best suited to 3D animation.
In this situation the brain interpolates discrete positions to give a smoother perception of motion.

In 2D the brain does not do this, so sustained, fixed rate, smooth animation is preferable.

sustained, fixed rate, smooth animation is preferable.

Sorry…you’ve lost me slightly. What are you saying is the best way to handle this?

Much knowledge, this forum has!

http://www.java-gaming.org/cgi-bin/JGNetForums/YaBB.cgi?board=2D;action=display;num=1040163227;start=

Thanks :slight_smile: