Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!doctype html>
- <html>
- <head>
- <style>
- canvas { border:1px solid black; width:480px; height:320px; }
- </style>
- </head>
- <body>
- <canvas id='screen' width='480' height='320'></canvas>
- <p><input type="checkbox" id="sync">Sync update to animate</input>
- <p>Step delay (ms):<input type="text" id="stepdelay"></input>
- <p>Animate delay (ms):<input type="text" id="animatedelay"></input>
- <p><input type="text" id="counter"></input>
- <script>
- // Grab the canvas
- var canvas = document.getElementById('screen'),
- ctx = canvas.getContext('2d'),
- gamewidth = canvas.width,
- gameheight = canvas.height,
- running = false,
- sync = document.getElementById("sync"),
- timer = {
- fps: 1/60, // Frames per second
- fpsMS: 1000/60, // Frame time in ms
- accum:0, // Accumulated deltas
- delta:0, // the delta between frames
- last:(new Date()).getTime(),
- now: (new Date()).getTime(),
- // tick the clock on each update (simulation step)
- tick: function() {
- this.last = this.now;
- this.now = (new Date()).getTime();
- this.delta = Math.min(this.now - this.last, 250);
- this.accum += this.delta;
- }
- },
- // Keep track of the actual updates per second (ups) and frames per second (fps)
- counter = document.getElementById("counter"),
- laststep = Date.now(),
- lastanimate = Date.now(),
- avgdtu = 0,
- avgdtf = 0,
- updatecounter = function () {
- counter.value = (1000/avgdtu).toPrecision(3) + "ups " + (1000/avgdtf).toPrecision(3) + "fps";
- },
- // Call this once per step to keep count
- countstep = function () {
- var now = Date.now(), dt = now - laststep;
- laststep = now;
- avgdtu = 0.95 * avgdtu + 0.05 * dt;
- updatecounter();
- },
- // Call this once per animate to keep count
- countanimate = function () {
- var now = Date.now(), dt = now - lastanimate;
- lastanimate = now;
- avgdtf = 0.95 * avgdtf + 0.05 * dt;
- updatecounter();
- },
- // Do nothing for dt milliseconds
- delay = function (dt) {
- var end = Date.now () + dt;
- while (Date.now() < end);
- },
- stepdelay = document.getElementById("stepdelay"),
- animatedelay = document.getElementById("animatedelay"),
- // A simple box to bounce around the canvas
- box = {
- position: { x:228, y:135},
- lastPostition: { x:228, y:135},
- velocity: { x1:1, x2:1},
- speed: 60,
- width:16, height:16
- },
- /*
- ** This is the simulation step
- */
- pendingUpdate = null;
- update = function() {
- // ticks the clock,
- timer.tick();
- // steps the simulation at a fixed delta until the accumlated delta time is consumed
- while(timer.accum >= timer.fpsMS) {
- timer.accum -= timer.fpsMS;
- step(timer.fps);
- }
- // if running continue the simulation loop
- if(running && !sync.checked) { pendingUpdate = setTimeout(update, timer.fpsMS); }
- else pendingUpdate = null;
- },
- step = function(delta) {
- countstep();
- delay(+stepdelay.value);
- // move the old position to lastPosition before updating to preserve two states
- box.lastPostition = box.position;
- // compute the change in (x, y)
- var dx = box.velocity.x1 * box.speed * delta,
- dy = box.velocity.x2 * box.speed * delta;
- // if out of bounds reverse velocity, otherwise add the change in position
- if(box.position.x + dx < 0 || box.position.x + dx + box.width > gamewidth) {
- box.velocity.x1 = box.velocity.x1 * -1;
- } else {
- box.position.x += dx;
- }
- if(box.position.y + dy < 0 || box.position.y + dy + box.height > gameheight) {
- box.velocity.x2 = box.velocity.x2 * -1;
- } else {
- box.position.y += dy;
- }
- },
- /*
- ** This is the animation step
- */
- animate = function() {
- countanimate();
- delay(+animatedelay.value);
- if (!pendingUpdate) update();
- // If running request a new frame continuing the loop
- if(running) { window.requestAnimFrame(animate); }
- // Linear Interpolation
- var a = timer.accum > timer.fspMS ? timer.accum / timer.fpsMS : 1,
- x0 = box.lastPostition.x, y0 = box.lastPostition.y,
- x1 = box.position.x, y1 = box.position.y,
- pt = {
- x: x0 + ( (x1 - x0) * a ),
- y: y0 + ( (y1 - y0) * a )
- };
- // Canvas clear and drawing
- ctx.clearRect(0, 0, gamewidth, gameheight);
- ctx.fillRect(pt.x, pt.y, box.width, box.height);
- },
- // Called on load to start the loops
- start = function() {
- running = true;
- update();
- animate();
- };
- window.onload = start;
- // Awesome requestAnimationFrame shim by Paul Irish
- // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
- window.requestAnimFrame = (function(){
- return window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame ||
- function( callback ){
- window.setTimeout(callback, 1000 / 60);
- };
- })();
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement