Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
    <body>
        <div id="stage"></div>
    </body>
</html>
 
/**
  * BASE.JS
  */
window.requestAnimationFrame = (function() {
      return window.requestAnimationFrame ||
             window.mozRequestAnimationFrame ||
             window.webkitRequestAnimationFrame ||
             window.msRequestAnimationFrame ||
             window.oRequestAnimationFrame ||
               function(callback) {
                     return window.setTimeout(callback, 16.6667);
               };
}());
var add_listener = function(target, event, callback, context) {
    var fn = function(e) {
        callback.call(context, e);
    };
    
    if(target.addEventListener)
        target.addEventListener(event, fn, false);
};
var set_interval = function(ms, fn, context) {
    return setInterval(function() {
                          fn.call(context);
                      }, ms);
};
var set_timeout = function(ms, fn, context) {
    return setTimeout(function() {
                          fn.call(context);
                      }, ms);
};
var request_animation_frame = function(callback, context) {
  return window.requestAnimationFrame(function() {
                                  callback.call(context);
                              });
};
var make_canvas = function(w, h, id, pid) {
    var canvas = document.createElement('canvas');
    canvas.width = Number(w) || 1;
    canvas.height = Number(h) || 1;
    canvas.id = (id !== null && typeof(id) == 'string') ? id : '';
    
    var ctx = canvas.getContext('2d');
    ctx.imageSmoothingEnabled = false;
    ctx.mozImageSmoothingEnabled = false;
    ctx.webkitImageSmoothingEnabled = false;
    
    if(pid !== null && typeof(pid) == 'string') {
          var p = document.getElementById(pid);
          if(p)
              p.appendChild(canvas);
          else
              document.getElementsByTagName('body')[0].appendChild(canvas);
    }
    
    return canvas;
};
//Closure - goog inheritence
var inherit = function(sub, sup) {
    var t = function() {};
    t.prototype = sup.prototype;
    sub._super = sup.prototype;
    sub.prototype = new t();
    sub.prototype.constructor = sub;
};
/**
  * KEYBOARD.JS
  */
var Keyboard = function() {
    if(Keyboard.prototype._singleton)
          return Keyboard.prototype._singleton;
    
    Keyboard.prototype._singleton = this;
    
    this.keys = {};
    this.lastKeys = {};
    
    add_listener(window, 'keydown', this.onKeyDown, this);
    add_listener(window, 'keyup', this.onKeyUp, this);
};
Keyboard.Keys = {
    UP: 38,
    DOWN: 40,
    LEFT: 37,
    RIGHT: 39
};
Keyboard.prototype.onKeyDown = function(e) {
    var keyCode = e.which ? e.which : e.keyCode;
    this.keys[keyCode] = true;
};
Keyboard.prototype.onKeyUp = function(e) {
    var keyCode = e.which ? e.which : e.keyCode;
    this.keys[keyCode] = false;
};
Keyboard.prototype.keyPressed = function(key) {
    return this.keys[key] === true;
};
Keyboard.prototype.keyHit = function(key) {
    return (this.keyPressed(key) && !this.lastKeys[key]);
};
Keyboard.prototype.reset = function() {
    for(var k in this.keys) {
          this.lastKeys[k] = this.keys[k];
    }
};
/**
  * STATE.JS
  */
var State = function(game) {
    this.game = game;
    this.width = this.game.getWidth();
    this.height = this.game.getHeight();
    
    this.canvas = make_canvas(this.width, this.height);
    this.ctx = this.canvas.getContext('2d');
    this.ctx.font = '22px bold \'courier new\'';
    
    this.ticks = 0;
    this.updateFrameTicks = 0;
    this.renderFrameTicks = 0;
    this.updateFrames = 0;
    this.renderFrames = 0;
    this.ups = 0;
    this.rps = 0;
};
State.DELTA_TIME = 16.6667;
State.MAX_UPDATES = 3;
State.prototype.update = function(ms) {
    this.ticks += ms;
    
    var updates = 0;
    while(this.ticks >= State.DELTA_TIME && updates < State.MAX_UPDATES) {
          this.updateState();
        
          this.updateFrameTicks += State.DELTA_TIME;
          this.updateFrames++;
        
          if(this.updateFrameTicks >= 1000) {
              this.ups = this.updateFrames;
              this.updateFrames = 0;
              this.updateFrameTicks -= 1000;
          }
        
        this.ticks -= State.DELTA_TIME;
        updates++;
    }   
    
    if(updates > 0) {
          this.renderFrameTicks += updates*State.DELTA_TIME;
          this.renderFrames++;
        
          if(this.renderFrameTicks >= 1000) {
              this.rps = this.renderFrames;
              this.renderFrames = 0;
              this.renderFrameTicks -= 1000;
          }
        
          this.renderState(updates*State.DELTA_TIME);
    }
    
};
State.prototype.updateState = function() {
};
State.prototype.renderState = function(ms) {
};
State.prototype.renderFPS = function() {
    this.ctx.save();
    this.ctx.fillStyle = '#ffffff';
    this.ctx.strokeStyle = '#000000';
    this.ctx.strokeText('UPS: ' + this.ups, 20, 20);
    this.ctx.fillText('UPS: ' + this.ups, 20, 20);
    this.ctx.strokeText('FPS: ' + this.rps, 20, 40);
    this.ctx.fillText('FPS: ' + this.rps, 20, 40);
    this.ctx.restore();
};
State.prototype.destroyState = function() {
    delete this.ctx;
    delete this.canvas;
};
/**
  * LEVEL_STATE.JS
  */
var LevelState = function(game) {
    State.call(this, game);
    var g1 = this.ctx.createRadialGradient(this.width/2, this.height/2, 0, this.width/2, this.height/2, this.width/2);
    
    g1.addColorStop(0.1, '#7d97c2');
    g1.addColorStop(0.2, '#6f85a9');
    g1.addColorStop(0.3, '#607391');
    g1.addColorStop(0.4, '#53627b');
    g1.addColorStop(0.5, '#485469');
    g1.addColorStop(0.6, '#3d4757');
    g1.addColorStop(0.7, '#343c48');
    g1.addColorStop(0.8, '#282d36');
    g1.addColorStop(0.9, '#22262c');
    g1.addColorStop(1.0, '#16181b');
    
    this.g1 = g1;
    
    this.player = {
                      x: 0, y: 0, w: 50, h: 50, t: 100,
                      speed: 5,
                      baseCol: 'rgba(0, 0, 0, 1)',
                      faceCol: 'rgba(41, 134, 58, 0.4)',
                      topCol:  'rgba(134, 212, 149, 0.2)'                   
                  };
};
inherit(LevelState, State);
LevelState.prototype.updateState = function() {
    var kb = Keyboard();
    
    if(kb.keyPressed(Keyboard.Keys.UP)) {
          this.player.y -= this.player.speed;
    }
    
    if(kb.keyPressed(Keyboard.Keys.DOWN)) {
          this.player.y += this.player.speed;
    }
    
    if(kb.keyPressed(Keyboard.Keys.LEFT)) {
          this.player.x -= this.player.speed;
    }   
        
    if(kb.keyPressed(Keyboard.Keys.RIGHT)) {
          this.player.x += this.player.speed;
    }
    
    if(this.player.x - this.player.w/2 < 0) {
          this.player.x = this.player.w/2;
    }
    
    if(this.player.x + this.player.w/2 >= this.width) {
          this.player.x = this.width - this.player.w/2 - 1;
    }
    
    if(this.player.y - this.player.h/2 < 0) {
          this.player.y = this.player.h/2;
    }
    
    if(this.player.y + this.player.h/2 >= this.height) {
          this.player.y = this.height - this.player.h/2 - 1;
    }
};
LevelState.prototype.renderState = function(ms) {
    this.ctx.clearRect(0, 0, this.width, this.height);
    
    this.ctx.fillStyle = this.g1;
    this.ctx.fillRect(0, 0, this.width, this.height);
    
    this.ctx.fillStyle = this.player.baseCol;
    this.ctx.fillRect(this.player.x - this.player.w/2, this.player.y - this.player.h/2, this.player.w, this.player.h);
    this.ctx.fillStyle = this.player.faceCol;
    this.ctx.fillRect(this.player.x - this.player.w/2, this.player.y - this.player.t + this.player.h/2, this.player.w, this.player.t);
    this.ctx.fillStyle = this.player.topCol;
    this.ctx.fillRect(this.player.x - this.player.w/2, this.player.y - this.player.t - this.player.h/2, this.player.w, this.player.h);
    
    this.renderFPS();
    
    this.game.blitCanvas(this.canvas);
};
/**
  * GAME.JS
  */
var SCREEN_WIDTH = 640,
    SCREEN_HEIGHT = 480;
    
var Game = function() {
    if(Game.prototype._singleton)
        return Game.prototype._singleton;
    Game.prototype._singleton = this;
    
    this.width = SCREEN_WIDTH;
    this.height = SCREEN_HEIGHT;
    
    this.canvas = null;
    this.ctx = null;
    
    this.state = null;
    
    this.keyboard = new Keyboard();
    
    this.running = false;
    this.lastUpdate = 0;
    
    this.init();
};
Game.prototype.init = function() {
    this.canvas = make_canvas(this.width, this.height, 'screen', 'stage');
    this.ctx = this.canvas.getContext('2d');
    
    this.state = new LevelState(this);
};
Game.prototype.start = function() {
    if(!this.running) {
          this.running = true;
        this.lastUpdate = +Date.now();
        this.animFrame = request_animation_frame(this.update, this);
    }
};
Game.prototype.update = function() {
    var now = +Date.now();
    var ms = now - this.lastUpdate;
    this.lastUpdate = now;
    
    this.animFrame = request_animation_frame(this.update, this);
  
    this.state.update(ms);
    this.keyboard.reset();
};
Game.prototype.blitCanvas = function(canvas) { 
    this.ctx.clearRect(0, 0, this.width, this.height);
    this.ctx.drawImage(canvas, 0, 0);
};
Game.prototype.getWidth = function() {
    return this.width;
};
Game.prototype.getHeight = function() {
    return this.height;
};
/**
  * RUN_GAME.js
  */
var g = new Game();
g.start();
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers