Monaca Docs
Search…
Break the Bricks
This is a sample game based on pixi.js which is a super fast HTML5 2D rendering engine that uses webGL with canvas fallback. For more information about Pixi, please refer to here. In the game, player controlls a paddle to prevent a ball from falling while trying to clear the bricks. The objective of the game is to clear all the bricks.

Demo

Tested Environment
  • Android 11.0
  • iOS 14.3

File Components

File
Description
index.html
The Startup page (Home page)
js/main.js
A JavaScript file handling various implementation in the application
css/style.css
Style Sheet for the whole application
img/*.png
All image files needed to use this template
res/VT323-Regular.ttf
A true type font

Required JS/CSS Components

  • Pixi

Source Code Explanation

js/main.js

main.js is a JavaScript file handling various functionalities of the application.
Below is the code of BB object which is the main object of this application. Its properties are screensize, paddle, balls, blocks, score and so on. Its methods are creating block map (setMap()), creating a ball (addBall()), creating a paddle (addPaddle()), resetting the game after it ended (reset()), calculating the score (addScore()), ending the game (endGame()) and so on.
1
...
2
var BB = {
3
stage: new PIXI.Stage(0x000000),
4
renderer: null,
5
screenSize: null,
6
paddle: null,
7
balls: [],
8
blocks: [],
9
score: 0,
10
scoreLabel: null,
11
accelLabel: null,
12
isMouseDown: false,
13
14
// Create blocks map
15
setMap: function() {
16
var blockMap = [
17
[null, null, null, null, null, 'blue', null, null, null, null],
18
[null, null, null, null, 'red', 'red', 'blue', null, null, null],
19
[null, null, null, 'red', 'red', null, null, 'blue', null, null],
20
[null, null, 'red', 'red', null, null, null, null, 'blue', null],
21
[null, 'red', 'red', null, null, 'gold', null, null, 'silver', 'silver'],
22
[null, null, 'red', 'red', null, null, null, 'silver', 'silver', null],
23
[null, null, null, 'red', 'red', null, 'silver', 'silver', null, null],
24
[null, null, null, null, 'silver', 'silver', 'silver', null, null, null],
25
[null, null, null, null, null, 'silver', null, null, null, null]
26
];
27
28
for(j = 0; j < blockMap.length; j++) {
29
for(i = 0; i < blockMap[j].length; i++) {
30
if(blockMap[j][i] !== null) {
31
var block = BB.addBlock(10 + (30 * i), 80 + (12 * j), blockMap[j][i]);
32
}
33
}
34
}
35
},
36
37
/**
38
* @param {int} x
39
* @param {int} y
40
* @param {String} color red,blue,silver,gold
41
* @return {Object} block
42
**/
43
addBlock: function(x, y, color) {
44
switch (color) {
45
case "red":
46
case "blue":
47
var point = SETTINGS_POINT;
48
break;
49
case "silver":
50
var point = SETTINGS_POINT_SILVER;
51
break;
52
case "gold":
53
var point = SETTINGS_POINT_GOLD;
54
break;
55
default:
56
var point = SETTINGS_POINT;
57
color = "red";
58
break;
59
}
60
61
var texture = PIXI.Texture.fromImage(imgPath["block_" + color], false);
62
var block = new PIXI.Sprite(texture);
63
64
block.anchor.x = 0.5;
65
block.anchor.y = 0.5;
66
67
block.position.x = x;
68
block.position.y = y;
69
70
block.width = 30;
71
block.height = 12;
72
73
block.point = point;
74
75
BB.stage.addChild(block);
76
BB.blocks.push(block);
77
78
return block;
79
},
80
81
// Create a ball and add it to PIXI.Stage
82
addBall: function() {
83
var texture = PIXI.Texture.fromImage(imgPath["ball"], false);
84
var ball = new PIXI.Sprite(texture);
85
86
ball.anchor.x = 0.5;
87
ball.anchor.y = 0.5;
88
89
ball.position.x = parseInt(BB.renderer.width * 0.5);
90
ball.position.y = 200;
91
92
ball.width = 10;
93
ball.height = 10;
94
95
ball.delta = {
96
'x' : Math.random() - 0.5,
97
'y' : -0.4
98
};
99
100
BB.stage.addChild(ball);
101
BB.balls.push(ball);
102
},
103
104
// Create a paddle and add it to PIXI.Stage
105
addPaddle: function() {
106
var texture = PIXI.Texture.fromImage(imgPath["paddle"], false);
107
BB.paddle = new PIXI.Sprite(texture);
108
109
BB.paddle.anchor.x = 0.5;
110
BB.paddle.anchor.y = 0.5;
111
112
BB.paddle.position.x = parseInt(BB.renderer.width * 0.5);
113
BB.paddle.position.y = BB.renderer.height - 60;
114
115
BB.paddle.width = 60;
116
BB.paddle.height = 10;
117
118
BB.paddle.accel = 0;
119
BB.paddle.delta = {
120
'x' : Math.random() - 0.5,
121
'y' : -3.8
122
};
123
124
BB.stage.addChild(BB.paddle);
125
},
126
127
/**
128
* Add points to current score
129
* @param {int} val points to add
130
*/
131
addScore: function(val) {
132
BB.score += parseInt(val);
133
BB.scoreLabel.setText(BB.score);
134
},
135
136
/**
137
* Set score
138
* @param {int} val new score
139
*/
140
setScore: function(val) {
141
BB.score = val;
142
BB.scoreLabel.setText(BB.score);
143
},
144
145
/**
146
* callback for Core Cordova Plugins Acceleration Watch
147
* @param {Object} a a.x, a.y, a.z
148
*/
149
updateAcceleration: function(a) {
150
var accelText = "", ac = a.x.toFixed(2);
151
152
if(a.x > 0) accelText = '+' + String(ac);
153
else accelText = String(ac);
154
155
// Use parameter x to move paddle
156
if (BB.paddle !== null) {
157
if (BB.paddle.accel / ac > 2.0) {
158
159
} else if (BB.paddle.accel / ac > 0) {
160
BB.paddle.accel += ac * SETTINGS_PADDLE_ACCEL;
161
} else {
162
BB.paddle.accel = ac * SETTINGS_PADDLE_ACCEL;
163
}
164
}
165
166
BB.accelLabel.setText(accelText);
167
},
168
169
// Reset current game and start new one
170
reset: function() {
171
//Reset (remove all children in the stage if exists)
172
for (var i = BB.stage.children.length - 1; i >= 0; i--) {
173
BB.stage.removeChildAt(i);
174
}
175
176
BB.balls = [];
177
BB.blocks = [];
178
BB.setMap();
179
for (var i = 0; i < SETTINGS_BALL_NUM; i++) {
180
BB.addBall();
181
}
182
BB.addPaddle();
183
184
var resetLabel = new PIXI.Text("RESET", {font: "24px/1.2 vt", fill: "red"});
185
resetLabel.position.x = 18;
186
resetLabel.position.y = BB.renderer.height - 52;
187
BB.stage.addChild(resetLabel);
188
resetLabel.buttonMode = true;
189
resetLabel.interactive = true;
190
resetLabel.click = resetLabel.tap = function(data) {
191
BB.reset();
192
};
193
setTimeout(function() {
194
resetLabel.setText("RESET"); //for Android
195
}, 1000, resetLabel);
196
197
var label = new PIXI.Text("SCORE:", {font: "24px/1.2 vt", fill: "red"});
198
label.position.x = 20;
199
label.position.y = 20;
200
BB.stage.addChild(label);
201
setTimeout(function() {
202
label.setText("SCORE:"); //for Android
203
}, 1000, label);
204
205
BB.scoreLabel = new PIXI.Text("0", {font: "24px/1.2 vt", fill: "white"});
206
BB.scoreLabel.position.x = 90;
207
BB.scoreLabel.position.y = 20;
208
BB.stage.addChild(BB.scoreLabel);
209
BB.setScore(0);
210
211
/*
212
var label = new PIXI.Text("ACCEL:", {font: "24px/1.2 vt", fill: "red"});
213
label.position.x = 160;
214
label.position.y = 20;
215
BB.stage.addChild(label);
216
label.setText("ACCEL:"); //for Android
217
218
BB.accelLabel = new PIXI.Text("0", {font: "24px/1.2 vt", fill: "white"});
219
BB.accelLabel.position.x = 230;
220
BB.accelLabel.position.y = 20;
221
BB.stage.addChild(BB.accelLabel);
222
*/
223
224
BB.gameState = GAMESTATE_PLAY;
225
},
226
227
/**
228
* Check whether the ball hits the object
229
* @param {PIXI.Sprite} ball
230
* @param {PIXI.Sprite} obj target object
231
*/
232
isBallHit: function(ball, obj) {
233
return (ball.position.x > (obj.position.x - (obj.width * 0.5))) &&
234
(ball.position.x < (obj.position.x + (obj.width * 0.5))) &&
235
(ball.position.y > (obj.position.y - (obj.height * 0.5))) &&
236
(ball.position.y < (obj.position.y + (obj.height * 0.5)));
237
},
238
239
// Game Over
240
endGame: function() {
241
BB.gameState = GAMESTATE_STOP;
242
vibrate();
243
},
244
245
// Game Clear
246
clearGame: function() {
247
if(typeof navigator.notification !== 'undefined') navigator.notification.alert("Cleared!", function(){}, "Congraturations");
248
else alert("Cleared!");
249
250
BB.gameState = GAMESTATE_STOP;
251
}
252
}
253
...
Copied!
When this page is loading, init() function is called when Cordova is fully loaded or when it's failed to detect the type of the device.
1
...
2
window.onload = function() {
3
if(getUa() === false) init();
4
else document.addEventListener("deviceready", init, false);
5
}
6
...
Copied!
Here is the code of init() function. In this function, BB object is rendered according to the type of device you are using. Then, events listeners related the paddle are added. Also, it renders the paddle position according to each event.
1
...
2
function init() {
3
// Accelerometer
4
/*
5
if (typeof navigator.accelerometer !== 'undefined' && !accelerationWatch) {
6
accelerationWatch = navigator.accelerometer.watchAcceleration(
7
BB.updateAcceleration,
8
function(ex) {
9
alert("accel fail (" + ex.name + ": " + ex.message + ")");
10
},
11
{frequency: SETTINGS_ACCELEROMETER_RELOAD_FREQ}
12
);
13
}
14
*/
15
BB.screenSize = setBound();
16
17
BB.renderer = (getUa() === "Android") ? new PIXI.CanvasRenderer(BB.screenSize.width, BB.screenSize.height) : new PIXI.autoDetectRenderer(BB.screenSize.width, BB.screenSize.height),
18
BB.renderer.transparent = false;
19
document.body.appendChild(BB.renderer.view);
20
21
setScale(BB.screenSize);
22
23
BB.reset();
24
25
// Event listeners to control the paddle
26
window.addEventListener("touchmove", function(e) {
27
BB.paddle.position.x = e.touches[0].clientX / BB.screenSize.zoom;
28
});
29
30
window.addEventListener("mousedown", function(e) {
31
BB.isMouseDown = true;
32
});
33
34
window.addEventListener("mouseup", function(e) {
35
BB.isMouseDown = false;
36
});
37
38
window.addEventListener("mousemove", function(e) {
39
if(BB.isMouseDown) BB.paddle.position.x = e.clientX;
40
});
41
42
window.addEventListener("keydown", function(e) {
43
switch (e.which) {
44
case 37:
45
BB.paddle.position.x -= 4;
46
BB.paddle.accel += (SETTINGS_PADDLE_ACCEL * 0.1);
47
break;
48
case 39:
49
BB.paddle.position.x += 4;
50
BB.paddle.accel -= (SETTINGS_PADDLE_ACCEL * 0.1);
51
break;
52
case 38:
53
BB.paddle.position.y -= 1;
54
break;
55
}
56
});
57
58
requestAnimFrame(animate);
59
}
60
...
Copied!
getUa() function is used to detect the type of the device. It will return false when it failed to get this information.
1
...
2
function getUa() {
3
if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 ) {
4
return 'iPhone';
5
} else if(navigator.userAgent.indexOf('iPad') > 0) {
6
return 'iPad';
7
} else if(navigator.userAgent.indexOf('Android') > 0) {
8
return 'Android';
9
} else return false;
10
}
11
...
Copied!
Last modified 4mo ago