Welcome back to my HTML5 game programming series. In this part of the tutorial we are going to finish our first HTML5 game for Windows 8.
Note: This tutorial was written on the plane to Las Vegas, will fix typos at a later time.
If you havent completed my previous tutorials, now is the time 🙂
Anyhow. Last time we were left of with a playfield where you could move the hero around the screen, a main menu where you had to tap the screen to start the game, but no enemies. This is what we are going to implement today.
First of all, we need a few global variables for the ghost.
1: var ghosts = [];
2: var ghostSpeed = 1.0;
The first variable is an array including all the ghosts thats currently alive, and the 2nd one is the speed the ghosts will have when moving towards you.
We also need a global variable for the image and the bitmap of the ghost:
var ghostImage, ghostBitmap;
Next, we need a class for the ghost:
1: function Ghost(gfx) {
2: this.positionX = Math.random() * 5000 - 2500;
3: this.positionY = Math.random() * 3000 - 1500;
4:
5: this.setStartPosition = function () {
6: if (this.positionX >= 0 && this.positionX <= window.innerWidth) {
7: this.positionX = -500;
8: }
9:
10: if (this.positionY >= 0 && this.positionY <= window.innerHeight) {
11: this.positionY = -500;
12: }
13: }
14:
15: this.targetX = 0;
16: this.targetY = 0;
17:
18: this.move = function (tX, tY) {
19: this.targetX = tX;
20: this.targetY = tY;
21:
22: if (this.targetX > this.positionX) {
23: this.positionX += ghostSpeed;
24: }
25: if (this.targetX < this.positionX) {
26: this.positionX -= ghostSpeed;
27: }
28: if (this.targetY > this.positionY) {
29: this.positionY += ghostSpeed;
30: }
31: if (this.targetY < this.positionY) {
32: this.positionY -= ghostSpeed;
33: }
34: };
35:
36: this.isCollision = function (playerX, playerY, playerW, playerH) {
37: var centerX = this.positionX + (this.ghostBitmap.image.width * scaleW / 2);
38: var centerY = this.positionY + (this.ghostBitmap.image.height * scaleH / 2);
39:
40: if ((centerX >= playerX - playerW / 2) && (centerX < playerX + playerW / 2)) {
41: if ((centerY >= playerY - playerH / 2) && (centerY < playerY + playerH / 2)) {
42: return true;
43: }
44: }
45:
46: return false;
47: }
48:
49: this.ghostBitmap = gfx;
50: }
51:
This class looks a bit like the player class – it got a variable for the current position of one ghost and the target. But this class also contains a function that moved the ghost towards the target, and a function that checks if the ghost is colliding with the player sprite.
The position of a new ghost will be randomly selected – but if it spawns in the middle of the playscreen, we move it outside so he wont spawn on top of the player making it impossible to avoid it. All ghosts must spawn outside the playfield, and move towards the player at all time.
Now, we load the image for the ghost like we did with the player in loadContent() – but we only load the image from the preload object:
1: ghostImage = preload.getResult("ghost").result
Spawning a ghost
We will use a timer to spawn a ghost, so go ahead and create a new global variable that will contain the spawntime untill a new ghost is spawned:
var timeToAddNewGhost = 0;
In the update loop, just below the code that moves the player towards the target, we add the code that will add a new ghost to the ghosts array:
1: timeToAddNewGhost -= 1;
2: if (timeToAddNewGhost < 0) {
3: timeToAddNewGhost = 1000
4: ghosts.push(new Ghost(new createjs.Bitmap(ghostImage)));
5: ghosts[ghosts.length - 1].setStartPosition();
6: gameStage.addChild(ghosts[ghosts.length - 1].ghostBitmap);
7: }
Every frame, we subtract one from the timeToAddNewGhost variable. If this is below 0, we set the timer to 1000 and add a new ghost to the array using the ghostImage we loaded earlier. We also make sure that the start position isn’t on the visible playfield.
For every 1000 frame, a new ghost is spawned and the game gets a bit harder. But an array wont do us much good without updating the position of the image file (or else the ghost will be invisible). So for each active ghost in the array, we set the image position, move the ghost towards the player and check for collision:
1: for (var i = 0; i < ghosts.length; i++)
2: {
3: ghosts[i].ghostBitmap.x = ghosts[i].positionX;
4: ghosts[i].ghostBitmap.y = ghosts[i].positionY;
5: ghosts[i].ghostBitmap.visible = true;
6: ghosts[i].move(player.positionX, player.positionY);
7: ghosts[i].isCollision(player.positionX, player.positionY, player.width, player.height);
8: }
Just to make sure you got everything right, below is a listing of the entire source this far:
1: // For an introduction to the Blank template, see the following documentation:
2: // http://go.microsoft.com/fwlink/?LinkId=232509
3: (function () {
4: "use strict";
5:
6: WinJS.Binding.optimizeBindingReferences = true;
7:
8: var app = WinJS.Application;
9: var activation = Windows.ApplicationModel.Activation;
10:
11: var canvas, context;
12: var gameStage;
13: var preload;
14:
15: var logoScreenImage, logoScreenBitmap;
16: var floorImage, floorBitmap;
17: var playerIdleImage, playerIdleBitmap;
18: var ghostImage, ghostBitmap;
19:
20: var newGame = true;
21:
22: var player;
23:
24: var ghosts = [];
25: var ghostSpeed = 1.0;
26: var timeToAddNewGhost = 0;
27:
28: var scaleW = window.innerWidth / 1366;
29: var scaleH = window.innerHeight / 768;
30:
31:
32: app.onactivated = function (args) {
33: if (args.detail.kind === activation.ActivationKind.launch) {
34: if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
35: // TODO: This application has been newly launched. Initialize
36: // your application here.
37: } else {
38: // TODO: This application has been reactivated from suspension.
39: // Restore application state here.
40: }
41: args.setPromise(WinJS.UI.processAll());
42: }
43: };
44:
45: // The player class
46: function Player() {
47: this.positionX = window.innerWidth / 2;
48: this.positionY = window.innerHeight / 2;
49:
50: this.targetX = this.positionX;
51: this.targetY = this.positionY;
52:
53: this.width = playerIdleBitmap.image.width * scaleW;
54: this.height = playerIdleBitmap.image.height * scaleH;
55: }
56:
57: // The ghost class
58: function Ghost(gfx) {
59: this.positionX = Math.random() * 5000 - 2500;
60: this.positionY = Math.random() * 3000 - 1500;
61:
62: this.setStartPosition = function () {
63: if (this.positionX >= 0 && this.positionX <= window.innerWidth) {
64: this.positionX = -500;
65: }
66:
67: if (this.positionY >= 0 && this.positionY <= window.innerHeight) {
68: this.positionY = -500;
69: }
70: }
71:
72: this.targetX = 0;
73: this.targetY = 0;
74:
75: this.move = function (tX, tY) {
76: this.targetX = tX;
77: this.targetY = tY;
78:
79: if (this.targetX > this.positionX) {
80: this.positionX += ghostSpeed;
81: }
82: if (this.targetX < this.positionX) {
83: this.positionX -= ghostSpeed;
84: }
85: if (this.targetY > this.positionY) {
86: this.positionY += ghostSpeed;
87: }
88: if (this.targetY < this.positionY) {
89: this.positionY -= ghostSpeed;
90: }
91: };
92:
93: this.isCollision = function (playerX, playerY, playerW, playerH) {
94: var centerX = this.positionX + (this.ghostBitmap.image.width * scaleW / 2);
95: var centerY = this.positionY + (this.ghostBitmap.image.height * scaleH / 2);
96:
97: if ((centerX >= playerX - playerW / 2) && (centerX < playerX + playerW / 2)) {
98: if ((centerY >= playerY - playerH / 2) && (centerY < playerY + playerH / 2)) {
99: return true;
100: }
101: }
102:
103: return false;
104: }
105:
106: this.ghostBitmap = gfx;
107: }
108:
109:
110: function pointerUp(event) {
111: if (newGame) {
112: newGame = false;
113: }
114: else {
115: player.targetX = event.x;
116: player.targetY = event.y;
117: }
118: }
119:
120: function pointerDown(event) {
121: if (newGame) {
122: }
123: else {
124: player.targetX = event.x;
125: player.targetY = event.y;
126: }
127: }
128:
129: function pointerMove(event) {
130: if (newGame) {
131: }
132: else {
133: player.targetX = event.x;
134: player.targetY = event.y;
135: }
136: }
137:
138: function initialize() {
139: canvas = document.getElementById("gameCanvas");
140: canvas.width = window.innerWidth;
141: canvas.height = window.innerHeight;
142: context = canvas.getContext("2d");
143:
144: canvas.addEventListener("MSPointerUp", pointerUp, false);
145: canvas.addEventListener("MSPointerMove", pointerMove, false);
146: canvas.addEventListener("MSPointerDown", pointerDown, false);
147:
148: gameStage = new createjs.Stage(canvas);
149:
150: loadContent();
151: }
152:
153: function loadContent() {
154: preload = new createjs.PreloadJS();
155: preload.onComplete = prepareStage;
156:
157: var manifest = [
158: { id: "logoScreen", src: "images/GFX/LogoScreen.png" },
159: { id: "floor", src: "images/GFX/floor.png" },
160: { id: "ghost", src: "images/GFX/Ghost.png" },
161: { id: "playerIdle", src: "images/GFX/PlayerIdle.png" }
162: ];
163:
164: preload.loadManifest(manifest);
165: }
166:
167: function prepareStage() {
168: logoScreenImage = preload.getResult("logoScreen").result;
169: logoScreenBitmap = new createjs.Bitmap(logoScreenImage);
170: logoScreenBitmap.scaleX = scaleW;
171: logoScreenBitmap.scaleY = scaleH;
172: gameStage.addChild(logoScreenBitmap);
173:
174: floorImage = preload.getResult("floor").result;
175: floorBitmap = new createjs.Bitmap(floorImage);
176: floorBitmap.visible = false;
177: floorBitmap.scaleX = scaleW;
178: floorBitmap.scaleY = scaleH;
179: gameStage.addChild(floorBitmap);
180:
181: playerIdleImage = preload.getResult("playerIdle").result;
182: playerIdleBitmap = new createjs.Bitmap(playerIdleImage);
183: playerIdleBitmap.visible = false;
184: playerIdleBitmap.scaleX = scaleW;
185: playerIdleBitmap.scaleY = scaleH;
186: gameStage.addChild(playerIdleBitmap);
187:
188: ghostImage = preload.getResult("ghost").result
189:
190: player = new Player();
191:
192: createjs.Ticker.setInterval(window.requestAnimationFrame);
193: createjs.Ticker.addListener(gameLoop);
194: }
195:
196: function gameLoop() {
197: update();
198: draw();
199: }
200:
201: function update() {
202: if (newGame) {
203: logoScreenBitmap.visible = true;
204: playerIdleBitmap.visible = false;
205: floorBitmap.visible = false;
206: }
207: else {
208: logoScreenBitmap.visible = false;
209: playerIdleBitmap.visible = true;
210: floorBitmap.visible = true;
211:
212: if (player.targetX > player.positionX) {
213: player.positionX += 3;
214: }
215: if (player.targetX < player.positionX) {
216: player.positionX -= 3;
217: }
218: if (player.targetY > player.positionY) {
219: player.positionY += 3;
220: }
221: if (player.targetY < player.positionY) {
222: player.positionY -= 3;
223: }
224:
225: timeToAddNewGhost -= 1;
226: if (timeToAddNewGhost < 0) {
227: timeToAddNewGhost = 1000
228: ghosts.push(new Ghost(new createjs.Bitmap(ghostImage)));
229: ghosts[ghosts.length - 1].setStartPosition();
230: gameStage.addChild(ghosts[ghosts.length - 1].ghostBitmap);
231: }
232:
233: for (var i = 0; i < ghosts.length; i++) {
234: ghosts[i].ghostBitmap.x = ghosts[i].positionX;
235: ghosts[i].ghostBitmap.y = ghosts[i].positionY;
236: ghosts[i].ghostBitmap.visible = true;
237: ghosts[i].move(player.positionX, player.positionY);
238: ghosts[i].isCollision(player.positionX, player.positionY, player.width, player.height);
239: }
240:
241: playerIdleBitmap.x = player.positionX - (player.width / 2);
242: playerIdleBitmap.y = player.positionY - (player.height / 2);
243: }
244: }
245:
246: function draw() {
247: gameStage.update();
248: }
249:
250: app.oncheckpoint = function (args) {
251: // TODO: This application is about to be suspended. Save any state
252: // that needs to persist across suspensions here. You might use the
253: // WinJS.Application.sessionState object, which is automatically
254: // saved and restored across suspension. If you need to complete an
255: // asynchronous operation before your application is suspended, call
256: // args.setPromise().
257: };
258:
259: document.addEventListener("DOMContentLoaded", initialize, false);
260:
261: app.start();
262: })();
263:
264:
265:
If you run the game now, the game will start, you can move around and more and more ghosts will try to attack you.
Implementing Game Over
The ghosts aren’t really dangerous right now, if the ghost hit you – nothing happens. Yes, we are checking for collision, but haven’t yet created any rules that will happen when the collision is true.
To do this we need to define a new global variable:
1: var isGameOver = false;
In the loop where we go through each of the ghosts, replace this line:
ghosts[i].isCollision(player.positionX, player.positionY, player.width, player.height);
with this:
1: isGameOver = ghosts[i].isCollision(player.positionX, player.positionY, player.width, player.height);
Also, add this code below so when a collision is happening, we break the for-loop:
1: if (isGameOver)
2: break;
In the top of the update() function, inside the else statement of if(newGame), add the following code:
1: if (isGameOver) {
2: isGameOver = false;
3: ghosts.length = 0;
4: gameStage.clear();
5:
6: gameStage.addChild(logoScreenBitmap);
7: gameStage.addChild(floorBitmap);
8: gameStage.addChild(playerIdleBitmap);
9: gameStage.addChild(scoreText);
10:
11: gameStage.update();
12: }
13:
Just to make sure you are in thr right place, the update function looks like this:
1: function update() {
2: if (newGame) {
3: logoScreenBitmap.visible = true;
4: playerIdleBitmap.visible = false;
5: floorBitmap.visible = false;
6: }
7: else {
8: if (isGameOver) {
9: isGameOver = false;
10: ghosts.length = 0;
11: gameStage.clear();
12:
13: gameStage.addChild(logoScreenBitmap);
14: gameStage.addChild(floorBitmap);
15: gameStage.addChild(playerIdleBitmap);
16:
17: gameStage.update();
18: }
19: logoScreenBitmap.visible = false;
20: playerIdleBitmap.visible = true;
21: floorBitmap.visible = true;
22:
23: if (player.targetX > player.positionX) {
24: player.positionX += 3;
25: }
26: if (player.targetX < player.positionX) {
27: player.positionX -= 3;
28: }
29: if (player.targetY > player.positionY) {
30: player.positionY += 3;
31: }
32: if (player.targetY < player.positionY) {
33: player.positionY -= 3;
34: }
35:
36: timeToAddNewGhost -= 1;
37: if (timeToAddNewGhost < 0) {
38: timeToAddNewGhost = 1000
39: ghosts.push(new Ghost(new createjs.Bitmap(ghostImage)));
40: ghosts[ghosts.length - 1].setStartPosition();
41: gameStage.addChild(ghosts[ghosts.length - 1].ghostBitmap);
42: }
43:
44: for (var i = 0; i < ghosts.length; i++) {
45: ghosts[i].ghostBitmap.x = ghosts[i].positionX;
46: ghosts[i].ghostBitmap.y = ghosts[i].positionY;
47: ghosts[i].ghostBitmap.visible = true;
48: ghosts[i].move(player.positionX, player.positionY);
49: isGameOver = ghosts[i].isCollision(player.positionX, player.positionY, player.width, player.height);
50: if (isGameOver)
51: break;
52: }
53:
54: playerIdleBitmap.x = player.positionX - (player.width / 2);
55: playerIdleBitmap.y = player.positionY - (player.height / 2);
56: }
57: }
58:
What we do in this code is to check if it’s game over. If this is true (a collision is happened), we set the gameOver flag to false again, clear all the active ghosts in the array and remove everything from the gameState (because its filled with ghosts). We then add back the logoScreen, the floor and the player and restart the game.
If you run the game again, you can see that we have a working game! 🙂
Adding a score
But, something is missing – a score!
The longer you stay alive, the more score you will get.
To add a score, define a new global variable called playerScore and a a new global variable called scoreText:
1: var scoreText;
2: var playerScore = 0;
scoreText will contain the font and position of the text.
In the game over “routine”, add a line that sets the playerScore to 0 – when it’s game over, we want to reset the score:
1: playerScore = 0;
Back in loadContent(): We create a new font object using CreateJS containing the text we want to display, the position (we want it to be on the top center of the screen) and add it to the gameStage:
1: scoreText = new createjs.Text("Score: " + playerScore, "30px sans-serif", "yellow");
2: scoreText.x = canvas.width / 2 - (scoreText.getMeasuredWidth() * scaleW / 2);
3: scoreText.scaleX = scaleW;
4: scoreText.scaleY = scaleH;
5: scoreText.y = 30 * scaleH;
6: scoreText.visible = false;
7: gameStage.addChild(scoreText);
The function getMeasuredWidth() simply returns how wide the string that we want to render is – making it simple to calculate where to render it based on how long the text is.
Back again to the gameOver rules: Add a new line that adds the scoreText object back to the stage:
1: gameStage.addChild(scoreText);
Still in the update() function, just below the code that moves the player – add these two lines of code:
1: playerScore += 1;
2: scoreText.text = ("Score: " + playerScore);
This increases the score for each frame and updates the text in scoreText.
We also must make sure that the score text is visible or invisible based on if we are in game or not.
And thats it, we got a working game! If something isn’t working, you can check your solution with the code below, it contains all the code for the game:
1: // For an introduction to the Blank template, see the following documentation:
2: // http://go.microsoft.com/fwlink/?LinkId=232509
3: (function () {
4: "use strict";
5:
6: WinJS.Binding.optimizeBindingReferences = true;
7:
8: var app = WinJS.Application;
9: var activation = Windows.ApplicationModel.Activation;
10:
11: var canvas, context;
12: var gameStage;
13: var preload;
14:
15: var logoScreenImage, logoScreenBitmap;
16: var floorImage, floorBitmap;
17: var playerIdleImage, playerIdleBitmap;
18: var ghostImage, ghostBitmap;
19:
20: var newGame = true;
21: var isGameOver = false;
22:
23: var player;
24:
25: var scoreText;
26: var playerScore = 0;
27:
28: var ghosts = [];
29: var ghostSpeed = 1.0;
30: var timeToAddNewGhost = 0;
31:
32: var scaleW = window.innerWidth / 1366;
33: var scaleH = window.innerHeight / 768;
34:
35:
36: app.onactivated = function (args) {
37: if (args.detail.kind === activation.ActivationKind.launch) {
38: if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
39: // TODO: This application has been newly launched. Initialize
40: // your application here.
41: } else {
42: // TODO: This application has been reactivated from suspension.
43: // Restore application state here.
44: }
45: args.setPromise(WinJS.UI.processAll());
46: }
47: };
48:
49: // The player class
50: function Player() {
51: this.positionX = window.innerWidth / 2;
52: this.positionY = window.innerHeight / 2;
53:
54: this.targetX = this.positionX;
55: this.targetY = this.positionY;
56:
57: this.width = playerIdleBitmap.image.width * scaleW;
58: this.height = playerIdleBitmap.image.height * scaleH;
59: }
60:
61: // The ghost class
62: function Ghost(gfx) {
63: this.positionX = Math.random() * 5000 - 2500;
64: this.positionY = Math.random() * 3000 - 1500;
65:
66: this.setStartPosition = function () {
67: if (this.positionX >= 0 && this.positionX <= window.innerWidth) {
68: this.positionX = -500;
69: }
70:
71: if (this.positionY >= 0 && this.positionY <= window.innerHeight) {
72: this.positionY = -500;
73: }
74: }
75:
76: this.targetX = 0;
77: this.targetY = 0;
78:
79: this.move = function (tX, tY) {
80: this.targetX = tX;
81: this.targetY = tY;
82:
83: if (this.targetX > this.positionX) {
84: this.positionX += ghostSpeed;
85: }
86: if (this.targetX < this.positionX) {
87: this.positionX -= ghostSpeed;
88: }
89: if (this.targetY > this.positionY) {
90: this.positionY += ghostSpeed;
91: }
92: if (this.targetY < this.positionY) {
93: this.positionY -= ghostSpeed;
94: }
95: };
96:
97: this.isCollision = function (playerX, playerY, playerW, playerH) {
98: var centerX = this.positionX + (this.ghostBitmap.image.width * scaleW / 2);
99: var centerY = this.positionY + (this.ghostBitmap.image.height * scaleH / 2);
100:
101: if ((centerX >= playerX - playerW / 2) && (centerX < playerX + playerW / 2)) {
102: if ((centerY >= playerY - playerH / 2) && (centerY < playerY + playerH / 2)) {
103: return true;
104: }
105: }
106:
107: return false;
108: }
109:
110: this.ghostBitmap = gfx;
111: }
112:
113:
114: function pointerUp(event) {
115: if (newGame) {
116: newGame = false;
117: }
118: else {
119: player.targetX = event.x;
120: player.targetY = event.y;
121: }
122: }
123:
124: function pointerDown(event) {
125: if (newGame) {
126: }
127: else {
128: player.targetX = event.x;
129: player.targetY = event.y;
130: }
131: }
132:
133: function pointerMove(event) {
134: if (newGame) {
135: }
136: else {
137: player.targetX = event.x;
138: player.targetY = event.y;
139: }
140: }
141:
142: function initialize() {
143: canvas = document.getElementById("gameCanvas");
144: canvas.width = window.innerWidth;
145: canvas.height = window.innerHeight;
146: context = canvas.getContext("2d");
147:
148: canvas.addEventListener("MSPointerUp", pointerUp, false);
149: canvas.addEventListener("MSPointerMove", pointerMove, false);
150: canvas.addEventListener("MSPointerDown", pointerDown, false);
151:
152: gameStage = new createjs.Stage(canvas);
153:
154: loadContent();
155: }
156:
157: function loadContent() {
158: preload = new createjs.PreloadJS();
159: preload.onComplete = prepareStage;
160:
161: var manifest = [
162: { id: "logoScreen", src: "images/GFX/LogoScreen.png" },
163: { id: "floor", src: "images/GFX/floor.png" },
164: { id: "ghost", src: "images/GFX/Ghost.png" },
165: { id: "playerIdle", src: "images/GFX/PlayerIdle.png" }
166: ];
167:
168: preload.loadManifest(manifest);
169: }
170:
171: function prepareStage() {
172: logoScreenImage = preload.getResult("logoScreen").result;
173: logoScreenBitmap = new createjs.Bitmap(logoScreenImage);
174: logoScreenBitmap.scaleX = scaleW;
175: logoScreenBitmap.scaleY = scaleH;
176: gameStage.addChild(logoScreenBitmap);
177:
178: floorImage = preload.getResult("floor").result;
179: floorBitmap = new createjs.Bitmap(floorImage);
180: floorBitmap.visible = false;
181: floorBitmap.scaleX = scaleW;
182: floorBitmap.scaleY = scaleH;
183: gameStage.addChild(floorBitmap);
184:
185: playerIdleImage = preload.getResult("playerIdle").result;
186: playerIdleBitmap = new createjs.Bitmap(playerIdleImage);
187: playerIdleBitmap.visible = false;
188: playerIdleBitmap.scaleX = scaleW;
189: playerIdleBitmap.scaleY = scaleH;
190: gameStage.addChild(playerIdleBitmap);
191:
192: scoreText = new createjs.Text("Score: " + playerScore, "30px sans-serif", "yellow");
193: scoreText.x = canvas.width / 2 - (scoreText.getMeasuredWidth() * scaleW / 2);
194: scoreText.scaleX = scaleW;
195: scoreText.scaleY = scaleH;
196: scoreText.y = 30 * scaleH;
197: scoreText.visible = false;
198: gameStage.addChild(scoreText);
199:
200:
201: ghostImage = preload.getResult("ghost").result
202:
203: player = new Player();
204:
205: createjs.Ticker.setInterval(window.requestAnimationFrame);
206: createjs.Ticker.addListener(gameLoop);
207: }
208:
209: function gameLoop() {
210: update();
211: draw();
212: }
213:
214: function update() {
215: if (newGame) {
216: logoScreenBitmap.visible = true;
217: playerIdleBitmap.visible = false;
218: floorBitmap.visible = false;
219: scoreText.visible = false;
220: }
221: else {
222: if (isGameOver) {
223: isGameOver = false;
224: ghosts.length = 0;
225: playerScore = 0;
226: gameStage.clear();
227:
228: gameStage.addChild(logoScreenBitmap);
229: gameStage.addChild(floorBitmap);
230: gameStage.addChild(playerIdleBitmap);
231: gameStage.addChild(scoreText);
232:
233: gameStage.update();
234: }
235: logoScreenBitmap.visible = false;
236: playerIdleBitmap.visible = true;
237: floorBitmap.visible = true;
238: scoreText.visible = true;
239:
240: if (player.targetX > player.positionX) {
241: player.positionX += 3;
242: }
243: if (player.targetX < player.positionX) {
244: player.positionX -= 3;
245: }
246: if (player.targetY > player.positionY) {
247: player.positionY += 3;
248: }
249: if (player.targetY < player.positionY) {
250: player.positionY -= 3;
251: }
252:
253: playerScore += 1;
254: scoreText.text = ("Score: " + playerScore);
255:
256: timeToAddNewGhost -= 1;
257: if (timeToAddNewGhost < 0) {
258: timeToAddNewGhost = 1000
259: ghosts.push(new Ghost(new createjs.Bitmap(ghostImage)));
260: ghosts[ghosts.length - 1].setStartPosition();
261: gameStage.addChild(ghosts[ghosts.length - 1].ghostBitmap);
262: }
263:
264: for (var i = 0; i < ghosts.length; i++) {
265: ghosts[i].ghostBitmap.x = ghosts[i].positionX;
266: ghosts[i].ghostBitmap.y = ghosts[i].positionY;
267: ghosts[i].ghostBitmap.visible = true;
268: ghosts[i].move(player.positionX, player.positionY);
269: isGameOver = ghosts[i].isCollision(player.positionX, player.positionY, player.width, player.height);
270: if (isGameOver)
271: break;
272: }
273:
274: playerIdleBitmap.x = player.positionX - (player.width / 2);
275: playerIdleBitmap.y = player.positionY - (player.height / 2);
276: }
277: }
278:
279: function draw() {
280: gameStage.update();
281: }
282:
283: app.oncheckpoint = function (args) {
284: // TODO: This application is about to be suspended. Save any state
285: // that needs to persist across suspensions here. You might use the
286: // WinJS.Application.sessionState object, which is automatically
287: // saved and restored across suspension. If you need to complete an
288: // asynchronous operation before your application is suspended, call
289: // args.setPromise().
290: };
291:
292: document.addEventListener("DOMContentLoaded", initialize, false);
293:
294: app.start();
295: })();
296:
Thanks for following! In the next tutorial, we are going to look at other important aspects of game programming on Windows 8 like storeing data and so on.
Download the source of the game here:
http://sdrv.ms/T2KTFg
Hi, thanks for this great tutorial! can I reuse your code for a similar game?
Yes, feel free to use the code. 🙂
Wow thanks so much! 🙂
Pingback: HTML5 Game Starter Kit for Windows 8 | digitalerr0r
thanks man great tutorial
Pingback: Windows 8 Games with CreateJS Tutorials & Resources « skater coder
Great tutorial. Thanks a lot. 🙂
I plan to navigate to different page instead of hide/show an image.
However i encounter an error when navigate. It said:
Unhandled exception at line 81, column 326 in ms-appx://4c985e5d-0546-41d7-9f24-e945d98a9232/js/CreateJS/easeljs-0.5.0.min.js
0x80004005 – JavaScript runtime error: Unspecified error.
What should i put as the second parameter(initial state) of WinJS.Navigation.navigate()?
Pingback: Game Starterkit for Windows 8 with leaderboard in Windows Azure | digitalerr0r
Pingback: You can lead a dev to... "Game Starter Kit for Windows 8 with leaderboard in Windows Azure" - Windows Azure Blog
am getting the following error
157: preload = new createjs.PreloadJS();
158: preload.onComplete = prepareStage;
“Unhandled exception at line 157, column 18 in ms-appx://e873b1a2-9c7e-4668-8426-b5cba485e4ef/js/default.js
0x800a01bd – JavaScript runtime error: Object doesn’t support this action
If there is a handler for this exception, the program may be safely continued.”