Sign in to follow this  

time based movement code messed up

This topic is 3154 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

trying to make a proper movement function for a multiplayer game, only problem is it seems to be giving different results over the same amounts of time depending on the number of times the function is called, using this code:
const MAX_CPU_TOKEN_SPEED:Number = 0.160;//pixels/ms
const ACCELERATION:Number = 0.010;
const FRICTION:Number = 0.003;

function moveToken(token:Object,dt:Number):void
{
    if(((token.acceleration & 1) > (token.acceleration & 2) && (token.scaleX > 0)) || 
       ((token.acceleration & 2) > (token.acceleration & 1) && (token.scaleX < 0)))
        token.scaleX *= -1;
    var max_token_speed:Number = 1 - Math.abs(token.scaleX);
    max_token_speed *= MAX_CPU_TOKEN_SPEED * dt * 2;
    if(token.acceleration & 1)
        token.dx -= ACCELERATION * dt;
    if(token.acceleration & 2)
        token.dx += ACCELERATION * dt;
    if(token.acceleration & 4)
        token.dy -= ACCELERATION * dt;
    if(token.acceleration & 8)
        token.dy += ACCELERATION * dt;
    if(token.dx > 0)
    {
        token.dx -= FRICTION * dt;
        if(token.dx < 0)
            token.dx = 0;
    }
    else if(token.dx < 0)
    {
        token.dx += FRICTION * dt;
        if(token.dx > 0)
            token.dx = 0;
    }
    if(token.dy > 0)
    {
        token.dy -= FRICTION * dt;
        if(token.dy < 0)
            token.dy = 0;
    }
    else if(token.dy < 0)
    {
        token.dy += FRICTION * dt;
        if(token.dy > 0)
            token.dy = 0;
    }
    if(token.dx > max_token_speed)
        token.dx = max_token_speed;
    else if(token.dx < -max_token_speed)
        token.dx = -max_token_speed;
    if(token.dy > max_token_speed)
        token.dy = max_token_speed;
    else if( token.dy < -max_token_speed)
        token.dy = -max_token_speed;
    var d:Number = Math.sqrt(token.dx * token.dx + token.dy * token.dy);
    if(d > max_token_speed)
        d = max_token_speed;
    var travel_angle:Number = Math.atan2(token.dy,token.dx);
    if(Math.abs(token.dx) + Math.abs(token.dy))
        var dx:Number = d * Math.cos(travel_angle);
    else
        dx = 0;
    var dy:Number = d * Math.sin(travel_angle);
    token.x += dx;
    token.y += dy;
}

var t1:Object = new Object();
t1.acceleration = 10;
t1.scaleX = 0.5;
t1.dx = 0.01;
t1.dy = 0.01;
t1.x = 725;
t1.y = 231;
t1.width = 100;
t1.height = 50;

var t2:Object = new Object();
t2.acceleration = 10;
t2.scaleX = 0.5;
t2.dx = 0.01;
t2.dy = 0.01;
t2.x = 725;
t2.y = 231;
t2.width = 100;
t2.height = 50;

moveToken(t1,500);
for(var i:int = 0; i < 10; i++)
	moveToken(t2,50);

trace("t1: " + t1.x + "," + t1.y);
trace("t2: " + t2.x + "," + t2.y);

The result is: t1: 728.51,234.51 t2: 744.35,250.35 I can't seem to find what's causing this discrepancy so could I borrow a fresh set of eyes to maybe point out my code flaw(should work as is if you copy+paste it in any actionscript environment)

Share this post


Link to post
Share on other sites
it's just the way this integration works. If you have variable timesteps, you'll get variable results. The smaller the timestep, the more accurate the results.

if you get variable timesteps and you want to use simple integration, you can use a small timestep decomposition as a basis to get something more accurate.


float left_over = 0;
float timestep = 0.01f;

void update(float dt)
{
dt += left_over; // add rest of time from last frame.

int count = (int)(dt / timestep); // number of timesteps we have to run

left_over = dt - (count * timestep); // save the reminder

// run integration steps
for(int i = 0; i < count; i ++)
{
integrate(timestep);
}
}


This example isn't particularly good though, especially when the framerate drops (it will just drop further and further). Best is to use a better integration technique, but for the moment...

Share this post


Link to post
Share on other sites
thanks, I guess it's time I get pushed to using a ticker class anyways, and it's a pretty cheap function so I don't think it'll bog down the game at all

I still can't help but wonder though if there exists a way to do something similar to this that gives the same results no matter how many times it's called as long as they add up to the same time delta in the end and have the same inputs

Share this post


Link to post
Share on other sites

This topic is 3154 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this