Compare commits
3 Commits
jdg_releas
...
master
Author | SHA1 | Date | |
---|---|---|---|
44e93e5c6d | |||
bc3ef31728 | |||
e0ebef2a27 |
30
Bricks.js
@ -1,30 +0,0 @@
|
||||
class Brick {
|
||||
constructor(type, column, row) {
|
||||
this.type = type;
|
||||
this.row = row;
|
||||
this.column = column;
|
||||
|
||||
this.vspace = 2;
|
||||
this.hspace = 2;
|
||||
|
||||
this.w = (360/8) -this.hspace;
|
||||
this.h = (20) - this.vspace;
|
||||
this.x = (this.w +this.hspace)*column;
|
||||
this.y = 80 + (this.h +this.vspace)*row;
|
||||
|
||||
this.alive = true;
|
||||
}
|
||||
|
||||
update(ctx) {
|
||||
if (!this.alive) return false;
|
||||
|
||||
switch(this.type) {
|
||||
case 1:
|
||||
ctx.fillStyle = 'blue';
|
||||
ctx.fillRect(this.x+1, this.y, this.w, this.h);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
24
Keyboard.js
@ -1,24 +0,0 @@
|
||||
class Keyboard {
|
||||
constructor(onKeydown) {
|
||||
this._pressed = {};
|
||||
this.cb_onKeydown = onKeydown;
|
||||
|
||||
window.addEventListener('keydown', e => this.onKeydown(e));
|
||||
window.addEventListener('keyup', e => this.onKeyup(e));
|
||||
}
|
||||
|
||||
setKeydown(fn) {
|
||||
this.cb_onKeydown = fn;
|
||||
}
|
||||
|
||||
isDown(keyCode) {
|
||||
return this._pressed[keyCode];
|
||||
}
|
||||
onKeydown(event) {
|
||||
this._pressed[event.code] = true;
|
||||
if (this.cb_onKeydown) this.cb_onKeydown(event);
|
||||
}
|
||||
onKeyup(event) {
|
||||
delete this._pressed[event.code];
|
||||
}
|
||||
}
|
48
Levels.js
@ -1,48 +0,0 @@
|
||||
class Levels {
|
||||
load(lvl) {
|
||||
let map = [];
|
||||
switch (+lvl) {
|
||||
case 1:
|
||||
map = [].concat(
|
||||
this.row(0, [1, 0, 1, 0, 0, 1, 0, 1]),
|
||||
this.row(1, [1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
this.row(3, [0, 1, 1, 1, 1, 1, 1, 0]),
|
||||
this.row(4, [1, 1, 1, 1, 1, 1, 1, 1])
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
map = [].concat(
|
||||
this.row(0, [1, 1, 1, 0, 1, 1, 0, 0]),
|
||||
this.row(1, [0, 0, 1, 0, 1, 0, 1, 0]),
|
||||
this.row(2, [0, 0, 1, 0, 1, 0, 1, 0]),
|
||||
this.row(3, [1, 0, 1, 0, 1, 0, 1, 0]),
|
||||
this.row(4, [0, 1, 1, 0, 1, 1, 0, 0])
|
||||
);
|
||||
break;
|
||||
default:
|
||||
map = [].concat(
|
||||
this.row(0, [1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
this.row(1, [1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
this.row(2, [1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
this.row(3, [1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
this.row(4, [1, 1, 1, 1, 1, 1, 1, 1])
|
||||
);
|
||||
break;
|
||||
}
|
||||
return this.toBricks(map);
|
||||
}
|
||||
|
||||
row(r, bricksTypes) {
|
||||
let row = [];
|
||||
for (var i = 0; i < bricksTypes.length; i++) row.push([bricksTypes[i], i, r]);
|
||||
return row;
|
||||
}
|
||||
|
||||
toBricks(map) {
|
||||
let bricks = [];
|
||||
map.forEach(b => {
|
||||
if (b[0] > 0) bricks.push(new Brick(b[0], b[1], b[2]));
|
||||
});
|
||||
return bricks;
|
||||
}
|
||||
}
|
BIN
assets/imgs/b31.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
assets/imgs/b32.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/imgs/b33.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/imgs/ball.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
assets/imgs/bar.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
assets/imgs/bg01.jpg
Normal file
After Width: | Height: | Size: 360 KiB |
BIN
assets/imgs/breakout_sprites.png
Normal file
After Width: | Height: | Size: 161 KiB |
@ -1,6 +1,6 @@
|
||||
class Ball {
|
||||
constructor() {
|
||||
this.size = 10;
|
||||
this.size = 20;
|
||||
|
||||
|
||||
this.moving = false;
|
||||
@ -16,6 +16,8 @@ class Ball {
|
||||
this.angleBL = this.g2r(180);
|
||||
this.angleTL = this.g2r(270);
|
||||
|
||||
this.img = resources.get('ball');
|
||||
|
||||
}
|
||||
|
||||
start() {
|
||||
@ -24,8 +26,8 @@ class Ball {
|
||||
|
||||
update(ctx, x, y) {
|
||||
this.limits ??= {
|
||||
l: this.size,
|
||||
t: this.size,
|
||||
l: 0,
|
||||
t: 0,
|
||||
r: ctx.canvas.width - this.size,
|
||||
b: ctx.canvas.height
|
||||
};
|
||||
@ -38,6 +40,7 @@ class Ball {
|
||||
}
|
||||
|
||||
draw(ctx) {
|
||||
/*
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI, false);
|
||||
ctx.fillStyle = this.color;
|
||||
@ -45,8 +48,20 @@ class Ball {
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = '#003300';
|
||||
ctx.stroke();
|
||||
*/
|
||||
// ctx.drawImage(this.img,0,0,this.img.width,this.img.height,this.x,this.y,20,20);
|
||||
this.drawImage(ctx, this.img, this.x, this.y, this.size,this.size, this.angle);
|
||||
}
|
||||
|
||||
drawImage(ctx, image, x, y, w,h, rotation){
|
||||
ctx.save();
|
||||
ctx.translate(x+w/2, y+h/2);
|
||||
ctx.rotate(rotation);
|
||||
ctx.translate(-x-w/2, -y-h/2);
|
||||
ctx.drawImage(image, x, y, w, h);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
move(x, y) {
|
||||
if (this.moving) {
|
||||
this.x += this.speed * Math.cos(this.angle);
|
||||
@ -60,8 +75,9 @@ class Ball {
|
||||
|
||||
this.collideWalls(this.limits.l, this.limits.t, this.limits.r, this.limits.b);
|
||||
} else {
|
||||
this.x = x;
|
||||
this.y = y - this.size - 1;
|
||||
this.x = x - 10;
|
||||
// this.y = y - this.size - 1;
|
||||
this.y = y - 20;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -132,7 +148,7 @@ class Ball {
|
||||
this.bounceB(r);
|
||||
return true;
|
||||
}
|
||||
if ((this.y - this.size) <= y1 && (this.y - this.size) > y0) {
|
||||
if (this.y <= y1 && this.y > y0) {
|
||||
this.bounceT(r);
|
||||
return true;
|
||||
}
|
||||
@ -143,7 +159,7 @@ class Ball {
|
||||
this.bounceR(r);
|
||||
return true;
|
||||
}
|
||||
if ((this.x - this.size) <= x1 && (this.x - this.size) > x0) {
|
||||
if (this.x <= x1 && this.x > x0) {
|
||||
this.bounceL(r);
|
||||
return true;
|
||||
}
|
@ -9,6 +9,7 @@ class Bar {
|
||||
this._speed = 0; // Current Speed and direction
|
||||
|
||||
this.xLimit = (ctx.canvas.width - this.w);
|
||||
this.img = resources.get('bar');
|
||||
this.reset();
|
||||
}
|
||||
|
||||
@ -49,8 +50,11 @@ class Bar {
|
||||
draw() {
|
||||
if (this.y != this._y) this.y--;
|
||||
if (this.y < this.ctx.canvas.height) {
|
||||
/*
|
||||
this.ctx.fillStyle = 'black';
|
||||
this.ctx.fillRect(this.x, this.y, this.w, this.h);
|
||||
*/
|
||||
this.ctx.drawImage(this.img,this.x,this.y);
|
||||
}
|
||||
}
|
||||
}
|
@ -8,7 +8,9 @@ class Board {
|
||||
this.y = ctx.canvas.height / 2 - 48;
|
||||
|
||||
this.w = this.ctx.canvas.width;
|
||||
this.h = this.ctx.canvas.height
|
||||
this.h = this.ctx.canvas.height;
|
||||
|
||||
this.img = resources.get('bg01');
|
||||
}
|
||||
|
||||
run() {
|
||||
@ -45,7 +47,8 @@ class Board {
|
||||
loop() {
|
||||
if (this.stop) return;
|
||||
|
||||
this.ctx.clearRect(0, 0, this.w, this.h);
|
||||
// this.ctx.clearRect(0, 0, this.w, this.h);
|
||||
this.ctx.drawImage(this.img, 0, 0);
|
||||
this.update();
|
||||
this.requestID = requestAnimationFrame( ()=>this.loop() );
|
||||
}
|
44
assets/js/Bricks.js
Normal file
@ -0,0 +1,44 @@
|
||||
class Brick {
|
||||
constructor(type, column, row) {
|
||||
this.type = type;
|
||||
this.row = row;
|
||||
this.column = column;
|
||||
|
||||
this.vspace = 2;
|
||||
this.hspace = 2;
|
||||
|
||||
this.w = (32) - this.hspace;
|
||||
this.h = (32) - this.vspace;
|
||||
this.x = 2 + (this.w + this.hspace) * column;
|
||||
this.y = 80 + (this.h + this.vspace) * row;
|
||||
|
||||
this.img = [];
|
||||
switch (type) {
|
||||
case 2: this.lives = 2; this.img = [ resources.get('b31'),resources.get('b32') ]; break;
|
||||
case 3: this.lives = 3; this.img = [ resources.get('b31'),resources.get('b32'), resources.get('b33') ]; break;
|
||||
default: this.lives = 1; this.img = [ resources.get('b31') ]; break;
|
||||
}
|
||||
}
|
||||
|
||||
crack() {
|
||||
this.lives--;
|
||||
}
|
||||
|
||||
update(ctx) {
|
||||
if (this.lives == 0) return false;
|
||||
|
||||
switch (this.lives) {
|
||||
case 1:
|
||||
ctx.drawImage(this.img[0], this.x + 1, this.y);
|
||||
break;
|
||||
case 2:
|
||||
ctx.drawImage(this.img[1], this.x + 1, this.y);
|
||||
break;
|
||||
case 3:
|
||||
ctx.drawImage(this.img[2], this.x + 1, this.y);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -53,10 +53,10 @@ class GamePlay extends Board {
|
||||
let r = ball.update(this.ctx, this.bar.x + this.bar.w/2, this.bar.y);
|
||||
ball.collide( this.bar.x, this.bar.y, this.bar.x + this.bar.w, this.bar.y + this.bar.h );
|
||||
this.bricks.forEach(b=>{
|
||||
if(b.alive){
|
||||
if(b.lives>0){
|
||||
if ( ball.collide(b.x,b.y,b.x+b.w,b.y+b.h) ) {
|
||||
this.score.add(1);
|
||||
b.alive = false;
|
||||
b.crack();
|
||||
}
|
||||
|
||||
}});
|
72
assets/js/Keyboard.js
Normal file
@ -0,0 +1,72 @@
|
||||
class Keyboard {
|
||||
constructor(onKeydown) {
|
||||
this._pressed = {};
|
||||
this.cb_onKeydown = onKeydown;
|
||||
|
||||
window.addEventListener('keydown', e => this.onKeydown(e));
|
||||
window.addEventListener('keyup', e => this.onKeyup(e));
|
||||
|
||||
window.addEventListener('touchstart', e => this.onTouchStart(e));
|
||||
window.addEventListener('touchmove', e => this.onTouchMove(e));
|
||||
window.addEventListener('touchend', e => this.onTouchEnd(e));
|
||||
|
||||
}
|
||||
|
||||
setKeydown(fn) {
|
||||
this.cb_onKeydown = fn;
|
||||
}
|
||||
|
||||
isDown(keyCode) {
|
||||
return this._pressed[keyCode];
|
||||
}
|
||||
onKeydown(event) {
|
||||
this._pressed[event.code] = true;
|
||||
if (this.cb_onKeydown) this.cb_onKeydown(event);
|
||||
}
|
||||
onKeyup(event) {
|
||||
delete this._pressed[event.code];
|
||||
}
|
||||
|
||||
|
||||
onTouchStart(e) {
|
||||
var touchobj = e.changedTouches[0] // reference first touch point (ie: first finger)
|
||||
this.touchX = parseInt(touchobj.clientX) // get x position of touch point relative to left edge of browser
|
||||
this.touchY = parseInt(touchobj.clientY) // get x position of touch point relative to left edge of browser
|
||||
window.dispatchEvent(new KeyboardEvent('keydown',{'code':'Space'}));
|
||||
window.dispatchEvent(new KeyboardEvent('keydown',{'code':'KeyN'}));
|
||||
e.preventDefault()
|
||||
}
|
||||
onTouchMove(e) {
|
||||
var touchobj = e.changedTouches[0] // reference first touch point for this event
|
||||
var dist = parseInt(touchobj.clientX) - this.touchX
|
||||
if (dist>0) {
|
||||
delete this._pressed['ArrowLeft'];
|
||||
this._pressed['ArrowRight'] = true;
|
||||
} else if (dist<0) {
|
||||
delete this._pressed['ArrowRight'];
|
||||
this._pressed['ArrowLeft'] = true;
|
||||
} else {
|
||||
delete this._pressed['ArrowLeft'];
|
||||
delete this._pressed['ArrowRight'];
|
||||
}
|
||||
|
||||
dist = parseInt(touchobj.clientY) - this.touchY
|
||||
if (dist>0) {
|
||||
delete this._pressed['ArrowUp'];
|
||||
this._pressed['ArrowDown'] = true;
|
||||
} else if (dist<0) {
|
||||
delete this._pressed['ArrowDown'];
|
||||
this._pressed['ArrowUp'] = true;
|
||||
} else {
|
||||
delete this._pressed['ArrowUp'];
|
||||
delete this._pressed['ArrowDown'];
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
}
|
||||
onTouchEnd(e) {
|
||||
this._pressed = {};
|
||||
}
|
||||
|
||||
|
||||
}
|
48
assets/js/Levels.js
Normal file
@ -0,0 +1,48 @@
|
||||
class Levels {
|
||||
load(lvl) {
|
||||
let map = [];
|
||||
switch (+lvl) {
|
||||
case 1:
|
||||
map = [].concat(
|
||||
this.row(0, [0, 0, 1, 0, 1, 0, 0, 1, 0, 1]),
|
||||
this.row(1, [0, 0, 1, 1, 1, 1, 1, 1, 1, 1]),
|
||||
this.row(3, [0, 0, 0, 1, 1, 1, 1, 1, 1, 0]),
|
||||
this.row(4, [0, 0, 1, 1, 1, 1, 1, 1, 1, 1])
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
map = [].concat(
|
||||
this.row(0, [0, 0, 3, 3, 3, 0, 3, 3, 0, 0]),
|
||||
this.row(1, [0, 0, 0, 0, 3, 0, 3, 0, 3, 0]),
|
||||
this.row(2, [0, 0, 0, 0, 3, 0, 3, 0, 3, 0]),
|
||||
this.row(3, [0, 0, 3, 0, 3, 0, 3, 0, 3, 0]),
|
||||
this.row(4, [0, 0, 0, 3, 3, 0, 3, 3, 0, 0])
|
||||
);
|
||||
break;
|
||||
default:
|
||||
map = [].concat(
|
||||
this.row(0, [2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 2]),
|
||||
this.row(1, [2, 3, 1, 3, 1, 3, 1, 3, 1, 3, 2]),
|
||||
this.row(2, [2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 2]),
|
||||
this.row(3, [2, 3, 1, 3, 1, 3, 1, 3, 1, 3, 2]),
|
||||
this.row(4, [2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 2])
|
||||
);
|
||||
break;
|
||||
}
|
||||
return this.toBricks(map);
|
||||
}
|
||||
|
||||
row(r, bricksTypes) {
|
||||
let row = [];
|
||||
for (var i = 0; i < bricksTypes.length; i++) row.push([bricksTypes[i], i, r]);
|
||||
return row;
|
||||
}
|
||||
|
||||
toBricks(map) {
|
||||
let bricks = [];
|
||||
map.forEach(b => {
|
||||
if (b[0] > 0) bricks.push(new Brick(b[0], b[1], b[2]));
|
||||
});
|
||||
return bricks;
|
||||
}
|
||||
}
|
30
assets/js/Resources.js
Normal file
@ -0,0 +1,30 @@
|
||||
class Resources {
|
||||
constructor() {
|
||||
this.total = 0;
|
||||
this.loading = 0;
|
||||
this.resources = {};
|
||||
|
||||
this.load('bg01', 'jpg');
|
||||
this.load('ball');
|
||||
this.load('bar');
|
||||
this.load('b31');
|
||||
this.load('b32');
|
||||
this.load('b33');
|
||||
}
|
||||
|
||||
|
||||
load(res, ext='png') {
|
||||
let _this = this;
|
||||
this.total++;
|
||||
this.loading++;
|
||||
this.resources[res] = new Image();
|
||||
this.resources[res].onload = function () {
|
||||
_this.loading--;
|
||||
}
|
||||
this.resources[res].src = 'assets/imgs/' + res + '.'+ext;
|
||||
}
|
||||
|
||||
get(res) {
|
||||
return this.resources[res];
|
||||
}
|
||||
};
|
@ -5,6 +5,9 @@
|
||||
document.addEventListener('DOMContentLoaded', init);
|
||||
|
||||
|
||||
let resources = new Resources();
|
||||
|
||||
|
||||
function init() {
|
||||
let ctx, canvas = document.createElement("canvas");
|
||||
canvas.width = 360; // window.innerWidth
|
38
index.html
@ -9,24 +9,28 @@
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
}
|
||||
canvas { border:1px solid black; }
|
||||
|
||||
canvas {
|
||||
border: 1px solid black;
|
||||
}
|
||||
</style>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="Keyboard.js"></script>
|
||||
<script src="Board.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="GameIntro.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="GameOver.js"></script>
|
||||
<script src="Bricks.js"></script>
|
||||
<script src="Levels.js"></script>
|
||||
<script src="Score.js"></script>
|
||||
<script src="Lives.js"></script>
|
||||
<script src="Bar.js"></script>
|
||||
<script src="Ball.js"></script>
|
||||
<script src="GamePlay.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="index.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="assets/js/Resources.js"></script>
|
||||
<script src="assets/js/Keyboard.js"></script>
|
||||
<script src="assets/js/Board.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="assets/js/GameIntro.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="assets/js/GameOver.js"></script>
|
||||
<script src="assets/js/Bricks.js"></script>
|
||||
<script src="assets/js/Levels.js"></script>
|
||||
<script src="assets/js/Score.js"></script>
|
||||
<script src="assets/js/Lives.js"></script>
|
||||
<script src="assets/js/Bar.js"></script>
|
||||
<script src="assets/js/Ball.js"></script>
|
||||
<script src="assets/js/GamePlay.js"></script>
|
||||
<!-- ------------------------------------------ -->
|
||||
<script src="assets/js/index.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|