<!DOCTYPE html>
<html lang="pl">
<head>
<meta charset="UTF-8">
<title>Pong</title>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #111;
}
canvas {
background: #222;
border: 2px solid #fff;
}
</style>
</head>
<body>
<canvas id="gameCanvas" width="600" height="400"></canvas>
<script>
// ---------------------------
// Klasa Paletki
// ---------------------------
class Paddle {
constructor(canvas) {
this.canvas = canvas;
this.width = 100;
this.height = 15;
this.x = (canvas.width - this.width) / 2;
this.y = canvas.height - this.height - 10;
}
draw(ctx) {
ctx.fillStyle = "lime";
ctx.fillRect(this.x, this.y, this.width, this.height);
}
}
// ---------------------------
// Klasa Piłki
// ---------------------------
class Ball {
constructor(canvas) {
this.canvas = canvas;
this.reset();
}
reset() {
this.x = this.canvas.width / 2;
this.y = this.canvas.height / 2;
this.radius = 8;
this.speedX = 3 * (Math.random() > 0.5 ? 1 : -1);
this.speedY = 3;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
// Odbicia od ścian
if (this.x < this.radius || this.x > this.canvas.width - this.radius) {
this.speedX *= -1;
}
if (this.y < this.radius) {
this.speedY *= -1;
}
}
draw(ctx) {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = "orange";
ctx.fill();
ctx.closePath();
}
}
// ---------------------------
// Klasa Gry
// ---------------------------
class Game {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext("2d");
this.paddle = new Paddle(canvas);
this.ball = new Ball(canvas);
this.score = 0;
this.lives = 3;
// Obsługa zdarzeń
this.initEvents();
}
initEvents() {
// Myszka
this.canvas.addEventListener("mousemove", (e) => {
const rect = this.canvas.getBoundingClientRect();
this.paddle.x = e.clientX - rect.left - this.paddle.width / 2;
});
// Dotyk
this.canvas.addEventListener("touchmove", (e) => {
const rect = this.canvas.getBoundingClientRect();
const touchX = e.touches[0].clientX - rect.left;
this.paddle.x = touchX - this.paddle.width / 2;
e.preventDefault();
}, { passive: false });
}
update() {
this.ball.update();
// Sprawdź kolizję z paletką
if (this.ball.y + this.ball.radius >= this.paddle.y &&
this.ball.x >= this.paddle.x &&
this.ball.x <= this.paddle.x + this.paddle.width) {
this.ball.speedY *= -1;
this.score++;
// przyspiesz delikatnie
this.ball.speedX *= 1.05;
this.ball.speedY *= 1.05;
}
// Sprawdź czy piłka wypadła
if (this.ball.y > this.canvas.height) {
this.lives--;
this.ball.reset();
if (this.lives <= 0) {
alert("Koniec gry! Wynik: " + this.score);
document.location.reload();
}
}
}
draw() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Rysuj elementy gry
this.paddle.draw(this.ctx);
this.ball.draw(this.ctx);
// Wynik i życie
this.ctx.fillStyle = "#fff";
this.ctx.font = "16px Arial";
this.ctx.fillText("Punkty: " + this.score, 10, 20);
this.ctx.fillText("Życia: " + this.lives, this.canvas.width - 80, 20);
}
loop() {
this.update();
this.draw();
requestAnimationFrame(() => this.loop());
}
}
// ---------------------------
// Uruchomienie gry
// ---------------------------
const canvas = document.getElementById("gameCanvas");
const game = new Game(canvas);
game.loop();
</script>
</body>
</html>