Files
2026-04-26 09:44:19 +02:00

207 lines
7.7 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>Tennis - KinderWelt</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; user-select: none; }
body {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh; display: flex; flex-direction: column; align-items: center;
font-family: 'Comic Sans MS', cursive, sans-serif; overflow: hidden;
}
h1 { color: white; margin: 10px 0; font-size: 24px; }
.score { color: white; font-size: 20px; margin-bottom: 10px; }
#gameCanvas {
background: #4ade80; border: 4px solid white; border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0,0.3);
}
.controls {
display: flex; gap: 20px; margin-top: 15px; flex-wrap: wrap; justify-content: center;
}
.btn {
background: white; border: none; border-radius: 10px; padding: 15px 30px;
font-size: 20px; cursor: pointer; box-shadow: 0 4px 10px rgba(0,0,0,0.2);
font-family: inherit; font-weight: bold;
}
.btn:active { transform: scale(0.95); }
.btn-back { background: #ff6b6b; color: white; text-decoration: none; display: inline-block; }
.btn:disabled { opacity: 0.5; cursor: not-allowed; }
.instructions { color: white; margin-top: 10px; text-align: center; opacity: 0.9; }
</style>
</head>
<body>
<h1>🎾 Tennis</h1>
<div class="score">Spieler: <span id="playerScore">0</span> | Computer: <span id="computerScore">0</span></div>
<canvas id="gameCanvas"></canvas>
<div class="controls">
<button class="btn" id="startBtn" onclick="startGame()">▶️ Start</button>
<a href="../index.html" class="btn btn-back">⬅️ Zurück</a>
</div>
<p class="instructions">💡 Klicke/Tippe auf den Bildschirm, um das Paddle zu bewegen!</p>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
// Responsive Größe
function resizeCanvas() {
const maxWidth = Math.min(window.innerWidth - 20, 600);
const maxHeight = Math.min(window.innerHeight - 200, 400);
canvas.width = maxWidth;
canvas.height = maxHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
// Spiel-Variablen
let gameRunning = false;
let playerScore = 0;
let computerScore = 0;
let animationId;
// Paddle
const paddleWidth = 10;
const paddleHeight = 80;
let playerY = canvas.height / 2 - paddleHeight / 2;
let computerY = canvas.height / 2 - paddleHeight / 2;
const computerSpeed = 3;
// Ball
const ballSize = 10;
let ballX = canvas.width / 2;
let ballY = canvas.height / 2;
let ballSpeedX = 5;
let ballSpeedY = 3;
// Maus/Touch Position
let targetY = canvas.height / 2;
// Input-Handler
canvas.addEventListener('mousemove', (e) => {
const rect = canvas.getBoundingClientRect();
targetY = e.clientY - rect.top - paddleHeight / 2;
});
canvas.addEventListener('touchmove', (e) => {
e.preventDefault();
const rect = canvas.getBoundingClientRect();
targetY = e.touches[0].clientY - rect.top - paddleHeight / 2;
}, { passive: false });
canvas.addEventListener('click', () => {
if (!gameRunning) startGame();
});
function resetBall() {
ballX = canvas.width / 2;
ballY = canvas.height / 2;
ballSpeedX = (Math.random() > 0.5 ? 1 : -1) * (4 + Math.random() * 2);
ballSpeedY = (Math.random() * 2 - 1) * 4;
}
function update() {
if (!gameRunning) return;
// Spieler-Paddle bewegen (smooth)
playerY += (targetY - playerY) * 0.2;
playerY = Math.max(0, Math.min(canvas.height - paddleHeight, playerY));
// Computer-Paddle bewegen
const computerCenter = computerY + paddleHeight / 2;
if (computerCenter < ballY - 10) computerY += computerSpeed;
else if (computerCenter > ballY + 10) computerY -= computerSpeed;
computerY = Math.max(0, Math.min(canvas.height - paddleHeight, computerY));
// Ball bewegen
ballX += ballSpeedX;
ballY += ballSpeedY;
// Wände
if (ballY <= 0 || ballY >= canvas.height - ballSize) {
ballSpeedY = -ballSpeedY;
}
// Spieler-Paddle Kollision
if (ballX <= paddleWidth + ballSize &&
ballY > playerY && ballY < playerY + paddleHeight) {
ballSpeedX = -ballSpeedX * 1.05;
ballSpeedY += (ballY - (playerY + paddleHeight / 2)) * 0.1;
}
// Computer-Paddle Kollision
if (ballX >= canvas.width - paddleWidth - ballSize &&
ballY > computerY && ballY < computerY + paddleHeight) {
ballSpeedX = -ballSpeedX * 1.05;
ballSpeedY += (ballY - (computerY + paddleHeight / 2)) * 0.1;
}
// Punkt
if (ballX < 0) {
computerScore++;
document.getElementById('computerScore').textContent = computerScore;
resetBall();
} else if (ballX > canvas.width) {
playerScore++;
document.getElementById('playerScore').textContent = playerScore;
resetBall();
}
}
function draw() {
// Hintergrund
ctx.fillStyle = '#4ade80';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Mittellinie
ctx.strokeStyle = 'rgba(255,255,255,0.5)';
ctx.setLineDash([10, 10]);
ctx.beginPath();
ctx.moveTo(canvas.width / 2, 0);
ctx.lineTo(canvas.width / 2, canvas.height);
ctx.stroke();
ctx.setLineDash([]);
// Paddles
ctx.fillStyle = 'white';
ctx.fillRect(0, playerY, paddleWidth, paddleHeight);
ctx.fillRect(canvas.width - paddleWidth, computerY, paddleWidth, paddleHeight);
// Ball
ctx.beginPath();
ctx.arc(ballX, ballY, ballSize, 0, Math.PI * 2);
ctx.fillStyle = '#ff6b6b';
ctx.fill();
ctx.strokeStyle = 'white';
ctx.lineWidth = 2;
ctx.stroke();
// Start-Hinweis
if (!gameRunning) {
ctx.fillStyle = 'rgba(0,0,0,0.5)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = 'white';
ctx.font = 'bold 24px Comic Sans MS';
ctx.textAlign = 'center';
ctx.fillText('Klicke auf Start!', canvas.width / 2, canvas.height / 2);
}
}
function gameLoop() {
update();
draw();
animationId = requestAnimationFrame(gameLoop);
}
function startGame() {
gameRunning = true;
document.getElementById('startBtn').textContent = '🔄 Neustart';
resetBall();
}
// Start
gameLoop();
</script>
</body>
</html>