using System; using System.Collections.Generic; using System.Text; using FRB; using FRB.Text; namespace RocketBrawl.Screens { class TestScreen : Screen { Sprite s; State current; State previous; float t = 0.0f; float dt = 0.1f; float currentTime = 0.0f; float accumulator = 0.0f; Text time; public TestScreen(FrbEngineReferences refs) : base(string.Empty, string.Empty, refs) { s = sprMan.AddSprite("redball.bmp"); current.x = 10; current.v = 3f; previous = current; time = textMan.AddText(string.Empty); time.x = -5; time.y = -5; TimeManager.StartFPSRecording(); } public override void Activity() { base.Activity(); float newTime = TimeManager.secondDifference; float deltaTime = newTime - currentTime; currentTime = newTime; if (deltaTime > 0.25f) deltaTime = 0.25f; accumulator += deltaTime; while (accumulator >= dt) { accumulator -= dt; previous = current; integrate(ref current, t, dt); t += dt; } State state = interpolate(ref previous, ref current, accumulator / dt); s.x = state.x; time.text = accumulator.ToString(); } public override void Destroy() { base.Destroy(); sprMan.RemoveSprite(s); } struct State { public float x; public float v; } struct Derivative { public float dx; public float dv; } State interpolate(ref State previous, ref State current, float alpha) { State state; state.x = current.x * alpha + previous.x * (1 - alpha); state.v = current.v * alpha + previous.v * (1 - alpha); return state; } float acceleration(ref State state, float t) { const float k = 10; const float b = 1; return -k * state.x - b * state.v; } Derivative evaluate(ref State initial, float t) { Derivative output; output.dx = initial.v; output.dv = acceleration(ref initial, t); return output; } Derivative evaluate(ref State initial, float t, float dt, ref Derivative d) { State state; state.x = initial.x + d.dx * dt; state.v = initial.v + d.dv * dt; Derivative output; output.dx = state.v; output.dv = acceleration(ref state, t + dt); return output; } void integrate(ref State state, float t, float dt) { Derivative a = evaluate(ref state, t); Derivative b = evaluate(ref state, t, dt * 0.5f, ref a); Derivative c = evaluate(ref state, t, dt * 0.5f, ref b); Derivative d = evaluate(ref state, t, dt, ref c); float dxdt = 1.0f / 6.0f * (a.dx + 2.0f * (b.dx + c.dx) + d.dx); float dvdt = 1.0f / 6.0f * (a.dv + 2.0f * (b.dv + c.dv) + d.dv); state.x = state.x + dxdt * dt; state.v = state.v + dvdt * dt; } } }