Ogen
Ogen

Reputation: 6709

Using Android timers to implement graphical movement

I'm using opengl with android. I am just playing around and trying to learn some stuff and I've decided to make a simple game where there are falling triangles and you have to tap them to "collect" them (Don't steal my idea! xD).

I am using an Android Timer like this:

Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {

    @Override
    public void run() {
        float[] p1Temp = mTriangle.getP1();
        float[] p2Temp = mTriangle.getP2();
        float[] p3Temp = mTriangle.getP3();

        mTriangle.changeCoords(new float[] {p1Temp[0], p1Temp[1] - 0.01f, p1Temp[2],
                                            p2Temp[0], p2Temp[1] - 0.01f, p2Temp[2],
                                            p3Temp[0], p3Temp[1] - 0.01f, p3Temp[2]});

        if (mTriangle.getP1()[1] <= -1.0f ||
            mTriangle.getP2()[1] <= -1.0f ||
            mTriangle.getP3()[1] <= -1.0f) {
            t.cancel();
        }
    }

}, 0, 40);

So basically what this code is doing is this: there is a timer, and every 40 milliseconds, the y coordinate of every vertex of the falling triangle is decremented. This process stops when it hits the bottom of the screen (i.e. hit the ground).

My question is this, I'm new to using openGL in android, is this the correct way to handle "movement" of objects etc? Or are there methods I'm supposed to use to implement animation/movement.

Upvotes: 0

Views: 555

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54652

The most common approach I have seen is somewhat different. It's more typical to update the animation while preparing to render each frame, and base the update on the amount of time that has passed since the last frame.

Since distance is velocity multiplied by time, you do this by assigning a velocity vector to each of your objects. Then when it's time to update the animation, you take the time difference since the last update, and the increment you apply to your positions is the time difference multiplied by the velocity. The velocity is constant as long as you just use a linear motion, but can also change over time for more complex animations, e.g. due to gravity, collision with other objects, etc.

If you're using OpenGL on Android, you're probably using a GLSurfaceView for your rendering. By default, the GLSurfaceView will already invoke your rendering function continuously, up to 60 fps if your rendering can keep up with the display refresh rate.

What you roughly do is keep the time when the last frame was rendered as a member variable in your GLSurfaceView.Renderer implementation. Then each time onDraw() is called, you get the new time, and subtract the last frame time from this time to get the time increment. Then you store away the new time in your member variable, multiply the time increment by the velocity, and add the result to your positions.

After the positions are updated, you render your objects as you normally would.

To give you the outline, the following is a slightly adapted piece of (pseudo-)code I copied from my answer to a similar question (Android timing in OpenGL ES thread is not monotonic):

public void onDrawFrame(GL10 gl) {
    currentTime = SystemClock.elapsedRealtime()
    deltaTime = currentTime - lastFrameTime
    lastFrameTime = currentTime
    update animation based on deltaTime
    draw frame
}

Where lastFrameTime is a member variable, currentTime a local variable.

Upvotes: 1

Related Questions