🎮ArcadeLab

Pinguin Jump Premium Deluxe Edition

by NovaGalaxy88
723 lines23.5 KB
▶ Play
<!DOCTYPE html>
<html lang="de">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Pinguin Jump Premium Deluxe Edition</title>
    <style>
        * {
            box-sizing: border-box;
            user-select: none;
        }
        body {
            margin: 0;
            padding: 0;
            font-family: 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
            overflow: hidden;
            background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            height: 100vh;
        }
        #game {
            position: relative;
            width: 800px;
            height: 400px;
            background: linear-gradient(180deg, #111d42 0%, #1f376d 40%, #43649f 70%, #85aed4 100%);
            overflow: hidden;
            border: 4px solid #fff;
            border-radius: 16px;
            box-shadow: 0 20px 50px rgba(0,0,0,0.5);
        }
        .star {
            position: absolute;
            background: white;
            border-radius: 50%;
            animation: twinkle 3s infinite ease-in-out;
        }
        @keyframes twinkle {
            0%, 100% { opacity: 0.3; }
            50% { opacity: 1; }
        }
        .cloud {
            position: absolute;
            background: rgba(255, 255, 255, 0.25);
            border-radius: 50px;
            pointer-events: none;
        }
        #startScreen, #gameoverScreen, #pauseScreen {
            position: absolute;
            width: 100%;
            height: 100%;
            background: rgba(10, 15, 30, 0.85);
            backdrop-filter: blur(6px);
            display: flex;
            flex-direction: column;
            justify-content: center;
            align-items: center;
            color: white;
            z-index: 100;
            transition: all 0.3s ease;
        }
        #gameoverScreen, #pauseScreen {
            display: none;
        }
        h1, h2 {
            margin: 0 0 10px 0;
            font-size: 42px;
            text-transform: uppercase;
            letter-spacing: 3px;
            text-shadow: 0 4px 10px rgba(0,0,0,0.5);
            background: linear-gradient(45deg, #00f2fe, #4facfe);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        h2 { font-size: 36px; background: linear-gradient(45deg, #ff416c, #ff4b2b); -webkit-background-clip: text; }
        .menu-btn {
            margin: 8px;
            padding: 12px 28px;
            font-size: 18px;
            font-weight: bold;
            border: none;
            border-radius: 30px;
            cursor: pointer;
            background: linear-gradient(90deg, #00f2fe, #4facfe);
            color: white;
            box-shadow: 0 4px 15px rgba(0,242,254,0.4);
            transition: transform 0.2s, box-shadow 0.2s;
        }
        .menu-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(0,242,254,0.6);
        }
        .menu-btn:active { transform: translateY(1px); }
        #ground {
            position: absolute;
            bottom: 0;
            width: 1600px;
            height: 80px;
            background: linear-gradient(180deg, #e6f7ff 0%, #adc6ff 100%);
            border-top: 4px solid #fff;
            box-shadow: inset 0 5px 10px rgba(0,0,0,0.1);
        }
        #penguin {
            position: absolute;
            bottom: 80px;
            left: 120px;
            font-size: 55px;
            width: 55px;
            height: 55px;
            line-height: 55px;
            text-align: center;
            z-index: 20;
            transform-origin: center bottom;
        }
        .penguin-run { animation: waddle 0.3s infinite alternate ease-in-out; }
        @keyframes waddle {
            0% { transform: rotate(-6deg); }
            100% { transform: rotate(6deg); }
        }
        .obstacle {
            position: absolute;
            bottom: 80px;
            z-index: 15;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .rock {
            width: 45px;
            height: 40px;
            background: linear-gradient(135deg, #757f9a, #4a5061);
            border: 2px solid #fff;
            border-radius: 60% 60% 40% 40%;
            box-shadow: 0 4px 8px rgba(0,0,0,0.3);
        }
        .stick {
            width: 20px;
            height: 65px;
            background: linear-gradient(90deg, #a86032, #6e3b1c);
            border: 2px solid #fff;
            border-radius: 6px;
            box-shadow: 4px 4px 8px rgba(0,0,0,0.3);
        }
        .icicle {
            width: 25px;
            height: 50px;
            background: linear-gradient(180deg, #e0f7fa, #80deea);
            clip-path: polygon(50% 100%, 0 0, 100% 0);
            border: 1px solid #fff;
        }
        .coin-pickup {
            position: absolute;
            width: 25px;
            height: 25px;
            background: radial-gradient(circle, #ffe066, #f5b041);
            border: 2px solid #fff;
            border-radius: 50%;
            z-index: 12;
            animation: coinSpin 0.6s infinite linear;
            box-shadow: 0 2px 6px rgba(245,176,65,0.6);
        }
        @keyframes coinSpin {
            0% { transform: scaleX(1); }
            50% { transform: scaleX(0); }
            100% { transform: scaleX(1); }
        }
        .particle {
            position: absolute;
            border-radius: 50%;
            pointer-events: none;
            z-index: 25;
        }
        #ui {
            position: absolute;
            top: 15px;
            left: 15px;
            color: white;
            font-weight: bold;
            font-size: 16px;
            z-index: 50;
            background: rgba(0, 0, 0, 0.4);
            padding: 10px 15px;
            border-radius: 12px;
            border: 1px solid rgba(255,255,255,0.2);
            backdrop-filter: blur(4px);
            line-height: 1.5;
        }
        #ui span {
            color: #00f2fe;
            font-family: monospace;
            font-size: 18px;
        }
        #ui #coins { color: #ffd700; }
        #ui #level { color: #ff4b2b; }
        #topControls {
            position: absolute;
            top: 15px;
            right: 15px;
            display: flex;
            gap: 10px;
            z-index: 110; /* Z-Index erhöht, damit der Shop-Button über den Screens liegt */
        }
        .ctrl-btn {
            padding: 10px 16px;
            background: rgba(255,255,255,0.2);
            border: 1px solid rgba(255,255,255,0.4);
            color: white;
            font-weight: bold;
            border-radius: 10px;
            cursor: pointer;
            backdrop-filter: blur(4px);
            transition: background 0.2s;
        }
        .ctrl-btn:hover { background: rgba(255,255,255,0.4); }
        #shopPanel {
            position: absolute;
            top: 70px;
            right: 15px;
            background: rgba(255, 255, 255, 0.95);
            padding: 15px;
            border-radius: 14px;
            display: none;
            box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            z-index: 120; /* Z-Index erhöht, damit der Shop über dem Gameover-Screen liegt */
            width: 260px;
            border: 2px solid #4facfe;
        }
        .shop-title {
            font-weight: bold;
            color: #333;
            margin-bottom: 10px;
            text-align: center;
            border-bottom: 1px solid #ddd;
            padding-bottom: 5px;
        }
        .shop-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: 8px 0;
            padding: 6px;
            background: #f7f9fa;
            border-radius: 8px;
            color: #333;
        }
        .shop-item button {
            padding: 6px 12px;
            background: #4facfe;
            border: none;
            color: white;
            font-weight: bold;
            border-radius: 6px;
            cursor: pointer;
        }
        .shop-item button.owned {
            background: #6c757d;
        }
        #jumpBtn {
            position: absolute;
            bottom: 95px;
            right: 25px;
            width: 75px;
            height: 75px;
            border-radius: 50%;
            border: 3px solid white;
            background: linear-gradient(135deg, #4facfe, #00f2fe);
            font-size: 32px;
            color: white;
            cursor: pointer;
            z-index: 50;
            display: flex;
            justify-content: center;
            align-items: center;
            box-shadow: 0 6px 15px rgba(0,0,0,0.3);
        }
        #jumpBtn:active { transform: scale(0.95); }
        #statsContainer {
            margin-top: 15px;
            font-size: 18px;
            color: #ddd;
            text-align: center;
        }
        .instructions {
            margin-top: 20px;
            font-size: 14px;
            color: #aaa;
            text-align: center;
            max-width: 80%;
        }
    </style>
</head>
<body>

<div id="game">
    <div id="starsContainer"></div>
    <div id="cloudsContainer"></div>

    <div id="startScreen">
        <h1>Pinguin Jump</h1>
        <p style="color: #4facfe; font-size: 18px; margin: 0 0 20px 0;">Premium Arcade Edition</p>
        <button class="menu-btn" onclick="startGame()">SPIEL STARTEN</button>
        <div class="instructions">Steuerung: Leertaste, Pfeiltaste Nach Oben oder Klick auf den großen blauen Button zum Springen. Weiche Hindernissen aus und sammle goldene Münzen!</div>
    </div>

    <div id="pauseScreen">
        <h1>PAUSE</h1>
        <button class="menu-btn" onclick="togglePause()">WEITER</button>
        <button class="menu-btn" style="background:linear-gradient(90deg, #ff416c, #ff4b2b); box-shadow:0 4px 15px rgba(255,65,108,0.4);" onclick="resetToMenu()">MENU</button>
    </div>

    <div id="gameoverScreen">
        <h2>GAME OVER</h2>
        <div id="statsContainer">
            <div>Erreichte Punkte: <span id="finalScore" style="color:#00f2fe; font-weight:bold;">0</span></div>
            <div>Gesammelte Münzen: <span id="finalCoins" style="color:#ffd700; font-weight:bold;">0</span></div>
        </div>
        <button class="menu-btn" onclick="startGame()">NOCHMAL SPIELEN</button>
        <button class="menu-btn" style="background:linear-gradient(90deg, #ffb300, #f57c00); box-shadow:0 4px 15px rgba(245,124,0,0.4);" onclick="toggleShop()">SHOP ÖFFNEN</button>
        <button class="menu-btn" style="background:linear-gradient(90deg, #6c757d, #495057); box-shadow:0 4px 15px rgba(0,0,0,0.3);" onclick="resetToMenu()">HAUPTMENÜ</button>
    </div>

    <div id="ui">
        Score: <span id="score">0</span><br>
        Coins: <span id="coins">0</span><br>
        Level: <span id="level">1</span><br>
        Highscore: <span id="highscore">0</span>
    </div>

    <div id="topControls">
        <button class="ctrl-btn" onclick="togglePause()">&DoubleVerticalBar; Pause</button>
        <button class="ctrl-btn" onclick="toggleShop()">&#128092; Shop</button>
    </div>

    <div id="shopPanel">
        <div class="shop-title">Skin Boutique</div>
        <div class="shop-item">
            <span>&#128039; Standard</span>
            <button class="owned" onclick="selectSkin('&#128039;', 0, this)">Aktiv</button>
        </div>
        <div class="shop-item">
            <span>&#128049; Katze (50 C)</span>
            <button id="btn-skin-cat" onclick="buySkin('&#128049;', 50, 'btn-skin-cat')">Kaufen</button>
        </div>
        <div class="shop-item">
            <span>&#128009; Drache (120 C)</span>
            <button id="btn-skin-dragon" onclick="buySkin('&#128009;', 120, 'btn-skin-dragon')">Kaufen</button>
        </div>
        <div class="shop-item">
            <span>&#129302; Roboter (250 C)</span>
            <button id="btn-skin-robo" onclick="buySkin('&#129302;', 250, 'btn-skin-robo')">Kaufen</button>
        </div>
        <div class="shop-item">
            <span>&#129412; Einhorn (500 C)</span>
            <button id="btn-skin-unicorn" onclick="buySkin('&#129412;', 500, 'btn-skin-unicorn')">Kaufen</button>
        </div>
    </div>

    <div id="penguin" class="penguin-run">&#128039;</div>
    <div id="ground"></div>
    <button id="jumpBtn">&uparrow;</button>
