title: How can I speed up my Javascript Game Engine
body: <p>So, recently, I've been working on a JS/HTML5 Game Engine. Right now I'm calling it DimSumJs, because like <a href="http://en.wikipedia.org/wiki/Dim_sum" rel="nofollow">DimSum</a> isn't a full meal, my framework still runs too slowly to make a full game (it can only run about 250 "objects" despite before slowing down, it becomes very noticeable around 300 "objects"). It uses divs inside an iframe.</p>
  
  <p>A sample game is available at <a href="http://pandamochi.x10.bz" rel="nofollow">http://pandamochi.x10.bz</a></p>
  
  <p>just view resources with google chrome and you should be able to find the dimsum.js file</p>
  
  <pre><code>//DimSumJS - Open Source Game Engine
  //DimSumJS (C) Ruochen Tang
  //Can be used commerically, but please give credit
  //Constants
  var RIGHTKEY = 37;
  var UPKEY = 38;
  var LEFTKEY = 39;
  var DOWNKEY = 40;
  var SPACEKEY = 32;
  var MASTER_WIDTH = 480;
  var MASTER_HEIGHT = 600;
  
  var Game = window.frames[0].document.body;
  Game.setAttribute("width",MASTER_WIDTH + "px");
  Game.setAttribute("height",MASTER_HEIGHT + "px");
  var gl = setInterval("gameLoop();",15);
  
  //Global Vars
  var keyDown = new Array();
  for (var i = 0; i &lt; 256; i++){
      keyDown[i] = false;
  }
  var gameState = 1;
  
  //Settings
  Game.style.backgroundColor = "#000";
  
  //Key
  processKeyEvent = function(event){
          // MSIE hack
          if (window.event)
          {
              event = window.event;
          }
  
          keyDown[event.keyCode] = true;      
  };
  
  releaseKey = function(event){
      // MSIE hack
          if (window.event)
          {
              event = window.event;
          }
  
      keyDown[event.keyCode] = false;
  }
  Game.onkeydown = processKeyEvent;
  Game.onkeyup = releaseKey;
  
  
  var GameObjects = new Array();
  
  function GameObject(xx, yy, w, h, i, inc, gs, name, img){
  
      GameObjects.push(this);
  
      this.width = w;
      this.height = h;
      this.index = i;
      this.currIndex = 0;
      this.increment = inc;
      this.currInc = 0;
      this.x = xx;
      this.y = yy;
      this.depth = 0;
      this.objType = name;
      this.image = img;
      this.xScale = 1;
      this.yScale = 1;
      this.scaleString = "scale(" + this.xScale + "," + this.yScale + ")";
      this.speed = 0;
      this.direction = 0;
      this.gravity = 0;
      this.gravityDirection = 0;
      this.active = true;
      this.visible = true;
      this.bindToRoom = false;
      this.text = "";
      this.color = "#FFF";
      this.gameState = gs;
  
      this.div = document.createElement("div");
      this.div.className=this.objType;
      this.div.style.position="absolute";
      this.div.style.left= this.x + "px";
      this.div.style.top= this.y + "px";
      this.div.style.width= this.width + "px";    
      this.div.style.height= this.height + "px";  
      this.div.style.backgroundImage = "url(images/" + this.image + ")";
  
      this.div.style[getTransformProperty(this.div)] = this.scaleString;
  
      Game.appendChild(this.div);
      this.isDiv = true;
      this.classChanged = false;
  
      this.move = move;
      this.anim = anim;
      this.setScale = setScale;
      this.checkCollisionAt = checkCollisionAt;
      this.objectAt = objectAt;
      this.objectTypeAt = objectTypeAt;
      this.toggleActive = toggleActive;
      this.extend = extend;
      this.unextend = unextend;
      this.isType = isType;
      this.update = update;
  
  
      function move(xx,yy){
          this.x += xx;
          this.y += yy;
      }
  
      function anim(){
          this.currInc += 1;
          if (this.currInc &gt;= this.increment){
              this.currInc -= this.increment;
              this.currIndex += 1;
              if (this.currIndex &gt;= this.index){
                  this.currIndex -= this.index;
              }
  
          }
  
      }
      function extend(type) {
          this.objType += " " + type;
          this.classChanged = true;
      }
  
      function unextend(type) {
          this.objType = this.objType.replace( /(?:^|\s)type(?!\S)/ , '' );
          this.classChanged = true;
      }
  
      function isType(type) {
              return ((' ' + this.objType + ' ').indexOf(' ' + type + ' ') &gt; -1);
      }
  
      function setScale(xx,yy){
          this.xScale = xx;
          this.yScale = yy;
          this.scaleString = "scale(" + this.xScale + "," + this.yScale + ")";    
      }
  
  
      function checkCollisionAt(xx,yy,other){
          //Check For Collision
          xx += this.x;
          yy += this.y;
  
          if ((xx + this.width &gt; other.x) &amp;&amp; (xx &lt; other.x + other.width) &amp;&amp; (yy + this.height &gt; other.y) &amp;&amp; (yy &lt; other.y + other.height)){
              return true;
          }
          else{
              return false;
          }
      }
  
      function objectAt(xx,yy,solid){
          //Loop All Objects
          for (var i = 0; i &lt; GameObjects.length; i++){
              if (GameObjects[i] != this &amp;&amp; this.isDiv){
                  if (this.checkCollisionAt(xx,yy,GameObjects[i])){
                      console.log(i);
                      return true;
                  }
              }           
          }
          return false;
      }
  
      function objectTypeAt(xx,yy,type){
          //Loop All Objects
          for (var i = 0; i &lt; GameObjects.length; i++){
              if (GameObjects[i] != this &amp;&amp; GameObjects[i].isType(type) &amp;&amp; this.isDiv){
                  if (this.checkCollisionAt(xx,yy,GameObjects[i])){
                      return true;
                  }
              }
          }
          return false;
      }
  
      function toggleActive(a){
          this.visible = a;
          this.update();
          this.active = a;
      }
  
      function update(){      
          if ((this.active == false || this.gameState != gameState) &amp;&amp; this.isDiv){
              this.isDiv = false;
              Game.removeChild(this.div);
              return;
          }
          else if(!this.isDiv){
              this.isDiv = true;
              Game.appendChild(this.div);
          }
  
          this.div.style.display = "inline";
  
          if (this.speed != 0){
              this.x += this.speed*Math.cos(this.direction*Math.PI/180);
              this.y += this.speed*Math.sin(this.direction*Math.PI/180);
          }
  
          if (this.bindToRoom == true){
              if (this.x &lt; 0){
                  this.x = 0;
              }
  
              if (this.y &lt; 0){
                  this.y = 0;
              }
  
              if (this.x &gt; MASTER_WIDTH-this.width){
                  this.x = MASTER_WIDTH-this.width;
              }
  
              if (this.y &gt; MASTER_HEIGHT-this.height){
                  this.y = MASTER_HEIGHT-this.height;
              }
          }
  
          if (!this.visible &amp;&amp; this.isDiv){
              this.isDiv = false;
              Game.removeChild(this.div);
              return;
          }
          if (this.classChanged){
              this.div.className = this.objType;
          }
  
          this.div.style.zIndex = this.depth;
  
          this.div.style.color = this.color;
          this.div.innerHTML = this.text;
  
          this.div.style.left= this.x + "px";
          this.div.style.top= this.y + "px";
  
          this.div.style[getTransformProperty(this.div)] = this.scaleString;
          this.div.style.backgroundPosition = this.currIndex * this.width +"px 0";
  
  
      }
  }
  function getTransformProperty(element) {
  
      // Note that in some versions of IE9 it is critical that
      // msTransform appear in this list before MozTransform
      // By ZachAstronaut
  
      var properties = [
          'transform',
          'WebkitTransform',
          'msTransform',
          'MozTransform',
          'OTransform'
      ];
      var p;
      while (p = properties.shift()) {
          if (typeof element.style[p] != 'undefined') {
              return p;
          }
      }
      return false;
  }
  </code></pre>
  
  <p>Right now, whenever an object is not in the current gameState, becomes inactive, or is not visible, I will remove the div from the game's iframe. I have checks to make sure not to run any unnecessary scripts in the update() function. Is there anyway I can improve my speed?</p>