How can I scale movement physics functions to frames per second (in a game engine)?
- by Richard
I am working on a game in Javascript (HTML5 Canvas). I implemented a simple algorithm that allows an object to follow another object with basic physics mixed in (a force vector to drive the object in the right direction, and the velocity stacks momentum, but is slowed by a constant drag force). At the moment, I set it up as a rectangle following the mouse (x, y) coordinates. Here's the code:
// rectangle x, y position
var x = 400; // starting x position
var y = 250; // starting y position
var FPS = 60; // frames per second of the screen
// physics variables:
var velX = 0; // initial velocity at 0 (not moving)
var velY = 0; // not moving
var drag = 0.92; // drag force reduces velocity by 8% per frame
var force = 0.35; // overall force applied to move the rectangle
var angle = 0; // angle in which to move
// called every frame (at 60 frames per second):
function update(){
// calculate distance between mouse and rectangle
var dx = mouseX - x;
var dy = mouseY - y;
// calculate angle between mouse and rectangle
var angle = Math.atan(dy/dx);
if(dx < 0)
angle += Math.PI;
else if(dy < 0)
angle += 2*Math.PI;
// calculate the force (on or off, depending on user input)
var curForce;
if(keys[32]) // SPACE bar
curForce = force; // if pressed, use 0.35 as force
else
curForce = 0; // otherwise, force is 0
// increment velocty by the force, and scaled by drag for x and y
velX += curForce * Math.cos(angle);
velX *= drag;
velY += curForce * Math.sin(angle);
velY *= drag;
// update x and y by their velocities
x += velX;
y += velY;
And that works fine at 60 frames per second. Now, the tricky part: my question is, if I change this to a different framerate (say, 30 FPS), how can I modify the force and drag values to keep the movement constant?
That is, right now my rectangle (whose position is dictated by the x and y variables) moves at a maximum speed of about 4 pixels per second, and accelerates to its max speed in about 1 second. BUT, if I change the framerate, it moves slower (e.g. 30 FPS accelerates to only 2 pixels per frame).
So, how can I create an equation that takes FPS (frames per second) as input, and spits out correct "drag" and "force" values that will behave the same way in real time?
I know it's a heavy question, but perhaps somebody with game design experience, or knowledge of programming physics can help. Thank you for your efforts.
jsFiddle: http://jsfiddle.net/BadDB