164 lines
3.7 KiB
JavaScript
164 lines
3.7 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 && (this.y+this.size)>=y0 && (this.y+this.size)<y1) {
|
|
this.bounceB(r);
|
|
return true;
|
|
}
|
|
|
|
if (this.x>=x0 && this.x<=x1 && (this.y-this.size)<=y1 && (this.y-this.size)>y0) {
|
|
this.bounceT(r);
|
|
return true;
|
|
}
|
|
|
|
if (this.y>=y0 && this.y<=y1 && (this.y+this.size)>=x0 && (this.y-this.size)<x1) {
|
|
this.bounceR(r);
|
|
return true;
|
|
}
|
|
|
|
if (this.y>=y0 && this.y<=y1 && (this.y-this.size)<=x1 && (this.y-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;
|
|
}
|
|
} |