</div>

<script>
let gameOver = true;
let isPaused = false;
let score = 0;
let coins = 0;
let highscore = 0;
let level = 1;
let speed = 6;
let velocity = 0;
const gravity = 0.75;
const groundHeight = 80;
let penguinY = 80;
let jumping = false;
let obstacleTimer = null;
let coinTimer = null;
let gameLoopInterval = null;
let currentSkin = "🐧";
let ownedSkins = ["🐧"];

const gameContainer = document.getElementById("game");
const penguin = document.getElementById("penguin");
const ground = document.getElementById("ground");

function initBackground() {
    const starsContainer = document.getElementById("starsContainer");
    starsContainer.innerHTML = "";
    for (let i = 0; i < 40; i++) {
        const star = document.createElement("div");
        star.className = "star";
        star.style.width = Math.random() * 3 + "px";
        star.style.height = star.style.width;
        star.style.left = Math.random() * 800 + "px";
        star.style.top = Math.random() * 220 + "px";
        star.style.animationDelay = Math.random() * 3 + "s";
        starsContainer.appendChild(star);
    }
    const cloudsContainer = document.getElementById("cloudsContainer");
    cloudsContainer.innerHTML = "";
    for (let i = 0; i < 4; i++) {
        createCloud(Math.random() * 800);
    }
}

