Erstes Release: Schildkröte überquert den Fluss 🐢
This commit is contained in:
421
index.html
Normal file
421
index.html
Normal file
@@ -0,0 +1,421 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Schildkröte überquert den Fluss</title>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: linear-gradient(to bottom, #87CEEB, #E0F7FA);
|
||||
font-family: 'Arial', sans-serif;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
}
|
||||
#game-container {
|
||||
position: relative;
|
||||
margin-top: 20px;
|
||||
}
|
||||
canvas {
|
||||
border: 4px solid #333;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
||||
background: linear-gradient(to bottom, #4EC0CA 0%, #87CEEB 100%);
|
||||
}
|
||||
#ui {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
text-shadow: 1px 1px 2px white;
|
||||
}
|
||||
#game-over {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
#game-over h2 {
|
||||
font-size: 48px;
|
||||
color: #D32F2F;
|
||||
text-shadow: 2px 2px 4px rgba(0,0,0,0.5);
|
||||
}
|
||||
#game-over button {
|
||||
font-size: 24px;
|
||||
padding: 12px 32px;
|
||||
border: 3px solid #333;
|
||||
border-radius: 8px;
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
#game-over button:hover {
|
||||
background: #45a049;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
#instructions {
|
||||
position: fixed;
|
||||
bottom: 20px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: rgba(255,255,255,0.9);
|
||||
padding: 12px 24px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
border: 2px solid #333;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="color: #1565C0; margin: 20px 0; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);">
|
||||
🐢 Schildkröte überquert den Fluss 🐊
|
||||
</h1>
|
||||
|
||||
<div id="game-container">
|
||||
<canvas id="gameCanvas" width="800" height="600"></canvas>
|
||||
<div id="ui">
|
||||
<div>Level: <span id="level">1</span></div>
|
||||
<div>Punkte: <span id="score">0</span></div>
|
||||
<div>Leben: <span id="lives">3</span></div>
|
||||
</div>
|
||||
<div id="game-over">
|
||||
<h2 id="game-over-title">Spiel vorbei!</h2>
|
||||
<p style="font-size: 24px; color: #333;">Dein Ergebnis: <span id="final-score">0</span> Punkte</p>
|
||||
<button onclick="restartGame()">Nochmal spielen</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="instructions">
|
||||
Benutze die Pfeiltasten ⬅️⬆️➡️ zum Bewegen
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const canvas = document.getElementById('gameCanvas');
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
// Spielzustand
|
||||
let gameRunning = true;
|
||||
let score = 0;
|
||||
let level = 1;
|
||||
let lives = 3;
|
||||
|
||||
// Schildkröte (Spieler)
|
||||
const player = {
|
||||
x: canvas.width / 2 - 25,
|
||||
y: canvas.height - 70,
|
||||
width: 50,
|
||||
height: 50,
|
||||
speed: 5,
|
||||
dx: 0,
|
||||
dy: 0
|
||||
};
|
||||
|
||||
// Flusslinien (Bäume)
|
||||
const rivers = [];
|
||||
const numRivers = 5;
|
||||
|
||||
// Bäume (Hindernisse)
|
||||
const trees = [];
|
||||
const numTrees = 10;
|
||||
|
||||
// Aligatoren (Gegner)
|
||||
const alligators = [];
|
||||
const numAlligators = 8;
|
||||
|
||||
// Initialisierung
|
||||
function initGame() {
|
||||
rivers.length = 0;
|
||||
for (let i = 0; i < numRivers; i++) {
|
||||
rivers.push({
|
||||
y: canvas.height - 150 - (i * 60),
|
||||
width: 40 + Math.random() * 30,
|
||||
speed: 1 + Math.random() * 1.5,
|
||||
direction: i % 2 === 0 ? 1 : -1,
|
||||
items: []
|
||||
});
|
||||
|
||||
// Bäume pro Fluss
|
||||
const numTreesInRiver = 2 + Math.floor(Math.random() * 3);
|
||||
for (let j = 0; j < numTreesInRiver; j++) {
|
||||
rivers[i].items.push({
|
||||
x: Math.random() * (canvas.width - 60),
|
||||
width: 40 + Math.random() * 30,
|
||||
type: 'tree'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
trees.length = 0;
|
||||
for (let i = 0; i < numTrees; i++) {
|
||||
trees.push({
|
||||
x: Math.random() * (canvas.width - 50),
|
||||
y: 150 + Math.random() * (canvas.height - 300),
|
||||
width: 50,
|
||||
height: 60
|
||||
});
|
||||
}
|
||||
|
||||
alligators.length = 0;
|
||||
for (let i = 0; i < numAlligators; i++) {
|
||||
alligators.push({
|
||||
x: Math.random() * canvas.width,
|
||||
y: 200 + Math.random() * 200,
|
||||
width: 60,
|
||||
height: 30,
|
||||
speed: 1.5 + Math.random(),
|
||||
direction: i % 2 === 0 ? 1 : -1
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Tastensteuerung
|
||||
const keys = {};
|
||||
window.addEventListener('keydown', e => keys[e.key] = true);
|
||||
window.addEventListener('keyup', e => keys[e.key] = false);
|
||||
|
||||
// Eingabeverarbeitung
|
||||
function handleInput() {
|
||||
if (!gameRunning) return;
|
||||
|
||||
if (keys['ArrowLeft']) player.x -= player.speed;
|
||||
if (keys['ArrowRight']) player.x += player.speed;
|
||||
if (keys['ArrowUp']) player.y -= player.speed;
|
||||
if (keys['ArrowDown']) player.y += player.speed;
|
||||
|
||||
// Grenzen
|
||||
if (player.x < 0) player.x = 0;
|
||||
if (player.x > canvas.width - player.width) player.x = canvas.width - player.width;
|
||||
if (player.y < 0) player.y = 0;
|
||||
if (player.y > canvas.height - player.height) player.y = canvas.height - player.height;
|
||||
}
|
||||
|
||||
// Aligatoren bewegen
|
||||
function moveAlligators() {
|
||||
alligators.forEach(alligator => {
|
||||
alligator.x += alligator.speed * alligator.direction;
|
||||
|
||||
// zurückspringen am Rand
|
||||
if (alligator.x < -50) alligator.x = canvas.width;
|
||||
if (alligator.x > canvas.width) alligator.x = -50;
|
||||
});
|
||||
}
|
||||
|
||||
// Bäume bewegen
|
||||
function moveRivers() {
|
||||
rivers.forEach(river => {
|
||||
river.items.forEach(item => {
|
||||
item.x += river.speed * river.direction;
|
||||
if (item.x < -100) item.x = canvas.width;
|
||||
if (item.x > canvas.width) item.x = -100;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Kollisionserkennung
|
||||
function checkCollisions() {
|
||||
// Aligatoren
|
||||
alligators.forEach(alligator => {
|
||||
if (player.x < alligator.x + alligator.width &&
|
||||
player.x + player.width > alligator.x &&
|
||||
player.y < alligator.y + alligator.height &&
|
||||
player.y + player.height > alligator.y) {
|
||||
loseLife();
|
||||
}
|
||||
});
|
||||
|
||||
// Bäume (Flüsse)
|
||||
rivers.forEach(river => {
|
||||
if (player.y > 150 && player.y < canvas.height - 150) {
|
||||
river.items.forEach(item => {
|
||||
if (player.x < item.x + item.width &&
|
||||
player.x + player.width > item.x &&
|
||||
player.y < river.y &&
|
||||
player.y + player.height > river.y - 40) {
|
||||
loseLife();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Ziel erreicht?
|
||||
if (player.y < 50) {
|
||||
levelUp();
|
||||
}
|
||||
}
|
||||
|
||||
function loseLife() {
|
||||
lives--;
|
||||
document.getElementById('lives').textContent = lives;
|
||||
player.x = canvas.width / 2 - 25;
|
||||
player.y = canvas.height - 70;
|
||||
|
||||
if (lives <= 0) {
|
||||
gameOver();
|
||||
}
|
||||
}
|
||||
|
||||
function levelUp() {
|
||||
level++;
|
||||
score += 100;
|
||||
document.getElementById('level').textContent = level;
|
||||
document.getElementById('score').textContent = score;
|
||||
|
||||
// Schwierigkeit erhöhen
|
||||
player.speed += 0.5;
|
||||
|
||||
//Reset Player
|
||||
player.x = canvas.width / 2 - 25;
|
||||
player.y = canvas.height - 70;
|
||||
|
||||
// Aligatoren beschleunigen
|
||||
alligators.forEach(a => a.speed += 0.3);
|
||||
}
|
||||
|
||||
// Zeichnen
|
||||
function draw() {
|
||||
// Hintergrund
|
||||
ctx.fillStyle = '#4EC0CA';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Startzone (Gras)
|
||||
ctx.fillStyle = '#4CAF50';
|
||||
ctx.fillRect(0, canvas.height - 100, canvas.width, 50);
|
||||
|
||||
// Zielzone (Gras oben)
|
||||
ctx.fillStyle = '#4CAF50';
|
||||
ctx.fillRect(0, 0, canvas.width, 50);
|
||||
ctx.fillStyle = '#2E7D32';
|
||||
ctx.fillText('🏆 ZIEL 🏆', canvas.width/2 - 50, 30);
|
||||
|
||||
// Flüsse
|
||||
ctx.fillStyle = '#2196F3';
|
||||
rivers.forEach(river => {
|
||||
ctx.fillRect(0, river.y - 40, canvas.width, 40);
|
||||
});
|
||||
|
||||
// Bäume
|
||||
rivers.forEach(river => {
|
||||
river.items.forEach(item => {
|
||||
// Baumstamm
|
||||
ctx.fillStyle = '#795548';
|
||||
ctx.fillRect(item.x, river.y - 50, item.width, 10);
|
||||
// Blätter
|
||||
ctx.fillStyle = '#2E7D32';
|
||||
ctx.beginPath();
|
||||
ctx.arc(item.x + item.width/2, river.y - 70, 15, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
});
|
||||
});
|
||||
|
||||
// Aligatoren
|
||||
alligators.forEach(alligator => {
|
||||
// Körper
|
||||
ctx.fillStyle = '#388E3C';
|
||||
ctx.fillRect(alligator.x, alligator.y, alligator.width, alligator.height);
|
||||
// Kopf
|
||||
ctx.fillStyle = '#1B5E20';
|
||||
ctx.fillRect(alligator.x - 10, alligator.y + 5, 20, 20);
|
||||
// Augen
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.fillRect(alligator.x - 5, alligator.y + 8, 5, 5);
|
||||
ctx.fillRect(alligator.x + 5, alligator.y + 8, 5, 5);
|
||||
// Zähne
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(alligator.x - 5, alligator.y + 25);
|
||||
ctx.lineTo(alligator.x, alligator.y + 30);
|
||||
ctx.lineTo(alligator.x + 5, alligator.y + 25);
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
// Schildkröte
|
||||
ctx.fillStyle = '#333'; // Panzer
|
||||
ctx.beginPath();
|
||||
ctx.ellipse(player.x + player.width/2, player.y + player.height/2, player.width/2, player.height/2, 0, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
// Kopf
|
||||
ctx.fillStyle = '#689F38';
|
||||
ctx.beginPath();
|
||||
ctx.arc(player.x + player.width/2, player.y + player.height - 10, 12, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
// Beine
|
||||
ctx.fillStyle = '#689F38';
|
||||
ctx.fillRect(player.x, player.y + 25, 10, 15);
|
||||
ctx.fillRect(player.x + player.width - 10, player.y + 25, 10, 15);
|
||||
|
||||
// Wolkeneffekt (Hintergrund)
|
||||
ctx.fillStyle = 'rgba(255,255,255,0.6)';
|
||||
ctx.beginPath();
|
||||
ctx.arc(100, 100, 30, 0, Math.PI * 2);
|
||||
ctx.arc(140, 100, 40, 0, Math.PI * 2);
|
||||
ctx.arc(180, 100, 30, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(canvas.width - 150, 150, 35, 0, Math.PI * 2);
|
||||
ctx.arc(canvas.width - 100, 150, 45, 0, Math.PI * 2);
|
||||
ctx.arc(canvas.width - 50, 150, 35, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Spiel-Loop
|
||||
function gameLoop() {
|
||||
if (!gameRunning) return;
|
||||
|
||||
handleInput();
|
||||
moveAlligators();
|
||||
moveRivers();
|
||||
checkCollisions();
|
||||
draw();
|
||||
|
||||
requestAnimationFrame(gameLoop);
|
||||
}
|
||||
|
||||
function gameOver() {
|
||||
gameRunning = false;
|
||||
document.getElementById('game-over').style.display = 'block';
|
||||
document.getElementById('final-score').textContent = score;
|
||||
}
|
||||
|
||||
function restartGame() {
|
||||
score = 0;
|
||||
level = 1;
|
||||
lives = 3;
|
||||
player.speed = 5;
|
||||
document.getElementById('level').textContent = level;
|
||||
document.getElementById('score').textContent = score;
|
||||
document.getElementById('lives').textContent = lives;
|
||||
document.getElementById('game-over').style.display = 'none';
|
||||
|
||||
// Reset
|
||||
player.x = canvas.width / 2 - 25;
|
||||
player.y = canvas.height - 70;
|
||||
|
||||
alligators.forEach(a => {
|
||||
a.speed = 1.5 + Math.random();
|
||||
a.x = Math.random() * canvas.width;
|
||||
});
|
||||
|
||||
gameRunning = true;
|
||||
initGame();
|
||||
gameLoop();
|
||||
}
|
||||
|
||||
// Start
|
||||
initGame();
|
||||
gameLoop();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user