207 lines
7.7 KiB
HTML
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> |