function createCloud(startX = 800) {
    const cloudsContainer = document.getElementById("cloudsContainer");
    const cloud = document.createElement("div");
    cloud.className = "cloud";
    const width = Math.random() * 100 + 60;
    cloud.style.width = width + "px";
    cloud.style.height = (width * 0.4) + "px";
    cloud.style.left = startX + "px";
    cloud.style.top = Math.random() * 100 + 20 + "px";
    cloud.dataset.speed = Math.random() * 0.4 + 0.1;
    cloudsContainer.appendChild(cloud);
}

function updatePhysics() {
    if (gameOver || isPaused) return;
    if (jumping) {
        velocity -= gravity;
        penguinY += velocity;
        if (penguinY <= groundHeight) {
            penguinY = groundHeight;
            velocity = 0;
            jumping = false;
            penguin.classList.add("penguin-run");
        }
        penguin.style.bottom = penguinY + "px";
    }
    let groundLeft = parseFloat(ground.style.left) || 0;
    groundLeft -= speed;
    if (groundLeft <= -800) groundLeft = 0;
    ground.style.left = groundLeft + "px";

    const clouds = document.querySelectorAll(".cloud");
    clouds.forEach(cloud => {
        let left = parseFloat(cloud.style.left);
        left -= parseFloat(cloud.dataset.speed);
        if (left < -160) {
            cloud.remove();
            createCloud(800);
        } else {
            cloud.style.left = left + "px";
        }
    });

    const particles = document.querySelectorAll(".particle");
    particles.forEach(p => {
        let pX = parseFloat(p.style.left);
        let pY = parseFloat(p.style.top);
        let vX = parseFloat(p.dataset.vx);
        let vY = parseFloat(p.dataset.vy);
        pX += vX;
        pY += vY;
        vY += 0.2;
        p.style.left = pX + "px";
        p.style.top = pY + "px";
        p.dataset.vy = vY;
        let alpha = parseFloat(p.style.opacity) - 0.02;
        if (alpha <= 0) {
            p.remove();
        } else {
            p.style.opacity = alpha;
        }
    });
    checkCollisions();
}

