ballz.js/ball.js
2019-04-10 10:29:41 +02:00

119 lines
3.9 KiB
JavaScript

class Ball {
constructor(game, cx, cy, v, dir) {
this.game = game;
this.id = this.game.balls.length;
this.cx = cx;
this.cy = cy;
this.vx = v * Math.cos(dir);
this.vy = v * Math.sin(dir);
this.collide = true;
}
update(stepCount = 10) {
if (!this.game.isMoving)
return;
for (let i = 0; i < stepCount; i++) {
this.cx += this.vx / stepCount;
this.cy -= this.vy / stepCount;
if (this.cx - this.game.ballRadius <= game.startAtX || this.cx + this.game.ballRadius >= this.game.canvas.width - game.startAtX) {
this.vx *= -1;
}
if (this.cy - this.game.ballRadius <= 0) {
this.vy *= -1;
}
if (this.cy >= this.game.originY && this.vy < 0) {
this.vy = 0;
this.cy = this.game.originY;
if (this.game.newOriginX === null || this.cx === this.game.newOriginX) {
this.game.newOriginX = this.cx;
this.vy = 0;
this.remove();
} else {
this.vx = (this.game.newOriginX - this.cx) / 60 * 2;
setTimeout(() => {
this.vx = 0;
this.remove();
}, 500);
}
}
if (this.collide) {
this.game.rects.forEach(rect => {
this.checkHitRect(rect);
});
this.game.powerUps.forEach(powerUp => {
this.checkHitPowerUp(powerUp);
});
}
}
}
remove() {
this.game.balls.splice(this.game.balls.findIndex(ball => ball === this), 1);
if (this.game.isMoving && this.game.balls.length === 0) {
this.game.roundOver();
}
}
checkHitRect(rect) {
const closestX = Math.clamp(this.cx, rect.x, rect.x + this.game.rectSize);
const closestY = Math.clamp(this.cy, rect.y, rect.y + this.game.rectSize);
const distX = this.cx - closestX;
const distY = this.cy - closestY;
const distSquared = (distX ** 2) + (distY ** 2);
if (distSquared < this.game.ballRadius ** 2) {
const collBottom = rect.y + this.game.rectSize - (this.cy - this.game.ballRadius);
const collTop = (this.cy + this.game.ballRadius) - rect.y;
const collLeft = (this.cx + this.game.ballRadius) - rect.x;
const collRight = rect.x + this.game.rectSize - (this.cx - this.game.ballRadius);
if ((collTop <= collBottom && collTop <= collLeft && collTop <= collRight) || (collBottom <= collTop && collBottom <= collLeft && collBottom <= collRight)) {
this.vy *= -1;
}
if((collLeft <= collRight && collLeft <= collTop && collLeft <= collBottom) || (collRight <= collLeft && collRight <= collTop && collRight <= collBottom)) {
this.vx *= -1;
}
if (distX > 0)
this.cx += game.ballRadius - distX;
else if (distX < 0)
this.cx -= game.ballRadius + distX;
if (distY > 0)
this.cy += game.ballRadius - distY;
else if(distY < 0)
this.cy -= game.ballRadius + distY;
rect.hit(this);
}
}
checkHitPowerUp(powerUp) {
const distX = this.cx - powerUp.cx;
const distY = this.cy - powerUp.cy;
const distSquared = (distX ** 2) + (distY ** 2);
if (distSquared < (this.game.ballRadius + this.game.powerUpRadius) ** 2) {
powerUp.hit();
}
}
draw() {
this.game.ctx.fillStyle = '#fff';
this.game.ctx.beginPath();
this.game.ctx.arc(this.cx, this.cy, this.game.ballRadius, 0, 2 * Math.PI);
this.game.ctx.fill();
}
}