I am creating a simple 2D canvas game engine in JavaScript. Are there any optimizations that I could make, or obvious issues (performance, semantics or otherwise) that you can see?
var GameCanvas = {
// GameCanvas Variables
animation: {
requestAnimationFrame: null,
halt: false
},
canvas: {
element: null,
context: null,
width: 500,
height: 500,
backgroundColor: '#000000'
},
objects: [
],
baseObject: function(){
return {
// Custom internal name of object (Mostly for debugging)
name: '',
position: {
width: 0,
height: 0,
x: 0,
y: 0
},
// Any custom data for this object
data: {
},
// the draw method
draw: function(GameCanvas){
},
criticalObj: true
};
},
addObject: function(obj){
this.objects.unshift(obj);
},
init: function(CanvasID){
// Get Canvas by ID
this.canvas.element = document.getElementById(CanvasID);
if(this.canvas.element===null){
this.console.error("No valid canvas with ID \""+CanvasID+"\" found.");
return false;
}
// Get Canvas dimensions
this.canvas.width = this.canvas.element.width || this.canvas.width;
this.canvas.height = this.canvas.element.height || this.canvas.height;
// Get the context
this.canvas.context = this.canvas.element.getContext('2d');
if(this.canvas.context===null){
this.console.error("Failed to get context.");
return false;
}
// Setup Request Animation Frame
// RequestAnimationFrame Shim
this.animation.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function(callback){
//hack for RequestAnimationFrame not being there
this.console.log('No support for RequestAnimationFrame.');
window.setTimeout(callback, 1000 / 60);
};
})();
this.console.log("Initialized Successfully.");
return true;
},
console: {
data: '',
// Allows for custom error output
error: function(data){
if(console.error!==undefined){
console.error('GameCanvas: '+String(data));
}
this.data += data+"\n";
},
log: function(data){
if(console.log!==undefined){
console.log('GameCanvas: '+String(data));
}
this.data += data+"\n";
}
},
run:function(){
this.console.log("Starting mainLoop().");
this.mainLoop();
},
mainLoop: function(){
// Fill Background
this.canvas.context.fillStyle = this.canvas.backgroundColor;
this.canvas.context.fillRect(0,0,this.canvas.width,this.canvas.height);
//Loop through objects
for(var obj in this.objects){
try{
this.objects[obj].draw(this);
}
catch(err){
this.console.log("Object "+this.objects[obj].name+":"+obj+" throws error:\n"+err);
if(this.objects[obj].criticalObj){
this.console.error("Critical Object "+this.objects[obj].name+":"+obj+" not drawn. Halting mainLoop().");
this.animation.halt = true;
}
}
}
// Looping call
if(!this.animation.halt){
this.animation.requestAnimationFrame.call(
window, // Call function in context of window
// Call the mainLoop() function in the context of the current object
this.mainLoop.bind(this)
);
}
else{
this.console.log("mainLoop() halted.");
this.animation.halt = false;
}
}
};
GameCanvas.init("canvas");
var box = GameCanvas.baseObject();
box.name = "Box";
box.draw = function(GameCanvas){
GameCanvas.canvas.context.fillStyle = "#00FF00";
GameCanvas.canvas.context.fillRect(this.position.x,this.position.y,this.position.width,this.position.height);
};
box.position.width = 50;
box.position.height = 50;
box.position.x = 10;
box.position.y = 10;
GameCanvas.addObject(box);
GameCanvas.run();
-
1\$\begingroup\$ Some optimization would be to stop using double quotes and just use single quotes. It looks a bit weird when you use double quotes and sometimes single quotes. The reasoning is that when you use javascript with html that has attributes normally they will use double quotes so you don't need to escape them. Another thing i would do is when you construct a string together with + you should add some space before and after the + it will just look easier to read. The same goes for things like console.error!==undefined Add some space between !== \$\endgroup\$Marcio– Marcio2015年06月19日 02:30:22 +00:00Commented Jun 19, 2015 at 2:30
1 Answer 1
You have some weird spacing in places, like empty arrays and functions. For example, the below block of code, can be changed to objects: []
.
objects: [ ]
The same also applies to empty functions, like this:
draw: function(GameCanvas){ }
Quite a bit of your indentation as well is inconsistent. For example, the below block of code, and ones like it with inconsistent indentation:
function(callback){ //hack for RequestAnimationFrame not being there this.console.log('No support for RequestAnimationFrame.'); window.setTimeout(callback, 1000 / 60); }
Should be changed to a more consistent style, like this:
function(callback){
//hack for RequestAnimationFrame not being there
this.console.log('No support for RequestAnimationFrame.');
window.setTimeout(callback, 1000 / 60);
}
I'd personally recommend either four spaces, or one tab for indentation in Javascript.
In the line this.console.log("Object "+this.objects[obj].name+":"+obj+" throws error:\n"+err);
, you prefix console.log
with this
. In this situation, this
isn't needed, and can be removed.
Finally, you have many other style violations, so I'd recommend checking out a style guide, like this one for reference on how to properly style code.