function checkCollisions() {
    const pRect = penguin.getBoundingClientRect();
    const obstacles = document.querySelectorAll(".obstacle");
    obstacles.forEach(o => {
        let pos = parseFloat(o.style.left);
        pos -= speed;
        o.style.left = pos + "px";
        if (pos < -60) {
            o.remove();
            score++;
            document.getElementById("score").textContent = score;
            updateLevel();
            return;
        }
        const oRect = o.getBoundingClientRect();
        if (pRect.left < oRect.right - 12 &&
            pRect.right > oRect.left + 12 &&
            pRect.bottom > oRect.top + 10) {
            endGame();
        }
    });

    const coinsList = document.querySelectorAll(".coin-pickup");
    coinsList.forEach(c => {
        let pos = parseFloat(c.style.left);
        pos -= speed;
        c.style.left = pos + "px";
        if (pos < -40) {
            c.remove();
            return;
        }
        const cRect = c.getBoundingClientRect();
        if (pRect.left < cRect.right &&
            pRect.right > cRect.left &&
            pRect.bottom > cRect.top &&
            pRect.top < cRect.bottom) {
            createCollectParticles(cRect.left + 12, cRect.top + 12, "#ffd700");
            c.remove();
            coins += Math.floor(Math.random() * 3) + 2;
            document.getElementById("coins").textContent = coins;
        }
    });
}

function createObstacle() {
    if (gameOver || isPaused) return;
    const types = ["rock", "stick", "icicle"];
    const chosenType = types[Math.floor(Math.random() * types.length)];
    const o = document.createElement("div");
    o.className = "obstacle " + chosenType;
    o.style.left = "800px";
    gameContainer.appendChild(o);
}

function createCoin() {
    if (gameOver || isPaused) return;
    if (Math.random() < 0.6) {
        const c = document.createElement("div");
        c.className = "coin-pickup";
        c.style.left = "800px";
        const heightRand = Math.random();
        if (heightRand < 0.4) {
            c.style.bottom = "100px";
        } else if (heightRand < 0.8) {
            c.style.bottom = "180px";
        } else {
            c.style.bottom = "250px";
        }
        gameContainer.appendChild(c);
    }
}

function createCollectParticles(x, y, color) {
    const rect = gameContainer.getBoundingClientRect();
    const relativeX = x - rect.left;
    const relativeY = y - rect.top;
    for (let i = 0; i < 12; i++) {
        const p = document.createElement("div");
        p.className = "particle";
        p.style.width = Math.random() * 6 + 4 + "px";
        p.style.height = p.style.width;
        p.style.background = color;
        p.style.left = relativeX + "px";
        p.style.top = relativeY + "px";
        p.style.opacity = "1";
        const angle = Math.random() * Math.PI * 2;
        const velocityValue = Math.random() * 4 + 2;
        p.dataset.vx = Math.cos(angle) * velocityValue;
        p.dataset.vy = Math.sin(angle) * velocityValue;
        gameContainer.appendChild(p);
    }
}

function jump() {
    if (!gameOver && !isPaused && !jumping) {
        velocity = 14.5;
        jumping = true;
        penguin.classList.remove("penguin-run");
        penguin.style.transform = "scaleY(1.2)";
        setTimeout(() => { penguin.style.transform = "scaleY(1)"; }, 100);
    }
}

function updateLevel() {
    level = Math.floor(score / 8) + 1;
    document.getElementById("level").textContent = level;
    speed = 6 + level * 0.8;
    clearInterval(obstacleTimer);
    const newInterval = Math.max(800, 1600 - (level * 100));
    obstacleTimer = setInterval(createObstacle, newInterval);
}

function startGame() {
    document.getElementById("startScreen").style.display = "none";
    document.getElementById("gameoverScreen").style.display = "none";
    document.getElementById("pauseScreen").style.display = "none";
    document.getElementById("shopPanel").style.display = "none"; // Schließt den Shop beim Neustart
    document.querySelectorAll(".obstacle").forEach(e => e.remove());
    document.querySelectorAll(".coin-pickup").forEach(e => e.remove());
    document.querySelectorAll(".particle").forEach(e => e.remove());
    clearInterval(obstacleTimer);
    clearInterval(coinTimer);
    clearInterval(gameLoopInterval);
    gameOver = false;
    isPaused = false;
    score = 0;
    level = 1;
    speed = 6;
    penguinY = 80;
    velocity = 0;
    jumping = false;
    penguin.style.bottom = penguinY + "px";
    penguin.textContent = currentSkin;
    penguin.classList.add("penguin-run");
    document.getElementById("score").textContent = score;
    document.getElementById("coins").textContent = coins;
    document.getElementById("level").textContent = level;
    obstacleTimer = setInterval(createObstacle, 1600);
    coinTimer = setInterval(createCoin, 2000);
    gameLoopInterval = setInterval(updatePhysics, 1000 / 60);
}

