Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Zombie Survival | |
| <style> | |
| body { | |
| margin: 0; | |
| overflow: hidden; | |
| background: #333; | |
| font-family: Arial, sans-serif; | |
| cursor: crosshair; | |
| } | |
| #score, #health, #timer { | |
| position: fixed; | |
| color: white; | |
| font-size: 20px; | |
| z-index: 100; | |
| } | |
| #score { | |
| top: 10px; | |
| left: 10px; | |
| } | |
| #health { | |
| top: 10px; | |
| right: 10px; | |
| } | |
| #timer { | |
| top: 10px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| } | |
| #startScreen { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: rgba(0, 0, 0, 0.8); | |
| color: white; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| flex-direction: column; | |
| z-index: 1000; | |
| } | |
| #startButton { | |
| padding: 10px 20px; | |
| font-size: 18px; | |
| background: green; | |
| color: white; | |
| border: none; | |
| cursor: pointer; | |
| border-radius: 5px; | |
| margin-top: 20px; | |
| } | |
| #player { | |
| position: absolute; | |
| width: 40px; | |
| height: 40px; | |
| background: lime; | |
| border-radius: 50%; | |
| transform-origin: center; | |
| } | |
| .zombie { | |
| position: absolute; | |
| width: 40px; | |
| height: 40px; | |
| background: crimson; | |
| border-radius: 50%; | |
| } | |
| .bullet { | |
| position: absolute; | |
| width: 8px; | |
| height: 8px; | |
| background: yellow; | |
| border-radius: 50%; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="startScreen"> | |
| <h1>Zombie Survival</h1> | |
| <button id="startButton">Start Game</button> | |
| </div> | |
| <div id="score">Score: 0</div> | |
| <div id="health">Health: 100</div> | |
| <div id="timer">Time: 0</div> | |
| <div id="player"></div> | |
| <script> | |
| const startScreen = document.getElementById('startScreen'); | |
| const startButton = document.getElementById('startButton'); | |
| const player = document.getElementById('player'); | |
| const scoreDisplay = document.getElementById('score'); | |
| const healthDisplay = document.getElementById('health'); | |
| const timerDisplay = document.getElementById('timer'); | |
| let score = 0; | |
| let health = 100; | |
| let gameRunning = false; | |
| let bullets = []; | |
| let zombies = []; | |
| let mouseX = 0, mouseY = 0; | |
| let playerX = window.innerWidth / 2; | |
| let playerY = window.innerHeight / 2; | |
| let gameTime = 0; | |
| let zombieSpeedMultiplier = 1; | |
| let timeInterval; | |
| // νλ μ΄μ΄ μ΄λ μ λ°μ΄νΈ | |
| function updatePlayer() { | |
| player.style.left = `${playerX - 20}px`; | |
| player.style.top = `${playerY - 20}px`; | |
| } | |
| // μ’λΉ μμ± | |
| function spawnZombie() { | |
| if (!gameRunning) return; | |
| const zombie = document.createElement('div'); | |
| zombie.className = 'zombie'; | |
| const size = 40; | |
| const side = Math.floor(Math.random() * 4); // 0: μ, 1: μ€λ₯Έμͺ½, 2: μλ, 3: μΌμͺ½ | |
| let x, y; | |
| if (side === 0) { // μμͺ½μμ μμ± | |
| x = Math.random() * window.innerWidth; | |
| y = -size; | |
| } else if (side === 1) { // μ€λ₯Έμͺ½μμ μμ± | |
| x = window.innerWidth + size; | |
| y = Math.random() * window.innerHeight; | |
| } else if (side === 2) { // μλμͺ½μμ μμ± | |
| x = Math.random() * window.innerWidth; | |
| y = window.innerHeight + size; | |
| } else { // μΌμͺ½μμ μμ± | |
| x = -size; | |
| y = Math.random() * window.innerHeight; | |
| } | |
| document.body.appendChild(zombie); | |
| zombies.push({ element: zombie, x, y, speed: (1.5 + Math.random() * 2) * zombieSpeedMultiplier }); | |
| updateZombies(); | |
| } | |
| // μ’λΉ μ΄λ λ° μΆ©λ μ²λ¦¬ | |
| function updateZombies() { | |
| zombies.forEach((zombie, index) => { | |
| const angle = Math.atan2(playerY - zombie.y, playerX - zombie.x); | |
| zombie.x += Math.cos(angle) * zombie.speed; | |
| zombie.y += Math.sin(angle) * zombie.speed; | |
| zombie.element.style.left = `${zombie.x - 20}px`; | |
| zombie.element.style.top = `${zombie.y - 20}px`; | |
| const distanceToPlayer = Math.hypot(zombie.x - playerX, zombie.y - playerY); | |
| if (distanceToPlayer < 40) { | |
| health -= 10; | |
| healthDisplay.textContent = `Health: ${health}`; | |
| zombie.element.remove(); | |
| zombies.splice(index, 1); | |
| if (health <= 0) { | |
| endGame(); | |
| } | |
| } | |
| }); | |
| } | |
| // μ΄μ μμ± | |
| function shootBullet() { | |
| if (!gameRunning) return; | |
| const bullet = document.createElement('div'); | |
| bullet.className = 'bullet'; | |
| const angle = Math.atan2(mouseY - playerY, mouseX - playerX); | |
| const speed = 10; | |
| bullets.push({ | |
| element: bullet, | |
| x: playerX, | |
| y: playerY, | |
| vx: Math.cos(angle) * speed, | |
| vy: Math.sin(angle) * speed | |
| }); | |
| document.body.appendChild(bullet); | |
| } | |
| // μ΄μ μ λ°μ΄νΈ | |
| function updateBullets() { | |
| bullets.forEach((bullet, index) => { | |
| bullet.x += bullet.vx; | |
| bullet.y += bullet.vy; | |
| bullet.element.style.left = `${bullet.x - 4}px`; | |
| bullet.element.style.top = `${bullet.y - 4}px`; | |
| // νλ©΄ λ°μΌλ‘ λκ° μ΄μ μ κ±° | |
| if (bullet.x < 0 || bullet.x > window.innerWidth || bullet.y < 0 || bullet.y > window.innerHeight) { | |
| bullet.element.remove(); | |
| bullets.splice(index, 1); | |
| } | |
| // μ’λΉμ μΆ©λ μ²΄ν¬ | |
| zombies.forEach((zombie, zombieIndex) => { | |
| const distance = Math.hypot(bullet.x - zombie.x, bullet.y - zombie.y); | |
| if (distance < 20) { | |
| bullet.element.remove(); | |
| zombie.element.remove(); | |
| bullets.splice(index, 1); | |
| zombies.splice(zombieIndex, 1); | |
| score += 10; | |
| scoreDisplay.textContent = `Score: ${score}`; | |
| } | |
| }); | |
| }); | |
| } | |
| // κ²μ 루ν | |
| function gameLoop() { | |
| if (!gameRunning) return; | |
| updateBullets(); | |
| updateZombies(); | |
| requestAnimationFrame(gameLoop); | |
| } | |
| // κ²μ μκ° μ λ°μ΄νΈ | |
| function updateTimer() { | |
| if (!gameRunning) return; | |
| gameTime++; | |
| timerDisplay.textContent = `Time: ${gameTime}`; | |
| if (gameTime % 10 === 0) { | |
| zombieSpeedMultiplier *= 2; | |
| zombies.forEach(zombie => { | |
| zombie.speed = (1.5 + Math.random() * 2) * zombieSpeedMultiplier; | |
| }); | |
| } | |
| } | |
| // κ²μ μμ | |
| startButton.addEventListener('click', () => { | |
| startScreen.style.display = 'none'; | |
| gameRunning = true; | |
| health = 100; | |
| score = 0; | |
| gameTime = 0; | |
| zombieSpeedMultiplier = 1; | |
| healthDisplay.textContent = `Health: ${health}`; | |
| scoreDisplay.textContent = `Score: ${score}`; | |
| timerDisplay.textContent = `Time: ${gameTime}`; | |
| spawnZombie(); | |
| setInterval(spawnZombie, 1000); | |
| gameLoop(); | |
| timeInterval = setInterval(updateTimer, 1000); | |
| }); | |
| // κ²μ μ’ λ£ | |
| function endGame() { | |
| gameRunning = false; | |
| clearInterval(timeInterval); | |
| alert(`Game Over! Final Score: ${score}, Time: ${gameTime}`); | |
| location.reload(); | |
| } | |
| // λ§μ°μ€ μ΄λ | |
| document.addEventListener('mousemove', (e) => { | |
| mouseX = e.clientX; | |
| mouseY = e.clientY; | |
| }); | |
| // μ΄μ λ°μ¬ | |
| document.addEventListener('click', shootBullet); | |
| // μ΄κΈ° νλ μ΄μ΄ μμΉ | |
| updatePlayer(); | |
| </script> | |
| </body> | |
| </html> |