I'm learning JavaScript and came up with this basic game code structure (using the CreateJS framework):
var stage;
var totalLoaded = 0;
var manifest;
var game = game || {};
game.init = {
load: function () {
var canvas = document.getElementById('gameCanvas');
images = createjs.images || {};
stage = new createjs.Stage(canvas);
manifest = [{
src: "http://i47.tinypic.com/swtj03.png",
id: "circleImg"
}, ]
loader = new createjs.PreloadJS(false);
loader.onFileLoad = game.init.handleFileLoad;
loader.loadManifest(manifest);
game.init.ticker();
game.init.processText();
game.init.interaction();
},
handleFileLoad: function (o) {
if (o.type == "image") {
images[o.id] = o.result = new createjs.Bitmap(o.result);
switch (o.id) {
case "circleImg":
images[o.id].y = 302;
break;
}
game.init.handleLoadComplete();
}
},
handleLoadComplete: function (e) {
totalLoaded++;
if (manifest.length == totalLoaded) {
game.init.handleComplete();
}
},
handleComplete: function () {
game.menu();
},
ticker: function () {
createjs.Ticker.addListener(window);
createjs.Ticker.useRAF = true;
createjs.Ticker.setFPS(60);
},
text: [{
"name": "startText",
"content": "START",
"style": "bold 50px Arial",
"color": "red",
"x": "325",
"y": "140",
"scaleX":"1",
"scaleY":"1"
},
{
"name": "animationComplete",
"content": "ANIMATION COMPLETE",
"style": "bold 50px Arial",
"color": "red",
"x": "125",
"y": "140",
"scaleX":"1",
"scaleY":"1"
},
{
"name": "animationRestart",
"content": "RESTART TO MENU?",
"style": "bold 20px Arial",
"color": "gray",
"x": "125",
"y": "340",
"scaleX":"1",
"scaleY":"1"
}
],
textId: [],
processText: function () {
for (i = 0; i < this.text.length; i++) {
this.textId[i] = new createjs.Text(this.text[i].content, this.text[i].style, this.text[i].color);
this.textId[i].x = this.text[i].x;
this.textId[i].y = this.text[i].y;
this.textId[i].scaleX = this.text[i].scaleX;
this.textId[i].scaleY = this.text[i].scaleY;
this.textId[i].name = this.text[i].name;
}
},
resource: function (e) {
stage.addChild(e);
},
remove: function (e) {
stage.removeChild(e);
},
interaction: function () {
this.textId[0].onClick = handleClick;
this.textId[2].onClick = handleClick;
function handleClick(event) {
switch (event.target.name) {
case "startText":
game.init.remove(game.init.textId[0]);
game.init.resource(images['circleImg']);
game.animation.circle();
break;
case "animationRestart":
game.restart();
break;
}
}
}
}
game.animation = {
circle: function () {
var circleTween = new createjs.Tween.get(images['circleImg'], {
loop: false
}).to({
x: 800
}, 2000, createjs.Ease.quadIn).call(function () {
game.animation.callComplete();
});
},
callComplete: function() {
game.init.resource(game.init.textId[1]);
game.animation.restartText();
},
restartText: function() {
game.init.resource(game.init.textId[2]);
var restartBlink = new createjs.Tween.get(game.init.textId[2], {
loop:true
}).to({
scaleX: 1,
scaleY: 1
}, 500, createjs.Ease.quadOut)
.to({
scaleX: 1.1,
scaleY: 1.1
}, 500, createjs.Ease.quadOut)
.to({
scaleX: 1,
scaleY: 1
}, 500, createjs.Ease.quadOut)
}
}
game.resetPositions = function() {
images['circleImg'].x = 0;
}
game.restart = function () {
stage.removeAllChildren();
game.resetPositions();
game.menu();
}
game.menu = function () {
game.init.resource(game.init.textId[0]);
}
tick = function () {
stage.update();
}
Is this a viable basic game structure? How can I improve game data storage (in this basic case text storage) and naming?
EDIT: added repeat functionality and a dedicated namespace.
1 Answer 1
From a once over:
Object notation does not require the properties to be quoted, you can simply do this:
{ name: "startText", content: "START", style: "bold 50px Arial", color: "red", x: 325, y: 140, scaleX:1, scaleY:1 }
Note that I also removed quotes from the numeric constants, you do not need them.
- I would have named your text array
texts
instead oftext
- There are some variables you are not declaring with
var
:i
,images
, andloader
, this pollutes the global namespace. - It is better to use
images.circleImg
thenimages['circleImg']
. - There is no need capture the results of
new createjs.Tween
intocircleTween
andrestartBlink
since you do nothing with those variables - The magic number
500
,2000
and800
inrestartText
should be capture in a single constant - This :
this.textId[0].onClick = handleClick;
is old skool, please look intoaddEventListener
- I would have made
stage
,totalLoaded
andmanifest
part ofgame
- I would add some error handling to
loader
especially if you are loading an image from a different domain.. - On a final note, the jsfiddle does not work for me, but then again, this a 2012 question ;)