{"id":18,"date":"2025-02-22T17:03:45","date_gmt":"2025-02-22T17:03:45","guid":{"rendered":"http:\/\/diverse.anderskisling.dk\/?page_id=18"},"modified":"2025-05-02T19:49:22","modified_gmt":"2025-05-02T19:49:22","slug":"spil1","status":"publish","type":"page","link":"https:\/\/diverse.anderskisling.dk\/index.php\/spil1\/","title":{"rendered":"spil1"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"18\" class=\"elementor elementor-18\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ee13175 e-flex e-con-boxed e-con e-parent\" data-id=\"ee13175\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;video&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-6d10cc9 elementor-hidden-tablet elementor-hidden-mobile e-flex e-con-boxed e-con e-child\" data-id=\"6d10cc9\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-8171772 e-flex e-con-boxed e-con e-child\" data-id=\"8171772\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;video&quot;}\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-7931332 elementor-widget elementor-widget-spacer\" data-id=\"7931332\" data-element_type=\"widget\" data-widget_type=\"spacer.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-spacer\">\n\t\t\t<div class=\"elementor-spacer-inner\"><\/div>\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-c08ec61 e-con-full elementor-hidden-tablet elementor-hidden-mobile e-flex e-con e-child\" data-id=\"c08ec61\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t<div class=\"elementor-element elementor-element-8b0e3c7 e-con-full e-flex e-con e-child\" data-id=\"8b0e3c7\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;video&quot;}\">\n\t\t\t\t<div class=\"elementor-element elementor-element-1e7a0a6 e-transform elementor-widget elementor-widget-heading\" data-id=\"1e7a0a6\" data-element_type=\"widget\" data-settings=\"{&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.05,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">&gt; FIRE = Spacebar &lt;<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a3d5701 e-transform elementor-widget elementor-widget-heading\" data-id=\"a3d5701\" data-element_type=\"widget\" data-settings=\"{&quot;_transform_scale_effect_hover&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:1.05,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;_transform_scale_effect_hover_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]}}\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">&gt;  Move = Arrow keys or mouse&lt;<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t<div class=\"elementor-element elementor-element-15a62cc e-con-full e-flex e-con e-child\" data-id=\"15a62cc\" data-element_type=\"container\" data-settings=\"{&quot;background_background&quot;:&quot;video&quot;,&quot;background_video_link&quot;:&quot;http:\\\/\\\/diverse.anderskisling.dk\\\/wp-content\\\/uploads\\\/2025\\\/03\\\/gridmove-field1.mp4&quot;}\">\n\t\t<div class=\"elementor-background-video-container elementor-hidden-mobile\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t<video class=\"elementor-background-video-hosted\" autoplay muted playsinline loop><\/video>\n\t\t\t\t\t<\/div>\t\t<div class=\"elementor-element elementor-element-b56b845 elementor-widget elementor-widget-html\" data-id=\"b56b845\" data-element_type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<style>\n    @import url('https:\/\/fonts.googleapis.com\/css2?family=Silkscreen&display=swap');\n    \n    :root {\n        --game-over-text-size: 24px;\n        --final-score-size: 60px;\n        --try-again-button-size: 20px;\n    }\n    \n    #game-container {\n        position: relative;\n        display: flex;\n        flex-direction: column;\n        align-items: center;\n        justify-content: center;\n        height: 65vh;\n        width: 100%;\n    }\n    #gameCanvas {\n        background: transparent;\n    }\n    #score, #lives, #music-toggle {\n    color: #FFD678;\n    font-size: 24px;\n    margin-top: 9px;\n    font-family: 'Silkscreen', sans-serif;\n    text-shadow: 0 0 5px #FFA500, 0 0 10px #FF8C00, 0 0 15px #FF4500;  \/* Tilf\u00f8jer skygge *\/\n}\n    #music-toggle {\n        cursor: pointer;\n        user-select: none;\n    }\n    #game-over-overlay {\n        position: absolute;\n        top: 50%;\n        left: 50%;\n        transform: translate(-50%, -50%);\n        width: 512px;\n        height: 512px;\n        background-image: url('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/bg-gameend7.png');\n        background-size: cover;\n        display: none;\n        flex-direction: column;\n        justify-content: center;\n        align-items: center;\n        color: #fff5ef;\n        font-family: 'Silkscreen', sans-serif;\n        text-align: center;\n    }\n    #game-over-text {\n        font-size: var(--game-over-text-size);\n        margin-bottom: 20px;\n        text-shadow: 0 0 10px #00f, 0 0 20px #00f, 0 0 30px #00f, 0 0 40px #ff0;\n    }\n    #final-score {\n        font-size: var(--final-score-size);\n        margin-bottom: 20px;\n        text-shadow: 0 0 10px #00f, 0 0 20px #00f, 0 0 30px #00f, 0 0 40px #ff0;\n    }\n    #points-text {\n        font-size: var(--game-over-text-size);\n        margin-bottom: 20px;\n        text-shadow: 0 0 10px #00f, 0 0 20px #00f, 0 0 30px #00f, 0 0 40px #ff0;\n    }\n    #try-again-button {\n        font-size: var(--try-again-button-size);\n        padding: 10px 20px;\n        background-color: #00FB2D80;\n        border: none;\n        color: white;\n        cursor: pointer;\n        font-family: 'Silkscreen', sans-serif;\n    }\n<\/style>\n\n<div id=\"game-container\">\n    <canvas id=\"gameCanvas\" width=\"400\" height=\"600\"><\/canvas>\n    <div id=\"score\">Score: <span id=\"scoreValue\">0<\/span><\/div>\n    <div id=\"lives\">Lives: <span id=\"livesValue\">3<\/span><\/div>\n    <div id=\"music-toggle\">Music: OFF<\/div>\n    <div id=\"game-over-overlay\">\n        <div id=\"game-over-text\">Well done ! You got<\/div>\n        <div id=\"final-score\">0<\/div>\n        <div id=\"points-text\">Points !<\/div>\n        <button id=\"try-again-button\">TRY AGAIN ?<\/button>\n    <\/div>\n<\/div>\n\n<script>\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\nconst scoreElement = document.getElementById('scoreValue');\nconst livesElement = document.getElementById('livesValue');\nconst musicToggle = document.getElementById('music-toggle');\nconst endCounterSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/counter4lyd.mp3');\nendCounterSound.volume = 0.50;\nconst gameOverOverlay = document.getElementById('game-over-overlay');\nconst finalScoreElement = document.getElementById('final-score');\nconst tryAgainButton = document.getElementById('try-again-button');\n\nconst PROJECTILE_WIDTH = 5;\nconst PROJECTILE_HEIGHT = 10;\n\n\/\/ Load images\nconst playerImage = new Image();\nplayerImage.src = 'http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/kaboom-hero-x.png';\n\nconst playerRedImage = new Image();\nplayerRedImage.src = 'http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/kaboom-hero-x-hit.png';\n\nconst enemyImage = new Image();\nenemyImage.src = 'http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/kaboom-enemyx.png';\n\nconst enemyRedImage = new Image();\nenemyRedImage.src = 'http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/kaboom-enemy-redfinal-2.png';\n\n\/\/ Load sounds\nconst laserSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/laser1.mp3');\nlaserSound.volume = 0.33;\n\nconst backgroundMusic = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/Space-Funk-Odyssey2.mp3');\nbackgroundMusic.loop = true;\n\nconst bombDropSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/alienbombdrop2.mp3');\nbombDropSound.volume = 0.23;\n\nconst alienShootHitSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/alien-shoot-hit1.mp3');\nalienShootHitSound.volume = 0.70;\n\nconst alienDieWallSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/alien-die-wall.mp3');\nalienDieWallSound.volume = 0.33;\n\nconst heroMinusLifeSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/herominus-life.mp3');\nheroMinusLifeSound.volume = 1;\n\n\/\/ Reload lydeffekt\nconst reloadSound = new Audio('http:\/\/diverse.anderskisling.dk\/wp-content\/uploads\/2025\/02\/laser1.mp3');\nreloadSound.volume = 0.2;\n\n\/\/ Sound pools for polyphony\nconst createSoundPool = (sound, poolSize) => {\n    const pool = [];\n    for (let i = 0; i < poolSize; i++) {\n        const audio = sound.cloneNode();\n        audio.volume = sound.volume;\n        pool.push(audio);\n    }\n    return pool;\n};\n\nconst alienShootHitSoundPool = createSoundPool(alienShootHitSound, 5);\nconst alienDieWallSoundPool = createSoundPool(alienDieWallSound, 5);\nconst heroMinusLifeSoundPool = createSoundPool(heroMinusLifeSound, 3);\n\nconst playSound = (pool) => {\n    const availableSound = pool.find(sound => sound.paused);\n    if (availableSound) {\n        availableSound.currentTime = 0;\n        availableSound.play();\n    }\n};\n\nlet isMusicPlaying = false;\n\nmusicToggle.addEventListener('click', () => {\n    if (isMusicPlaying) {\n        backgroundMusic.pause();\n        musicToggle.textContent = 'Music: OFF';\n    } else {\n        backgroundMusic.play();\n        musicToggle.textContent = 'Music: ON';\n    }\n    isMusicPlaying = !isMusicPlaying;\n});\n\n\/\/ Spiller\nconst player = {\n    x: canvas.width \/ 2 - 15,\n    y: canvas.height - 85,\n    width: 35,\n    height: 35,\n    dx: 10,\n    lives: 3,\n    isBlinking: false,\n    blinkCount: 0,\n    blinkDuration: 100,\n    lastBlinkTime: 0,\n    ammo: 50,\n    maxAmmo: 50,\n    lastReloadTime: 0,\n    reloadInterval: 10000, \/\/ 10 sekunder\n    isReloading: false\n};\n\n\/\/ Projektil\nlet projectiles = [];\n\n\/\/ Fjender\nlet enemies = [];\n\n\/\/ Bomber\nlet bombs = [];\n\n\/\/ Mur\nconst wall = {\n    x: 0,\n    y: canvas.height - 130,\n    width: canvas.width,\n    height: 15,\n    segments: []\n};\n\n\/\/ Initialis\u00e9r mursegmenter\nfor (let i = 0; i < wall.width; i++) {\n    wall.segments.push(3);  \/\/ Muren starter med 3 i styrke for hvert segment\n}\n\n\/\/ Ammo Bar\nconst ammoBar = {\n    x: canvas.width \/ 2 - 40,\n    y: canvas.height - 25,\n    width: 60,\n    height: 5,\n    color: '#FF6633',\n borderColor: '#333333'\n\n    };\n\n\/\/ Spilvariabler\nlet score = 0;\nlet isGameOver = false;\nlet animationId;\n\nfunction drawPlayer() {\n    if (player.isBlinking) {\n        const currentTime = Date.now();\n        if (currentTime - player.lastBlinkTime > player.blinkDuration) {\n            player.blinkCount++;\n            player.lastBlinkTime = currentTime;\n        }\n        \n        if (player.blinkCount % 2 === 0) {\n            ctx.drawImage(playerRedImage, player.x, player.y, player.width, player.height);\n        } else {\n            ctx.drawImage(playerImage, player.x, player.y, player.width, player.height);\n        }\n        \n        if (player.blinkCount >= 6) {\n            player.isBlinking = false;\n            player.blinkCount = 0;\n        }\n    } else {\n        ctx.drawImage(playerImage, player.x, player.y, player.width, player.height);\n    }\n}\n\nfunction drawAmmoBar() {\n    \/\/ Tegn ramme\n    ctx.strokeStyle = ammoBar.borderColor;\n    ctx.lineWidth = 2;\n    ctx.strokeRect(ammoBar.x, ammoBar.y, ammoBar.width, ammoBar.height);\n    \n    \/\/ Beregn aktuel ammo-bredde baseret p\u00e5 tilg\u00e6ngelig ammunition\n    const currentAmmoWidth = (player.ammo \/ player.maxAmmo) * ammoBar.width;\n    \n    \/\/ Tegn ammo-niveau\n    ctx.fillStyle = player.isReloading ? '#FF6633' : ammoBar.color;\n    ctx.fillRect(ammoBar.x, ammoBar.y, currentAmmoWidth, ammoBar.height);\n    \n    \/\/ Tilf\u00f8j orange label under ammo-baren\n    ctx.fillStyle = '#FF6633'; \/\/ Orange farve\n    ctx.font = '18px Silkscreen, sans-serif';\n    ctx.textAlign = 'center';\n    ctx.fillText('AMMO', ammoBar.x + ammoBar.width\/2, ammoBar.y + ammoBar.height + 20);\n}\n\nfunction drawProjectiles() {\n    projectiles.forEach(proj => {\n        ctx.fillStyle = 'white';\n        ctx.fillRect(proj.x, proj.y, PROJECTILE_WIDTH, PROJECTILE_HEIGHT);\n    });\n}\n\nfunction drawEnemies() {\n    enemies.forEach(enemy => {\n        ctx.globalAlpha = enemy.type === 'special' && enemy.hits > 0 ? 0.5 : 1;\n        if (enemy.deathTime) {\n            const timeSinceDeath = Date.now() - enemy.deathTime;\n            const alpha = 1 - timeSinceDeath \/ 100;\n            ctx.globalAlpha = alpha;\n            ctx.fillStyle = enemy.type === 'regular' ? '#ffeea9' : '#ff6666';\n            ctx.beginPath();\n            ctx.arc(enemy.x + enemy.width \/ 2, enemy.y + enemy.height \/ 2, enemy.width \/ 2, 0, Math.PI * 2);\n            ctx.fill();\n            \n            ctx.shadowBlur = 20;\n            ctx.shadowColor = enemy.type === 'regular' ? '#ffeea9' : '#ff6666';\n            ctx.fill();\n            ctx.shadowBlur = 0;\n        } else {\n            if (enemy.type === 'regular') {\n                ctx.drawImage(enemyImage, enemy.x, enemy.y, enemy.width, enemy.height);\n            } else {\n                ctx.drawImage(enemyRedImage, enemy.x, enemy.y, enemy.width, enemy.height);\n            }\n        }\n        ctx.globalAlpha = 1;\n    });\n}\n\nfunction drawWall() {\n    for (let i = 0; i < wall.segments.length; i++) {\n        if (wall.segments[i] > 0) {\n            ctx.fillStyle = wall.segments[i] === 3 ? '#d38a4c' : (wall.segments[i] === 2 ? '#9d402d' : '#8c3932');\n            ctx.fillRect(wall.x + i, wall.y, 1, wall.height);\n        }\n    }\n}\n\nfunction drawBombs() {\n    bombs.forEach(bomb => {\n        ctx.fillStyle = bomb.color || (bomb.isRed ? 'red' : 'yellow');\n        ctx.fillRect(bomb.x, bomb.y, 5, 10);\n    });\n}\n\nfunction moveProjectiles() {\n    projectiles = projectiles.filter(proj => proj.y > 0);\n    projectiles.forEach(proj => proj.y -= 5);\n}\n\nfunction moveEnemies() {\n    enemies.forEach(enemy => {\n        enemy.y += 1;\n        if (Math.random() < 0.01) enemy.x += (Math.random() - 0.5) * 20;\n        if (Math.random() < 0.005 && enemy.y < wall.y) dropBomb(enemy);\n    });\n}\n\nfunction moveBombs() {\n    bombs.forEach(bomb => {\n        bomb.y += 3;\n        if (bomb.isRed && bomb.y >= wall.y) {\n            const startSegment = Math.floor(bomb.x - wall.x);\n            const endSegment = Math.floor(bomb.x + 5 - wall.x);\n            for (let i = startSegment; i <= endSegment; i++) {\n                if (i >= 0 && i < wall.segments.length) {\n                    wall.segments[i] = 0;\n                }\n            }\n            bomb.exploded = true;\n        }\n    });\n    bombs = bombs.filter(bomb => bomb.y < canvas.height && !bomb.exploded);\n}\n\nfunction checkAmmoReload() {\n    const currentTime = Date.now();\n    \n    \/\/ Start automatisk genopladning hvis det har g\u00e5et 10 sekunder siden sidste genopladning\n    if (currentTime - player.lastReloadTime >= player.reloadInterval) {\n        if (player.ammo < player.maxAmmo && !player.isReloading) {\n            player.isReloading = true;\n            reloadSound.currentTime = 0;\n            reloadSound.play();\n            \n            setTimeout(() => {\n                player.ammo = player.maxAmmo;\n                player.isReloading = false;\n                player.lastReloadTime = currentTime;\n            }, 500); \/\/ Kort forsinkelse for at simulere genopladning\n        } else if (player.ammo === player.maxAmmo) {\n            player.lastReloadTime = currentTime;\n        }\n    }\n}\n\nfunction dropBomb(enemy) {\n    bombs.push({\n        x: enemy.x + enemy.width \/ 2,\n        y: enemy.y + enemy.height,\n        isRed: enemy.type === 'special'\n    });\n    bombDropSound.currentTime = 0;\n    bombDropSound.play();\n}\n\nfunction killEnemy(enemy, addScore = false, hitByProjectile = false) {\n    if (enemy.type === 'special' && enemy.hits < 1) {\n        enemy.hits++;\n        enemy.deathTime = Date.now();\n        setTimeout(() => {\n            enemy.deathTime = null;\n        }, 100);\n        playSound(alienShootHitSoundPool);\n        return;\n    }\n    enemy.deathTime = Date.now();\n    setTimeout(() => {\n        enemies = enemies.filter(e => e !== enemy);\n    }, 100);\n    if (addScore) {\n        score += enemy.type === 'regular' ? 10 : 50;\n        scoreElement.textContent = score;\n    }\n    if (hitByProjectile) {\n        playSound(alienShootHitSoundPool);\n    } else {\n        playSound(alienDieWallSoundPool);\n    }\n}\n\nfunction damageWall(startX, width, fullDamage = false) {\n    const startSegment = Math.floor(startX);\n    const endSegment = Math.floor(startX + width);\n    for (let i = startSegment; i < endSegment; i++) {\n        if (i >= 0 && i < wall.segments.length) {\n            if (fullDamage) {\n                wall.segments[i] = 0;\n            } else {\n                wall.segments[i] = Math.max(0, wall.segments[i] - 0.6);\n            }\n        }\n    }\n}\n\nfunction checkCollisions() {\n    projectiles.forEach((proj, projIndex) => {\n        if (proj.y <= wall.y + wall.height && proj.y + PROJECTILE_HEIGHT >= wall.y) {\n            const startSegment = Math.floor(proj.x - wall.x);\n            const endSegment = Math.floor(proj.x + PROJECTILE_WIDTH - wall.x);\n            let hitWall = false;\n            for (let i = startSegment; i <= endSegment; i++) {\n                if (i >= 0 && i < wall.segments.length && wall.segments[i] > 0) {\n                    wall.segments[i]--;\n                    hitWall = true;\n                }\n            }\n            if (hitWall) {\n                projectiles.splice(projIndex, 1);\n                return;\n            }\n        }\n        \n        enemies.forEach(enemy => {\n            if (proj.x < enemy.x + enemy.width &&\n                proj.x + PROJECTILE_WIDTH > enemy.x &&\n                proj.y < enemy.y + enemy.height &&\n                proj.y + PROJECTILE_HEIGHT > enemy.y &&\n                !enemy.deathTime) {\n                projectiles.splice(projIndex, 1);\n                killEnemy(enemy, true, true);\n            }\n        });\n    });\n\n    bombs.forEach((bomb, bombIndex) => {\n        if (!bomb.isRed && bomb.y + 10 >= wall.y && bomb.y <= wall.y + wall.height) {\n            const startSegment = Math.floor(bomb.x - wall.x);\n            const endSegment = Math.floor(bomb.x + 5 - wall.x);\n            let hitWall = false;\n            for (let i = startSegment; i <= endSegment; i++) {\n                if (i >= 0 && i < wall.segments.length && wall.segments[i] > 0) {\n                    wall.segments[i]--;\n                    hitWall = true;\n                }\n            }\n            if (hitWall) {\n                bomb.color = 'purple';\n                bomb.exploded = true;\n                ctx.fillStyle = 'purple';\n                ctx.beginPath();\n                ctx.arc(bomb.x, bomb.y, 15, 0, Math.PI * 2);\n                ctx.fill();\n                setTimeout(() => {\n                    bombs.splice(bombIndex, 1);\n                }, 100);\n                return;\n            }\n        }\n\n        if (bomb.x < player.x + player.width &&\n            bomb.x + 5 > player.x &&\n            bomb.y < player.y + player.height &&\n            bomb.y + 10 > player.y) {\n            bombs.splice(bombIndex, 1);\n            player.lives--;\n            livesElement.textContent = player.lives;\n            playSound(heroMinusLifeSoundPool);\n            player.isBlinking = true;\n            player.lastBlinkTime = Date.now();\n            if (player.lives <= 0) {\n                gameOver();\n            }\n        }\n    });\n\n    enemies.forEach(enemy => {\n        if (enemy.y + enemy.height >= wall.y && !enemy.deathTime) {\n            const startSegment = Math.floor(enemy.x - wall.x);\n            const endSegment = Math.floor((enemy.x + enemy.width) - wall.x);\n            let hitWall = false;\n            \n            for (let i = startSegment; i <= endSegment; i++) {\n                if (i >= 0 && i < wall.segments.length && wall.segments[i] > 0) {\n                    hitWall = true;\n                    break;\n                }\n            }\n            \n            if (hitWall) {\n                if (enemy.type === 'special') {\n                    damageWall(enemy.x, enemy.width, true);\n                } else {\n                    damageWall(enemy.x, enemy.width);\n                }\n                killEnemy(enemy, false, false);\n                playSound(alienDieWallSoundPool);\n            } else if (enemy.y + enemy.height >= canvas.height) {\n                killEnemy(enemy, false, false);\n            }\n        }\n\n        if (enemy.x < player.x + player.width &&\n            enemy.x + enemy.width > player.x &&\n            enemy.y < player.y + player.height &&\n            enemy.y + enemy.height > player.y &&\n            !enemy.deathTime) {\n            killEnemy(enemy, false, false);\n            player.lives--;\n            livesElement.textContent = player.lives;\n            playSound(heroMinusLifeSoundPool);\n            player.isBlinking = true;\n            player.lastBlinkTime = Date.now();\n            if (player.lives <= 0) {\n                gameOver();\n            }\n        }\n    });\n}\n\nfunction spawnEnemy() {\n    if (Math.random() < 0.02) {\n        const isSpecial = Math.random() < 0.1; \/\/ 10% chance for special enemy\n        enemies.push({\n            x: Math.random() * (canvas.width - 30),\n            y: 0,\n            width: 30,\n            height: 30,\n            type: isSpecial ? 'special' : 'regular',\n            hits: 0\n        });\n    }\n}\n\nfunction gameOver() {\n    isGameOver = true;\n    gameOverOverlay.style.display = 'flex';\n    let currentScore = 0;\n    const duration = 3000;\n    const steps = 60;\n    const interval = duration \/ steps;\n    const increment = score \/ steps;\n    \n    endCounterSound.play();\n    \n    const scoreInterval = setInterval(() => {\n        if (currentScore < score) {\n            currentScore += increment;\n            finalScoreElement.textContent = Math.round(currentScore);\n        } else {\n            finalScoreElement.textContent = score;\n            clearInterval(scoreInterval);\n        }\n    }, interval);\n\n    endCounterSound.onended = () => {\n        endCounterSound.currentTime = 0;\n    };\n}\n\nfunction resetGame() {\n    cancelAnimationFrame(animationId);\n    player.lives = 3;\n    score = 0;\n    enemies = [];\n    bombs = [];\n    projectiles = [];\n    player.ammo = player.maxAmmo;\n    player.lastReloadTime = Date.now();\n    livesElement.textContent = player.lives;\n    scoreElement.textContent = score;\n    for (let i = 0; i < wall.width; i++) {\n        wall.segments[i] = 3;\n    }\n    player.isBlinking = false;\n    player.blinkCount = 0;\n    isGameOver = false;\n    gameOverOverlay.style.display = 'none';\n    player.x = canvas.width \/ 2 - 15;\n    gameLoop();\n}\n\nfunction gameLoop() {\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\n    \n    drawWall();\n    drawPlayer();\n    drawProjectiles();\n    drawEnemies();\n    drawBombs();\n    drawAmmoBar();\n    \n    if (!isGameOver) {\n        moveProjectiles();\n        moveEnemies();\n        moveBombs();\n        checkCollisions();\n        checkAmmoReload();\n        spawnEnemy();\n    }\n    \n    animationId = requestAnimationFrame(gameLoop);\n}\n\n\/\/ Flyt mousemove event listener til document-niveau\ndocument.addEventListener('mousemove', (e) => {\n    if (!isGameOver) {\n        \/\/ Find canvas position og musens position relativt til canvas\n        const rect = canvas.getBoundingClientRect();\n        const mouseX = e.clientX - rect.left;\n        \n        \/\/ Beregn ny position for spilleren, centreret p\u00e5 musens X-position\n        let newX = mouseX - (player.width \/ 2);\n        \n        \/\/ Begr\u00e6ns til canvas-gr\u00e6nser\n        newX = Math.max(0, Math.min(newX, canvas.width - player.width));\n        \n        \/\/ Opdater spillerens position direkte\n        player.x = newX;\n    }\n});\n\ndocument.addEventListener('keydown', (e) => {\n    if (!isGameOver) {\n        if (e.key === 'ArrowLeft' && player.x > 0) player.x -= player.dx;\n        if (e.key === 'ArrowRight' && player.x < canvas.width - player.width) player.x += player.dx;\n        if (e.key === ' ') {\n            if (player.ammo > 0) {\n                projectiles.push({x: player.x + player.width \/ 2 - PROJECTILE_WIDTH\/2, y: player.y});\n                laserSound.currentTime = 0;\n                laserSound.play();\n                player.ammo--;\n            }\n        }\n    }\n});\n\n\/\/ Fjern den dublerede keydown event listener\ncanvas.addEventListener('click', (e) => {\n    if (!isGameOver) {\n        if (player.ammo > 0) {\n            projectiles.push({x: player.x + player.width \/ 2 - PROJECTILE_WIDTH\/2, y: player.y});\n            laserSound.currentTime = 0;\n            laserSound.play();\n            player.ammo--;\n        }\n    }\n});\n\ntryAgainButton.addEventListener('click', () => {\n    resetGame();\n});\n\ngameLoop();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>&gt; FIRE = Spacebar &lt; > Move = Arrow keys or mouse<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"inline_featured_image":false,"_kad_post_transparent":"","_kad_post_title":"hide","_kad_post_layout":"fullwidth","_kad_post_sidebar_id":"","_kad_post_content_style":"unboxed","_kad_post_vertical_padding":"hide","_kad_post_feature":"hide","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"footnotes":""},"class_list":["post-18","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/pages\/18","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":15,"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/pages\/18\/revisions"}],"predecessor-version":[{"id":4459,"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/pages\/18\/revisions\/4459"}],"wp:attachment":[{"href":"https:\/\/diverse.anderskisling.dk\/index.php\/wp-json\/wp\/v2\/media?parent=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}