eedok 982 Report post Posted April 29, 2009 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) 0 Share this post Link to post Share on other sites
oliii 2196 Report post Posted April 30, 2009 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... 0 Share this post Link to post Share on other sites
eedok 982 Report post Posted April 30, 2009 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 allI 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 0 Share this post Link to post Share on other sites