Neu: Emoji Doodle Jump
This commit is contained in:
parent
e83fd047eb
commit
efcc822b0a
321
emoji_jump/index.html
Normal file
321
emoji_jump/index.html
Normal file
@ -0,0 +1,321 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Emoji Doodle Jump</title>
|
||||
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
background: #f0f0f0;
|
||||
font-family: Arial, sans-serif;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
#gameContainer {
|
||||
position: relative;
|
||||
width: 320px;
|
||||
height: 480px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
background: linear-gradient(#87CEEB, #E0F6FF);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#lives {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
#score {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
font-size: 24px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.popup {
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 0 20px rgba(0,0,0,0.2);
|
||||
text-align: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#charSelect {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
font-size: 40px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.emoji:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
button {
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 10px 20px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
#instructions {
|
||||
max-width: 320px;
|
||||
margin: 20px auto;
|
||||
padding: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="gameContainer">
|
||||
<div id="lives">❤️❤️❤️</div>
|
||||
<div id="score">0</div>
|
||||
<canvas id="canvas" width="320" height="480"></canvas>
|
||||
</div>
|
||||
|
||||
<div id="charSelectPopup" class="popup">
|
||||
<h3>Wähle deinen Charakter!</h3>
|
||||
<div id="charSelect">
|
||||
<div class="emoji">💩</div>
|
||||
<div class="emoji">🤡</div>
|
||||
<div class="emoji">👾</div>
|
||||
<div class="emoji">🍌</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="gameOverPopup" class="popup">
|
||||
<h3>Game Over!</h3>
|
||||
<p>Highscore: <span id="highscore">0</span></p>
|
||||
<button onclick="takeScreenshot()">Screenshot</button>
|
||||
<button onclick="startGame()">Neustart</button>
|
||||
</div>
|
||||
|
||||
<div id="instructions">
|
||||
<h3>Anleitung:</h3>
|
||||
<p>Steuere mit Maus/Touch nach links/rechts<br>
|
||||
Sammle Punkte indem du höher springst<br>
|
||||
Vermeide Gegner 💀👻👽<br>
|
||||
Zerbrechliche Plattformen brechen!<br>
|
||||
3 Leben ❤️ - Bei 0 ist Spiel vorbei</p>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
let canvas = document.getElementById('canvas');
|
||||
let ctx = canvas.getContext('2d');
|
||||
let player = { x: 160, y: 400, vy: 0, character: '🍌' };
|
||||
let platforms = [];
|
||||
let enemies = [];
|
||||
let lives = 3;
|
||||
let score = 0;
|
||||
let highscore = localStorage.getItem('highscore') || 0;
|
||||
let touchStartX = 0;
|
||||
|
||||
function init() {
|
||||
document.getElementById('charSelectPopup').style.display = 'block';
|
||||
}
|
||||
|
||||
function startGame() {
|
||||
document.getElementById('gameOverPopup').style.display = 'none';
|
||||
document.getElementById('charSelectPopup').style.display = 'block';
|
||||
}
|
||||
|
||||
function initGame() {
|
||||
document.getElementById('charSelectPopup').style.display = 'none';
|
||||
lives = 3;
|
||||
score = 0;
|
||||
player.y = 400;
|
||||
player.vy = -8;
|
||||
platforms = [];
|
||||
enemies = [];
|
||||
|
||||
// Initialplatformen unter dem Spieler
|
||||
for(let i = 0; i < 8; i++) {
|
||||
platforms.push({
|
||||
x: Math.random() * 290,
|
||||
y: 400 + i * 80,
|
||||
type: Math.random() < 0.2 && i > 2 ? 'breaking' : 'normal'
|
||||
});
|
||||
}
|
||||
|
||||
// Positioniere Spieler auf erster Plattform
|
||||
player.x = platforms[0].x + 30;
|
||||
player.y = platforms[0].y - 30;
|
||||
|
||||
gameLoop();
|
||||
updateDisplay();
|
||||
}
|
||||
|
||||
function gameLoop() {
|
||||
update();
|
||||
draw();
|
||||
if(lives > 0) requestAnimationFrame(gameLoop);
|
||||
else showGameOver();
|
||||
}
|
||||
|
||||
function update() {
|
||||
// Physik-Update
|
||||
player.y += player.vy;
|
||||
player.vy += 0.2;
|
||||
|
||||
// Begrenze X-Position des Spielers
|
||||
player.x = Math.max(20, Math.min(300, player.x));
|
||||
|
||||
// Plattform-Kollision
|
||||
platforms.forEach((p, i) => {
|
||||
if(player.vy > 0 &&
|
||||
player.x + 20 > p.x &&
|
||||
player.x - 20 < p.x + 60 &&
|
||||
player.y + 40 > p.y &&
|
||||
player.y + 40 < p.y + 15) {
|
||||
if(p.type === 'breaking') platforms.splice(i, 1);
|
||||
player.vy = -8;
|
||||
score += 10;
|
||||
updateDisplay();
|
||||
}
|
||||
});
|
||||
|
||||
// Plattform-Generierung
|
||||
if (platforms.length > 0) { // Prüfe ob Plattformen existieren
|
||||
let lowestPlatform = Math.max(...platforms.map(p => p.y));
|
||||
while(platforms.length < 15) {
|
||||
const newY = Math.min(...platforms.map(p => p.y)) - 80;
|
||||
platforms.unshift({
|
||||
x: Math.random() * 290,
|
||||
y: newY,
|
||||
type: Math.random() < (score > 500 ? 0.4 : score > 200 ? 0.3 : 0.2) ? 'breaking' : 'normal'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Entferne alte Plattformen
|
||||
platforms = platforms.filter(p => p.y < 600);
|
||||
|
||||
// Gegner-Logik
|
||||
enemies.forEach((e, i) => {
|
||||
if(Math.abs(player.x - e.x) < 30 && Math.abs(player.y - e.y) < 30) {
|
||||
lives--;
|
||||
enemies.splice(i, 1);
|
||||
updateDisplay();
|
||||
}
|
||||
e.x += e.vx;
|
||||
if(e.x < 0 || e.x > 300) e.vx *= -1;
|
||||
});
|
||||
|
||||
// Generiere neue Gegner
|
||||
if(Math.random() < 0.005 && score > 200 && enemies.length < 3) { // Reduzierte Wahrscheinlichkeit und max 3 Gegner
|
||||
enemies.push({
|
||||
x: Math.random() * 300,
|
||||
y: player.y - 500,
|
||||
vx: Math.random() * 2 - 1 // Langsamere Bewegung
|
||||
});
|
||||
}
|
||||
|
||||
// Entferne Gegner die zu weit unten sind
|
||||
enemies = enemies.filter(e => e.y < 600);
|
||||
|
||||
// Bildlauf-System
|
||||
if(player.y < 200) {
|
||||
const scrollAmount = Math.floor(200 - player.y);
|
||||
player.y = 200;
|
||||
platforms.forEach(p => p.y += scrollAmount);
|
||||
enemies.forEach(e => e.y += scrollAmount);
|
||||
score = Math.floor(score + scrollAmount);
|
||||
}
|
||||
|
||||
// Spielende-Check
|
||||
if(player.y > 600) lives = 0;
|
||||
}
|
||||
|
||||
function draw() {
|
||||
ctx.clearRect(0, 0, 320, 480);
|
||||
|
||||
// Zeichne Plattformen
|
||||
platforms.forEach(p => {
|
||||
ctx.fillStyle = p.type === 'breaking' ? '#ff5555' : '#55ff55';
|
||||
ctx.fillRect(p.x, p.y, 60, 10);
|
||||
});
|
||||
|
||||
// Zeichne Gegner
|
||||
enemies.forEach(e => {
|
||||
ctx.font = '30px Arial';
|
||||
ctx.fillText(['💀','👻','👽'][Math.floor(Math.random()*3)], e.x, e.y);
|
||||
});
|
||||
|
||||
// Zeichne Spieler
|
||||
ctx.font = '40px Arial';
|
||||
ctx.fillText(player.character, player.x-20, player.y);
|
||||
}
|
||||
|
||||
function updateDisplay() {
|
||||
document.getElementById('score').textContent = Math.floor(score);
|
||||
document.getElementById('lives').innerHTML = '❤️'.repeat(lives) + '🖤'.repeat(3-lives);
|
||||
if(score > highscore) {
|
||||
highscore = Math.floor(score);
|
||||
localStorage.setItem('highscore', highscore);
|
||||
}
|
||||
}
|
||||
|
||||
function showGameOver() {
|
||||
document.getElementById('gameOverPopup').style.display = 'block';
|
||||
document.getElementById('highscore').textContent = highscore;
|
||||
}
|
||||
|
||||
function takeScreenshot() {
|
||||
html2canvas(document.querySelector("#gameContainer")).then(canvas => {
|
||||
let link = document.createElement('a');
|
||||
link.download = 'doodle-score.png';
|
||||
link.href = canvas.toDataURL();
|
||||
link.click();
|
||||
});
|
||||
}
|
||||
|
||||
// Event Listeners
|
||||
document.getElementById('charSelect').addEventListener('click', (e) => {
|
||||
if(e.target.classList.contains('emoji')) {
|
||||
player.character = e.target.textContent;
|
||||
initGame();
|
||||
}
|
||||
});
|
||||
|
||||
// Controls
|
||||
canvas.addEventListener('mousedown', e => {
|
||||
touchStartX = e.clientX;
|
||||
});
|
||||
|
||||
canvas.addEventListener('mousemove', e => {
|
||||
if(e.buttons === 1) {
|
||||
player.x += e.movementX;
|
||||
}
|
||||
});
|
||||
|
||||
canvas.addEventListener('touchstart', e => {
|
||||
touchStartX = e.touches[0].clientX;
|
||||
});
|
||||
|
||||
canvas.addEventListener('touchmove', e => {
|
||||
let touch = e.touches[0];
|
||||
player.x += touch.clientX - touchStartX;
|
||||
touchStartX = touch.clientX;
|
||||
e.preventDefault();
|
||||
}, { passive: false });
|
||||
|
||||
init();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -206,6 +206,10 @@
|
||||
<div class="category-section">
|
||||
<h2 class="category-title">🎮 Spiele</h2>
|
||||
<div class="tools-grid">
|
||||
<a href="https://tools.ponywave.de/emoji_jump" class="tool-bubble">
|
||||
<h2 class="tool-title">Emoji Doodle Jump</h2>
|
||||
<p class="tool-description">Ein Doodle Jump Klon mit Emojis als Charaktere</p>
|
||||
</a>
|
||||
<a href="https://tools.ponywave.de/2048" class="tool-bubble">
|
||||
<h2 class="tool-title">2048</h2>
|
||||
<p class="tool-description">2048 in HTML</p>
|
||||
|
Loading…
x
Reference in New Issue
Block a user