breakout/Ball.js
2021-11-15 00:10:53 +01:00

167 lines
3.8 KiB
JavaScript

class Ball {
constructor() {
this.size = 10;
this.moving = false;
this.speed = 7;
// this.angle = 90;
this.setAngle(180 + 60, 360 - 60);
this.color = 'red';
this.limits = null;
this.angleTR = this.g2r(360);
this.angleBR = this.g2r(90);
this.angleBL = this.g2r(180);
this.angleTL = this.g2r(270);
}
start() {
this.moving = true;
}
update(ctx, x, y) {
this.limits ??= {
l: this.size,
t: this.size,
r: ctx.canvas.width - this.size,
b: ctx.canvas.height
};
if (this.move(x, y)) {
this.draw(ctx);
return true;
}
return false;
}
draw(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI, false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = '#003300';
ctx.stroke();
}
move(x, y) {
if (this.moving) {
this.x += this.speed * Math.cos(this.angle);
this.y += this.speed * Math.sin(this.angle);
// Escaped from the pad
if (this.y > this.limits.b) {
this.moving = false;
return false;
}
this.collideWalls(this.limits.l, this.limits.t, this.limits.r, this.limits.b);
} else {
this.x = x;
this.y = y - this.size - 1;
}
return true;
}
bounceL(r) {
if (this.angle <= this.angleBL)
this.setAngle(0 + r, 90 - r);
else
this.setAngle(270 + r, 360 - r);
}
bounceR(r) {
if (this.angle <= this.angleBR)
this.setAngle(90 + r, 180 - r);
else
this.setAngle(180 + r, 270 - r);
}
bounceT(r) {
if (this.angle <= this.angleTL)
this.setAngle(90 + r, 180 - r);
else
this.setAngle(0 + r, 90 - r);
}
bounceB(r) {
if (this.angle <= this.angleBR)
this.setAngle(270 + r, 360 - r);
else
this.setAngle(180 + r, 270 - r);
}
collideWalls(x0, y0, x1, y1) {
let r = 20;
if (this.x <= x0) {
this.bounceL(r);
return true;
}
if (this.x >= x1) {
this.bounceR(r);
return true;
}
if (this.y <= y0) {
this.bounceT(r);
return true;
}
if (this.y >= y1) {
this.bounceB(r);
return true;
}
return false;
}
/*
TL 270 TR
180 0
BL 90 BR
B
---------
R | | L
---------
T
*/
collide(x0, y0, x1, y1) { // 0 = hit Left/Right, 1 = hit Up/Down
let r = 20;
if (this.x >= x0 && this.x <= x1) {
if ((this.y + this.size) >= y0 && (this.y + this.size) < y1) {
this.bounceB(r);
return true;
}
if ((this.y - this.size) <= y1 && (this.y - this.size) > y0) {
this.bounceT(r);
return true;
}
}
if (this.y >= y0 && this.y <= y1) {
if ((this.x + this.size) >= x0 && (this.x + this.size) < x1) {
this.bounceR(r);
return true;
}
if ((this.x - this.size) <= x1 && (this.x - this.size) > x0) {
this.bounceL(r);
return true;
}
}
return false;
}
setAngle(min, max) {
this.angle = this.g2r(Math.floor(Math.random() * (max - min)) + min);
}
g2r(deg) {
return (((360 + deg) % 360) * Math.PI) / 180.0;
}
r2g(rad) {
return rad * 180 / Math.PI;
}
}