97 lines
3.5 KiB
JavaScript

document.addEventListener("DOMContentLoaded", () => {
// get canvas and context
const canvas = document.querySelector("canvas");
const context = canvas.getContext("2d");
// set constant for midpoint of x-axis
const midX = canvas.width / 2;
// define objects for ball, paddle, and player with starting values
let ball = {x: midX, y: 0, speedX: 1, speedY: 5};
const paddle = {x: midX - 50, y: canvas.height - 50, len: 100,
direction: 0};
const player = {hits: 0, highScore: 0};
// callback function for requestAnimationFrame()
const render = () => {
// calculate paddle position
paddle.x = paddle.x + paddle.direction;
// calculate ball position
ball.x = ball.x + ball.speedX;
ball.y = ball.y + ball.speedY;
// if ball hits right or left border, reverse x speed to simulate bounce
if (ball.x < 0 || ball.x > canvas.width ) {
ball.speedX = -ball.speedX;
}
// if ball hits top border, reverse y speed to simulate bounce
if (ball.y < 0) {
ball.speedY = -ball.speedY;
}
// if ball is below paddle level...
if (ball.y > paddle.y) {
const isLeftOfPaddle = ball.x < paddle.x;
const isRightOfPaddle = ball.x > paddle.x + paddle.len;
if (isLeftOfPaddle || isRightOfPaddle) {
// missed - start over
ball = {x: midX, y: 0, speedX: 1, speedY: 5};
player.hits = 0;
} else {
// hit - reverse y speed to simulate bounce
ball.speedY = -ball.speedY;
// Change x speed based on where ball hits paddle to
// determine angle of bounce. If hits near middle of
// paddle, angle will be more up-and-down. Angle becomes
// more side-to-side as ball hits toward paddle ends.
// (To make the angle of bounce more pronounced,
// make the literal value more than .1)
const midPaddle = paddle.x + (paddle.len / 2);
ball.speedX = .1 * (ball.x - midPaddle);
// increment hits
player.hits++;
// update high score as needed
if (player.hits > player.highScore) {
player.highScore = player.hits;
}
}
}
// clear previous drawing and start new path
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
// ball
context.arc(ball.x, ball.y, 5, 0, Math.PI * 2);
// paddle
context.moveTo(paddle.x, paddle.y);
context.lineTo(paddle.x + paddle.len, paddle.y);
// draw ball and paddle
context.stroke();
// draw hit count and high score text
context.font = "20px sans-serif";
context.fillText("Hits: " + player.hits, 20, paddle.y + 30);
context.fillText("High Score: " + player.highScore, canvas.width - 140, paddle.y + 30);
// continue animation
requestAnimationFrame(render);
};
// event handlers
document.addEventListener("keydown", e => {
if(e.code == "ArrowLeft") paddle.direction = -5;
if(e.code == "ArrowRight") paddle.direction = 5;
});
document.addEventListener("keyup", () => {
paddle.direction = 0;
});
// start animation
requestAnimationFrame(render);
});