<!DOCTYPE html>
<html>
<head>
<title>Schaf-Sprung-Spiel</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background: #f0f0f0;
font-family: Arial, sans-serif;
overflow: hidden;
}
canvas {
border: 2px solid #000;
}
#score {
position: absolute;
top: 20px;
left: 20px;
font-size: 24px;
color: #000;
}
#startMessage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
color: #000;
background: rgba(255, 255, 255, 0.7);
padding: 10px 20px;
border-radius: 10px;
text-align: center;
}
#gameOverMessage {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 24px;
color: #000;
background: rgba(255, 255, 255, 0.7);
padding: 10px 20px;
border-radius: 10px;
text-align: center;
display: none;
}
</style>
</head>
<body>
<div id="score">Score: 0</div>
<div id="startMessage">Drücke eine Taste, um zu starten!</div>
<div id="gameOverMessage">Game Over! Drücke eine Taste, um neu zu starten. Score: <span id="finalScore">0</span></div>
<canvas id="game" width="800" height="300"></canvas>
<script>
const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d');
const scoreElement = document.getElementById('score');
const startMessage = document.getElementById('startMessage');
const gameOverMessage = document.getElementById('gameOverMessage');
const finalScoreElement = document.getElementById('finalScore');
// Spieler (Schaf)
const player = {
x: 50,
y: 200,
width: 40,
height: 40,
speed: 5,
jumpForce: 12,
velocityY: 0,
isJumping: false,
draw() {
// Körper (weiß)
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.ellipse(this.x + 20, this.y + 20, 18, 15, 0, 0, Math.PI * 2);
ctx.fill();
// Kopf (weiß)
ctx.beginPath();
ctx.ellipse(this.x + 32, this.y + 10, 12, 10, 0, 0, Math.PI * 2);
ctx.fill();
// Augen (schwarz)
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.arc(this.x + 36, this.y + 6, 2, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(this.x + 30, this.y + 6, 2, 0, Math.PI * 2);
ctx.fill();
// Ohren (weiß)
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.ellipse(this.x + 38, this.y + 3, 4, 6, 0, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.ellipse(this.x + 26, this.y + 3, 4, 6, 0, 0, Math.PI * 2);
ctx.fill();
// Beine (weiß)
ctx.fillRect(this.x + 12, this.y + 35, 6, 10);
ctx.fillRect(this.x + 22, this.y + 35, 6, 10);
// Grasend-Animation (wenn nicht im Spiel)
if (!gameActive && !gameStarted) {
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.arc(this.x + 35, this.y + 25, 3, 0, Math.PI * 2);
ctx.fill();
}
},
jump() {
if (!this.isJumping) {
this.velocityY = -this.jumpForce;
this.isJumping = true;
}
},
update() {
this.velocityY += 0.8;
this.y += this.velocityY;
if (this.y + this.height > canvas.height - 20) {
this.y = canvas.height - this.height - 20;
this.velocityY = 0;
this.isJumping = false;
}
}
};
// Hindernisse (andere Schafe)
const obstacles = [];
let score = 0;
let gameSpeed = 5;
let gameActive = false;
let gameStarted = false;
let obstacleDistance = 300; // Abstand zwischen den Hindernissen
// Hindernis erstellen (andere Schafe)
function createObstacle() {
obstacles.push({
x: canvas.width,
y: canvas.height - 50,
width: 40,
height: 30,
draw() {
// Körper (weiß)
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.ellipse(this.x + 20, this.y + 15, 15, 10, 0, 0, Math.PI * 2);
ctx.fill();
// Kopf (weiß)
ctx.beginPath();
ctx.ellipse(this.x + 30, this.y + 5, 10, 8, 0, 0, Math.PI * 2);
ctx.fill();
// Augen (schwarz)
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.arc(this.x + 34, this.y + 3, 2, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(this.x + 28, this.y + 3, 2, 0, Math.PI * 2);
ctx.fill();
},
update() {
this.x -= gameSpeed;
}
});
}
// Kollision prüfen
function checkCollision() {
for (let i = 0; i < obstacles.length; i++) {
const obstacle = obstacles[i];
if (
player.x < obstacle.x + obstacle.width &&
player.x + player.width > obstacle.x &&
player.y + player.height > obstacle.y &&
player.y < obstacle.y + obstacle.height
) {
gameActive = false;
finalScoreElement.textContent = score;
gameOverMessage.style.display = 'block';
return;
}
}
}
// Spiel zurücksetzen
function resetGame() {
player.x = 50;
player.y = 200;
player.velocityY = 0;
player.isJumping = false;
obstacles.length = 0;
score = 0;
gameSpeed = 5;
gameActive = true;
gameStarted = false;
scoreElement.textContent = `Score: ${score}`;
startMessage.style.display = 'block';
gameOverMessage.style.display = 'none';
}
// Spiel-Loop
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Hintergrund: Himmel und Gras
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, canvas.width, canvas.height - 20);
ctx.fillStyle = '#000000';
ctx.fillRect(0, canvas.height - 20, canvas.width, 20);
// Spieler aktualisieren und zeichnen
player.update();
player.draw();
if (gameActive) {
// Hindernisse aktualisieren und zeichnen
for (let i = 0; i < obstacles.length; i++) {
obstacles[i].update();
obstacles[i].draw();
if (obstacles[i].x + obstacles[i].width < 0) {
obstacles.splice(i, 1);
i--;
score++;
scoreElement.textContent = `Score: ${score}`;
}
}
// Neue Hindernisse erstellen
if (obstacles.length === 0 || obstacles[obstacles.length - 1].x < canvas.width - obstacleDistance) {
createObstacle();
}
// Geschwindigkeit erhöhen
if (score % 5 === 0 && score > 0) {
gameSpeed += 0.3;
obstacleDistance = Math.max(200, obstacleDistance - 10); // Abstand verringern, aber nicht unter 200
}
// Kollision prüfen
checkCollision();
}
requestAnimationFrame(gameLoop);
}
// Tastatur-Steuerung
document.addEventListener('keydown', (e) => {
if (!gameStarted && !gameActive) {
gameStarted = true;
gameActive = true;
startMessage.style.display = 'none';
} else if (gameActive && e.code === 'Space') {
player.jump();
} else if (!gameActive && gameStarted) {
resetGame();
}
});
// Spiel starten
gameLoop();
</script>
</body>
</html>