Spaces:
Running
Running
Update game.js
Browse files
game.js
CHANGED
|
@@ -303,34 +303,8 @@ class TankPlayer {
|
|
| 303 |
this.startReload();
|
| 304 |
}
|
| 305 |
}
|
| 306 |
-
// 카메라 흔들림 효과 추가
|
| 307 |
-
this.applyCameraShake();
|
| 308 |
return bullet;
|
| 309 |
}
|
| 310 |
-
applyCameraShake() {
|
| 311 |
-
if (!window.gameInstance || !window.gameInstance.camera) return;
|
| 312 |
-
|
| 313 |
-
const camera = window.gameInstance.camera;
|
| 314 |
-
const originalPosition = camera.position.clone();
|
| 315 |
-
let shakeTime = 0;
|
| 316 |
-
const shakeIntensity = 0.2; // 발사 시 흔들림 강도
|
| 317 |
-
const shakeDuration = 300; // 흔들림 지속 시간 (ms)
|
| 318 |
-
|
| 319 |
-
const shakeCamera = () => {
|
| 320 |
-
if (shakeTime < shakeDuration) {
|
| 321 |
-
camera.position.x = originalPosition.x + (Math.random() - 0.5) * shakeIntensity;
|
| 322 |
-
camera.position.y = originalPosition.y + (Math.random() - 0.5) * shakeIntensity;
|
| 323 |
-
camera.position.z = originalPosition.z + (Math.random() - 0.5) * shakeIntensity;
|
| 324 |
-
|
| 325 |
-
shakeTime += 16; // 약 60fps 기준
|
| 326 |
-
requestAnimationFrame(shakeCamera);
|
| 327 |
-
} else {
|
| 328 |
-
camera.position.copy(originalPosition);
|
| 329 |
-
}
|
| 330 |
-
};
|
| 331 |
-
|
| 332 |
-
shakeCamera();
|
| 333 |
-
}
|
| 334 |
|
| 335 |
startReload() {
|
| 336 |
if (this.isReloading) return; // 이미 재장전 중이면 무시
|
|
@@ -595,7 +569,7 @@ startReload() {
|
|
| 595 |
}
|
| 596 |
|
| 597 |
updateAmmoDisplay() {
|
| 598 |
-
document.getElementById('ammoDisplay').textContent = APFSDS: ${this.ammo}/${this.maxAmmo};
|
| 599 |
}
|
| 600 |
}
|
| 601 |
|
|
@@ -1775,8 +1749,8 @@ class Game {
|
|
| 1775 |
// 적 도트 생성 및 추가
|
| 1776 |
const dot = document.createElement('div');
|
| 1777 |
dot.className = 'enemy-dot';
|
| 1778 |
-
dot.style.left = ${dotX}px;
|
| 1779 |
-
dot.style.top = ${dotY}px;
|
| 1780 |
radar.appendChild(dot);
|
| 1781 |
}
|
| 1782 |
});
|
|
@@ -2167,11 +2141,11 @@ class Game {
|
|
| 2167 |
this.isLoading = false;
|
| 2168 |
const loadingElement = document.getElementById('loading');
|
| 2169 |
if (loadingElement) {
|
| 2170 |
-
loadingElement.innerHTML =
|
| 2171 |
<div class="loading-text" style="color: red;">
|
| 2172 |
Loading failed. Please refresh the page.
|
| 2173 |
</div>
|
| 2174 |
-
;
|
| 2175 |
}
|
| 2176 |
}
|
| 2177 |
|
|
@@ -2187,7 +2161,7 @@ class Game {
|
|
| 2187 |
}
|
| 2188 |
|
| 2189 |
this.gameTime--;
|
| 2190 |
-
document.getElementById('time').textContent = Time: ${this.gameTime}s;
|
| 2191 |
|
| 2192 |
if (this.gameTime <= 0) {
|
| 2193 |
clearInterval(this.gameTimer);
|
|
@@ -2366,7 +2340,7 @@ class Game {
|
|
| 2366 |
enemy.bullets.splice(bulletIndex, 1);
|
| 2367 |
|
| 2368 |
document.getElementById('health').style.width =
|
| 2369 |
-
${(this.tank.health / MAX_HEALTH) * 100}%;
|
| 2370 |
}
|
| 2371 |
});
|
| 2372 |
});
|
|
@@ -2415,7 +2389,7 @@ this.enemies.forEach(enemy => {
|
|
| 2415 |
enemy.bullets.splice(bulletIndex, 1);
|
| 2416 |
|
| 2417 |
document.getElementById('health').style.width =
|
| 2418 |
-
${(this.tank.health / MAX_HEALTH) * 100}%;
|
| 2419 |
}
|
| 2420 |
});
|
| 2421 |
});
|
|
@@ -2448,7 +2422,7 @@ this.enemies.forEach(enemy => {
|
|
| 2448 |
enemy.destroy();
|
| 2449 |
this.enemies.splice(j, 1);
|
| 2450 |
this.score += 100;
|
| 2451 |
-
document.getElementById('score').textContent = Score: ${this.score};
|
| 2452 |
}
|
| 2453 |
|
| 2454 |
this.tank.createExplosionEffect(this.scene, bullet.position);
|
|
@@ -2526,7 +2500,7 @@ this.enemies.forEach(enemy => {
|
|
| 2526 |
gameOverDiv.style.padding = '20px';
|
| 2527 |
gameOverDiv.style.borderRadius = '10px';
|
| 2528 |
gameOverDiv.style.textAlign = 'center';
|
| 2529 |
-
gameOverDiv.innerHTML =
|
| 2530 |
${isVictory ? 'Victory!' : 'Game Over'}<br>
|
| 2531 |
Score: ${this.score}<br>
|
| 2532 |
Time Survived: ${GAME_DURATION - this.gameTime}s<br>
|
|
@@ -2536,7 +2510,7 @@ this.enemies.forEach(enemy => {
|
|
| 2536 |
color: black; border-radius: 5px;">
|
| 2537 |
Play Again
|
| 2538 |
</button>
|
| 2539 |
-
;
|
| 2540 |
document.body.appendChild(gameOverDiv);
|
| 2541 |
}
|
| 2542 |
|
|
@@ -2545,17 +2519,17 @@ this.enemies.forEach(enemy => {
|
|
| 2545 |
if (!this.isGameOver) {
|
| 2546 |
const healthBar = document.getElementById('health');
|
| 2547 |
if (healthBar) {
|
| 2548 |
-
healthBar.style.width = ${(this.tank.health / MAX_HEALTH) * 100}%;
|
| 2549 |
}
|
| 2550 |
|
| 2551 |
const timeElement = document.getElementById('time');
|
| 2552 |
if (timeElement) {
|
| 2553 |
-
timeElement.textContent = Time: ${this.gameTime}s;
|
| 2554 |
}
|
| 2555 |
|
| 2556 |
const scoreElement = document.getElementById('score');
|
| 2557 |
if (scoreElement) {
|
| 2558 |
-
scoreElement.textContent = Score: ${this.score};
|
| 2559 |
}
|
| 2560 |
}
|
| 2561 |
}
|
|
@@ -2613,8 +2587,8 @@ updateCrosshair() {
|
|
| 2613 |
const label = document.createElement('div');
|
| 2614 |
label.className = 'enemy-label';
|
| 2615 |
label.textContent = 'T-90';
|
| 2616 |
-
label.style.left = ${x}px;
|
| 2617 |
-
label.style.top = ${y}px;
|
| 2618 |
|
| 2619 |
// 거리에 따른 투명도 조정
|
| 2620 |
const opacity = Math.max(0.2, 1 - (distance / this.radarRange));
|
|
|
|
| 303 |
this.startReload();
|
| 304 |
}
|
| 305 |
}
|
|
|
|
|
|
|
| 306 |
return bullet;
|
| 307 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
|
| 309 |
startReload() {
|
| 310 |
if (this.isReloading) return; // 이미 재장전 중이면 무시
|
|
|
|
| 569 |
}
|
| 570 |
|
| 571 |
updateAmmoDisplay() {
|
| 572 |
+
document.getElementById('ammoDisplay').textContent = `APFSDS: ${this.ammo}/${this.maxAmmo}`;
|
| 573 |
}
|
| 574 |
}
|
| 575 |
|
|
|
|
| 1749 |
// 적 도트 생성 및 추가
|
| 1750 |
const dot = document.createElement('div');
|
| 1751 |
dot.className = 'enemy-dot';
|
| 1752 |
+
dot.style.left = `${dotX}px`;
|
| 1753 |
+
dot.style.top = `${dotY}px`;
|
| 1754 |
radar.appendChild(dot);
|
| 1755 |
}
|
| 1756 |
});
|
|
|
|
| 2141 |
this.isLoading = false;
|
| 2142 |
const loadingElement = document.getElementById('loading');
|
| 2143 |
if (loadingElement) {
|
| 2144 |
+
loadingElement.innerHTML = `
|
| 2145 |
<div class="loading-text" style="color: red;">
|
| 2146 |
Loading failed. Please refresh the page.
|
| 2147 |
</div>
|
| 2148 |
+
`;
|
| 2149 |
}
|
| 2150 |
}
|
| 2151 |
|
|
|
|
| 2161 |
}
|
| 2162 |
|
| 2163 |
this.gameTime--;
|
| 2164 |
+
document.getElementById('time').textContent = `Time: ${this.gameTime}s`;
|
| 2165 |
|
| 2166 |
if (this.gameTime <= 0) {
|
| 2167 |
clearInterval(this.gameTimer);
|
|
|
|
| 2340 |
enemy.bullets.splice(bulletIndex, 1);
|
| 2341 |
|
| 2342 |
document.getElementById('health').style.width =
|
| 2343 |
+
`${(this.tank.health / MAX_HEALTH) * 100}%`;
|
| 2344 |
}
|
| 2345 |
});
|
| 2346 |
});
|
|
|
|
| 2389 |
enemy.bullets.splice(bulletIndex, 1);
|
| 2390 |
|
| 2391 |
document.getElementById('health').style.width =
|
| 2392 |
+
`${(this.tank.health / MAX_HEALTH) * 100}%`;
|
| 2393 |
}
|
| 2394 |
});
|
| 2395 |
});
|
|
|
|
| 2422 |
enemy.destroy();
|
| 2423 |
this.enemies.splice(j, 1);
|
| 2424 |
this.score += 100;
|
| 2425 |
+
document.getElementById('score').textContent = `Score: ${this.score}`;
|
| 2426 |
}
|
| 2427 |
|
| 2428 |
this.tank.createExplosionEffect(this.scene, bullet.position);
|
|
|
|
| 2500 |
gameOverDiv.style.padding = '20px';
|
| 2501 |
gameOverDiv.style.borderRadius = '10px';
|
| 2502 |
gameOverDiv.style.textAlign = 'center';
|
| 2503 |
+
gameOverDiv.innerHTML = `
|
| 2504 |
${isVictory ? 'Victory!' : 'Game Over'}<br>
|
| 2505 |
Score: ${this.score}<br>
|
| 2506 |
Time Survived: ${GAME_DURATION - this.gameTime}s<br>
|
|
|
|
| 2510 |
color: black; border-radius: 5px;">
|
| 2511 |
Play Again
|
| 2512 |
</button>
|
| 2513 |
+
`;
|
| 2514 |
document.body.appendChild(gameOverDiv);
|
| 2515 |
}
|
| 2516 |
|
|
|
|
| 2519 |
if (!this.isGameOver) {
|
| 2520 |
const healthBar = document.getElementById('health');
|
| 2521 |
if (healthBar) {
|
| 2522 |
+
healthBar.style.width = `${(this.tank.health / MAX_HEALTH) * 100}%`;
|
| 2523 |
}
|
| 2524 |
|
| 2525 |
const timeElement = document.getElementById('time');
|
| 2526 |
if (timeElement) {
|
| 2527 |
+
timeElement.textContent = `Time: ${this.gameTime}s`;
|
| 2528 |
}
|
| 2529 |
|
| 2530 |
const scoreElement = document.getElementById('score');
|
| 2531 |
if (scoreElement) {
|
| 2532 |
+
scoreElement.textContent = `Score: ${this.score}`;
|
| 2533 |
}
|
| 2534 |
}
|
| 2535 |
}
|
|
|
|
| 2587 |
const label = document.createElement('div');
|
| 2588 |
label.className = 'enemy-label';
|
| 2589 |
label.textContent = 'T-90';
|
| 2590 |
+
label.style.left = `${x}px`;
|
| 2591 |
+
label.style.top = `${y}px`;
|
| 2592 |
|
| 2593 |
// 거리에 따른 투명도 조정
|
| 2594 |
const opacity = Math.max(0.2, 1 - (distance / this.radarRange));
|