Spaces:
Running
Running
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r17/Stats.min.js"></script> | |
<title>Tank Combat Simulator - FPS Mode</title> | |
<style> | |
body { | |
margin: 0; | |
overflow: hidden; | |
background: #000; | |
font-family: 'Courier New', monospace; | |
} | |
#enemyLabels { | |
position: absolute; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
pointer-events: none; | |
} | |
.enemy-label { | |
position: absolute; | |
background-color: rgba(255, 0, 0, 0.7); | |
color: white; | |
padding: 2px 6px; | |
border-radius: 3px; | |
font-size: 12px; | |
font-family: Arial, sans-serif; | |
transform: translate(-50%, -50%); | |
white-space: nowrap; | |
} | |
#loading { | |
position: fixed; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
background: rgba(0,0,0,0.8); | |
padding: 20px; | |
border-radius: 10px; | |
z-index: 2000; | |
text-align: center; | |
} | |
.loading-spinner { | |
width: 50px; | |
height: 50px; | |
border: 5px solid #0f0; | |
border-top: 5px solid transparent; | |
border-radius: 50%; | |
animation: spin 1s linear infinite; | |
margin: 0 auto 20px; | |
} | |
@keyframes spin { | |
0% { transform: rotate(0deg); } | |
100% { transform: rotate(360deg); } | |
} | |
.loading-text { | |
color: #0f0; | |
font-size: 24px; | |
text-align: center; | |
} | |
#gameContainer { | |
position: relative; | |
width: 100vw; | |
height: 100vh; | |
cursor: crosshair; | |
} | |
#info { | |
position: absolute; | |
top: 10px; | |
left: 10px; | |
color: #0f0; | |
background: rgba(0,20,0,0.7); | |
padding: 10px; | |
font-size: 14px; | |
z-index: 1001; | |
border: 1px solid #0f0; | |
border-radius: 5px; | |
user-select: none; | |
} | |
#crosshair { | |
position: fixed; | |
top: 25%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
width: 40px; | |
height: 40px; | |
border: 2px solid #00ff00; | |
border-radius: 50%; | |
z-index: 1001; | |
pointer-events: none; | |
transition: all 0.2s ease; | |
} | |
/* λ¬Όμ²΄κ° κ°μ§λμμ λμ μ€νμΌ */ | |
#crosshair.target-detected { | |
border-color: #ff0000; | |
border-width: 3px; | |
box-shadow: 0 0 10px rgba(255, 0, 0, 0.5); | |
} | |
#crosshair::before, | |
#crosshair::after { | |
content: ''; | |
position: absolute; | |
background: #00ff00; | |
transition: all 0.2s ease; | |
} | |
#crosshair::before { | |
top: 50%; | |
left: -10px; | |
right: -10px; | |
height: 2px; | |
transform: translateY(-50%); | |
} | |
#crosshair::after { | |
left: 50%; | |
top: -10px; | |
bottom: -10px; | |
width: 2px; | |
transform: translateX(-50%); | |
} | |
/* λ¬Όμ²΄κ° κ°μ§λμμ λμ ν¬λ‘μ€ λΌμΈ μ€νμΌ */ | |
#crosshair.target-detected::before, | |
#crosshair.target-detected::after { | |
background: #ff0000; | |
} | |
#healthBar { | |
position: absolute; | |
bottom: 20px; | |
left: 20px; | |
width: 200px; | |
height: 20px; | |
background: rgba(0,20,0,0.7); | |
border: 2px solid #0f0; | |
z-index: 1001; | |
border-radius: 10px; | |
overflow: hidden; | |
} | |
#health { | |
width: 100%; | |
height: 100%; | |
background: linear-gradient(90deg, #0f0, #00ff00); | |
transition: width 0.3s; | |
} | |
#ammo { | |
position: absolute; | |
bottom: 20px; | |
right: 20px; | |
color: #0f0; | |
background: rgba(0,20,0,0.7); | |
padding: 10px; | |
font-size: 20px; | |
z-index: 1001; | |
border: 1px solid #0f0; | |
border-radius: 5px; | |
} | |
#gameTitle { | |
position: absolute; | |
top: 10px; | |
left: 50%; | |
transform: translateX(-50%); | |
color: #0f0; | |
background: rgba(0,20,0,0.7); | |
padding: 10px 20px; | |
font-size: 20px; | |
z-index: 1001; | |
border: 1px solid #0f0; | |
border-radius: 5px; | |
text-transform: uppercase; | |
letter-spacing: 2px; | |
} | |
#ammoDisplay { | |
position: absolute; | |
bottom: 20px; | |
right: 20px; | |
color: #0f0; | |
background: rgba(0,20,0,0.7); | |
padding: 10px; | |
font-size: 20px; | |
z-index: 1001; | |
border: 1px solid #0f0; | |
border-radius: 5px; | |
} | |
#reloadingText { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
color: #ff0000; | |
font-size: 24px; | |
font-weight: bold; | |
display: none; | |
z-index: 1002; | |
} | |
#radar { | |
position: absolute; | |
bottom: 60px; /* 체λ ₯λ° μλ‘ μ΄λ */ | |
left: 20px; | |
width: 200px; | |
height: 200px; | |
background: rgba(0,20,0,0.3); | |
border: 2px solid #0f0; | |
border-radius: 50%; | |
z-index: 1001; | |
overflow: hidden; | |
} | |
#mission { | |
position: absolute; | |
top: 10px; | |
left: 10px; | |
color: #0f0; | |
background: rgba(0,20,0,0.7); | |
padding: 10px; | |
font-size: 16px; | |
z-index: 1001; | |
border: 1px solid #0f0; | |
border-radius: 5px; | |
} | |
#radarLine { | |
position: absolute; | |
top: 50%; | |
left: 50%; | |
width: 50%; | |
height: 2px; | |
background: #0f0; | |
transform-origin: left center; | |
animation: radar-sweep 4s infinite linear; | |
} | |
.enemy-dot { | |
position: absolute; | |
width: 6px; | |
height: 6px; | |
background: #ff0000; | |
border-radius: 50%; | |
transform: translate(-50%, -50%); | |
} | |
@keyframes radar-sweep { | |
from { | |
transform: rotate(0deg); | |
} | |
to { | |
transform: rotate(360deg); | |
} | |
} | |
#gameStats { | |
position: absolute; | |
top: 10px; | |
right: 20px; | |
color: #0f0; | |
background: rgba(0,20,0,0.7); | |
padding: 10px; | |
font-size: 16px; | |
z-index: 1001; | |
border: 1px solid #0f0; | |
border-radius: 5px; | |
text-align: right; | |
} | |
.start-screen { | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background: rgba(0,0,0,0.8); | |
display: flex; | |
justify-content: center; | |
align-items: center; | |
flex-direction: column; | |
z-index: 2000; | |
} | |
.start-button { | |
padding: 15px 30px; | |
font-size: 24px; | |
background: #0f0; | |
color: #000; | |
border: none; | |
border-radius: 5px; | |
cursor: pointer; | |
margin-top: 20px; | |
transition: transform 0.2s; | |
/* μμ μ λΉνμ±ν μν */ | |
opacity: 0.5; | |
pointer-events: none; | |
} | |
.start-button.ready { | |
opacity: 1; | |
pointer-events: auto; | |
} | |
.start-button.ready:hover { | |
transform: scale(1.1); | |
} | |
#minimap { | |
position: absolute; | |
bottom: 20px; | |
right: 20px; | |
width: 200px; | |
height: 200px; | |
background: rgba(0,20,0,0.7); | |
border: 2px solid #0f0; | |
border-radius: 5px; | |
z-index: 1001; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="loading"> | |
<div class="loading-spinner"></div> | |
<div class="loading-text">Loading tank assets...</div> | |
</div> | |
<div class="start-screen" id="startScreen"> | |
<h1 style="color: #0f0; font-size: 48px; margin-bottom: 20px;">Tank Combat Simulator</h1> | |
<button class="start-button" id="startButton" disabled>Loading...</button> | |
<div style="color: #0f0; margin-top: 20px; text-align: center;"> | |
<p>Controls:</p> | |
<p>W,A,S,D - Move Tank</p> | |
<p>Mouse - Look Around</p> | |
<p>Left Click - Fire</p> | |
<p>ESC - Pause</p> | |
</div> | |
</div> | |
<div id="gameContainer"> | |
<div id="gameTitle">Tank Combat Simulator</div> | |
<div id="mission">MISSION: SURVIVE 180 SEC</div> | |
<div id="gameStats"> | |
<div id="score">Score: 0</div> | |
<div id="time">Time: 180s</div> | |
</div> | |
<div id="crosshair"></div> | |
<div id="enemyLabels"></div> | |
<!-- 체λ ₯λ° --> | |
<div id="healthBar"> | |
<div id="health"></div> | |
</div> | |
<!-- μλ‘μ΄ νμ½ μμ€ν --> | |
<div id="ammoDisplay">APFSDS: 1/1</div> | |
<!-- 리λ‘λ© ν μ€νΈ --> | |
<div id="reloadingText">RELOADING...</div> | |
<!-- λ μ΄λ --> | |
<div id="radar"> | |
<div id="radarLine"></div> | |
</div> | |
</div> | |
<script type="importmap"> | |
{ | |
"imports": { | |
"three": "https://unpkg.com/three@0.157.0/build/three.module.js", | |
"three/addons/": "https://unpkg.com/three@0.157.0/examples/jsm/" | |
} | |
} | |
</script> | |
<script> | |
// κ²μ λ‘λ© μλ£ μ νΈμΆλ ν¨μ | |
function onGameLoaded() { | |
const startButton = document.getElementById('startButton'); | |
startButton.textContent = 'Start Game'; | |
startButton.classList.add('ready'); | |
startButton.disabled = false; | |
} | |
// startGame ν¨μ μμ | |
function startGame() { | |
if (document.getElementById('startButton').classList.contains('ready')) { | |
document.getElementById('startScreen').style.display = 'none'; | |
document.body.requestPointerLock(); | |
window.gameInstance.isStarted = true; | |
} | |
} | |
// ν¬μΈν° λ½ μ΄λ²€νΈ μ²λ¦¬ | |
document.addEventListener('pointerlockchange', () => { | |
if (document.pointerLockElement === document.body) { | |
console.log('Pointer locked'); | |
} else { | |
console.log('Pointer unlocked'); | |
} | |
}); | |
</script> | |
<script type="module" src="game.js"></script> | |
</body> | |
</html> |