Ok, calm down. Everything’s going to be ok.
I’ve managed to get it going well on my Acer A500 Tablet and I’ve heard it works on the Motorola Xoom – for every one else, your mileage may vary.
If you’re on another device, please let me know
Ok, calm down. Everything’s going to be ok.
I’ve managed to get it going well on my Acer A500 Tablet and I’ve heard it works on the Motorola Xoom – for every one else, your mileage may vary.
If you’re on another device, please let me know
A quick change to fix a device motion bug.
UI wise I’ve added an options menu which, depending on your device, allows you to manage your volume and control type.
Behind the scenes I’ve changed how the sprites draw method is called hoping to speed things up a bit, but also to help me enable Euler Integration at a later date.
As an aside, I just bought an Acer A500 tablet and have been playing around with that. It’s not running optimally on it, but it’s getting there.
Stay tuned for my “It works on Honeycomb!” post.
Note: Volume only works (so-so) on desktops (for a number of reasons), and control type can only be changed on devices with accelerometers (iPod/iPhone, iPad, and Honeycomb tablets)
I’ve been reading a couple of articles on game physics by Glenn Fiedler at gafferongames.com and thought I’d implement his Integration Basics and Fix your Timestep in javascript.
Click in the box to see it in action
Check out the javascript here or below.
/** STATE
**************************************************/
var State = function(state) {
this.setXV(state ? state.x : 0, state ? state.v : 0);
};
State.prototype.setXV = function(x, v) {
this.x = x || 0;
this.v = v || 0;
};
/** DERIVATIVE
**************************************************/
var Derivative = function() {
this.dx = 0;
this.dv = 0;
};
/** MAIN
**************************************************/
var Main = function() {
var getTimeInSeconds = function() {
return (new Date).getTime() / 1000;
};
var t = 0.0
, dt = 0.01
, currentTime = 0.0
, accumulator = 0.0
, previous = new State()
, current = new State()
, state = null
;
this.setXV = function(x, v) {
current.setXV(x, v);
};
function acceleration(state, t) {
var k = 10
, b = 1
;
return -k * state.x - b * state.v;
}
function derive(state, t) {
var output = new Derivative();
output.dx = state.v;
output.dv = acceleration(state, t);
return output;
}
function evaluate(initial, t, dt, derivative) {
var state = new State();
state.x = initial.x + derivative.dx * dt;
state.v = initial.v + derivative.dv * dt;
return derive(state, t + dt);
}
function integrate(state,t, dt) {
var a = derive(state, t)
, b = evaluate(state, t, dt * 0.5, a)
, c = evaluate(state, t, dt * 0.5, b)
, d = evaluate(state, t, dt, c)
, dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx)
, dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv)
;
state.x += dxdt * dt;
state.v += dvdt * dt;
}
function interpolate(previous, current, alpha)
{
var state = new State();
state.x = current.x * alpha + previous.x * (1 - alpha);
state.v = current.v * alpha + previous.v * (1 - alpha);
return state;
}
// shim layer with setTimeout fallback
window.requestAnimFrame = window.requestAnimationFrame
|| window.webkitRequestAnimationFrame
|| window.mozRequestAnimationFrame
|| window.oRequestAnimationFrame
|| window.msRequestAnimationFrame
|| function (callback) { window.setTimeout(callback, 1000 / 60); };
function loop() {
if (mouseUp) {
var newTime = getTimeInSeconds()
, deltaTime = newTime - currentTime
, maxDeltaTime = 0.25
;
currentTime = newTime;
if (deltaTime > maxDeltaTime) {
// note: max frame time to avoid spiral of death
deltaTime = maxDeltaTime;
}
accumulator += deltaTime;
while(accumulator >= dt) {
previous = new State(current);
integrate(current, t, dt);
t += dt;
accumulator -= dt;
}
var alpha = accumulator / dt;
current = interpolate(previous, current, alpha);
}
render(current);
}
(function animLoop() { requestAnimFrame(animLoop); loop(); })();
};
var main = new Main();
Edit: Thanks to Darren (see comment below), I’ve updated the code so that getTime now returns seconds, and set the currentTime to newtime after updating deltaTime.
follow: