So, recently, I've been working on a JS/HTML5 Game Engine. Right now I'm calling it DimSumJs, because like DimSum isn't a full meal, my framework still runs too slowly to make a full game (it can only run about 400 "objects" despite before slowing down, it becomes very noticeable around 500 "objects"). It uses divs inside an iframe. Any advice is welcome! Please don't tell me to use a already made game engine, this is sort of a project of mine and i want to actually finish it.(Moved to Code Review as suggested)
just view resources with google chrome and you should be able to find the dimsum.js file
HERE IS THE 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;
var GameWindow = window.frames[0];
var gl = setInterval("gameLoop();",15);
//Global Vars
var keyDown = new Array();
for (var i = 0; i < 256; i++){
keyDown[i] = false;
}
var gameState = 0;
//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 >= this.increment){
this.currInc -= this.increment;
this.currIndex += 1;
if (this.currIndex >= 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 + ' ') > -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 > other.x) && (xx < other.x + other.width) && (yy + this.height > other.y) && (yy < other.y + other.height)){
return true;
}
else{
return false;
}
}
function objectAt(xx,yy,solid){
//Loop All Objects
for (var i = 0; i < GameObjects.length; i++){
if (GameObjects[i] != this && 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 < GameObjects.length; i++){
if (GameObjects[i] != this && GameObjects[i].isType(type) && 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) && 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 < 0){
this.x = 0;
}
if (this.y < 0){
this.y = 0;
}
if (this.x > MASTER_WIDTH-this.width){
this.x = MASTER_WIDTH-this.width;
}
if (this.y > MASTER_HEIGHT-this.height){
this.y = MASTER_HEIGHT-this.height;
}
}
if (!this.visible && 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;
}