function endGame() {
    gameOver = true;
    clearInterval(obstacleTimer);
    clearInterval(coinTimer);
    clearInterval(gameLoopInterval);
    penguin.classList.remove("penguin-run");
    if (score > highscore) {
        highscore = score;
        document.getElementById("highscore").textContent = highscore;
    }
    document.getElementById("finalScore").textContent = score;
    document.getElementById("finalCoins").textContent = coins;
    document.getElementById("gameoverScreen").style.display = "flex";
}

function togglePause() {
    if (gameOver) return;
    isPaused = !isPaused;
    if (isPaused) {
        document.getElementById("pauseScreen").style.display = "flex";
        penguin.classList.remove("penguin-run");
    } else {
        document.getElementById("pauseScreen").style.display = "none";
        if (!jumping) penguin.classList.add("penguin-run");
    }
}

function resetToMenu() {
    gameOver = true;
    isPaused = false;
    clearInterval(obstacleTimer);
    clearInterval(coinTimer);
    clearInterval(gameLoopInterval);
    document.getElementById("pauseScreen").style.display = "none";
    document.getElementById("gameoverScreen").style.display = "none";
    document.getElementById("shopPanel").style.display = "none";
    document.getElementById("startScreen").style.display = "flex";
}

function toggleShop() {
    const panel = document.getElementById("shopPanel");
    panel.style.display = panel.style.display === "block" ? "none" : "block";
}

function buySkin(skinEmoji, price, idName) {
    if (ownedSkins.includes(skinEmoji)) {
        currentSkin = skinEmoji;
        penguin.textContent = currentSkin;
        updateShopButtons();
        return;
    }
    if (coins >= price) {
        coins -= price;
        ownedSkins.push(skinEmoji);
        currentSkin = skinEmoji;
        penguin.textContent = currentSkin;
        document.getElementById("coins").textContent = coins;
        updateShopButtons();
    } else {
        alert("Du hast nicht genügend Münzen für diesen Skin!");
    }
}

function selectSkin(skinEmoji, price, element) {
    currentSkin = skinEmoji;
    penguin.textContent = currentSkin;
    updateShopButtons();
}

function updateShopButtons() {
    const skinsConfig = [
        { emoji: '🐱', id: 'btn-skin-cat' },
        { emoji: '🐉', id: 'btn-skin-dragon' },
        { emoji: '🤖', id: 'btn-skin-robo' },
        { emoji: '🦄', id: 'btn-skin-unicorn' }
    ];
    skinsConfig.forEach(item => {
        const btn = document.getElementById(item.id);
        if (btn) {
            if (currentSkin === item.emoji) {
                btn.textContent = "Aktiv";
                btn.className = "owned";
            } else if (ownedSkins.includes(item.emoji)) {
                btn.textContent = "Wählen";
                btn.className = "";
            }
        }
    });
}

window.addEventListener("keydown", (e) => {
    if (e.key === " " || e.key === "ArrowUp") {
        e.preventDefault();
        jump();
    }
    if (e.key === "p" || e.key === "P" || e.key === "Escape") {
        togglePause();
    }
});

document.getElementById("jumpBtn").addEventListener("click", (e) => {
    e.preventDefault();
    jump();
});

initBackground();
</script>
</body>
</html>

Game Source: Pinguin Jump Premium Deluxe Edition

Creator: NovaGalaxy88

Libraries: none

Complexity: complex (723 lines, 23.5 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: pinguin-jump-premium-deluxe-edition-novagalaxy88" to link back to the original. Then publish at arcadelab.ai/publish.