cutechicken commited on
Commit
c0c9c79
ยท
verified ยท
1 Parent(s): c0e7039

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +16 -418
game.js CHANGED
@@ -20,7 +20,6 @@ const GAME_CONSTANTS = {
20
  MISSILE_COUNT: 6,
21
  AMMO_COUNT: 940, // 940๋ฐœ๋กœ ๋ณ€๊ฒฝ
22
  BULLET_DAMAGE: 25, // ๋ฐœ๋‹น 25 ๋ฐ๋ฏธ์ง€
23
- MISSILE_DAMAGE: 500, // ๋ฏธ์‚ฌ์ผ ๋ฐ๋ฏธ์ง€
24
  MAX_HEALTH: 1000 // ์ฒด๋ ฅ 1000
25
  };
26
 
@@ -61,19 +60,10 @@ class Fighter {
61
  this.missiles = GAME_CONSTANTS.MISSILE_COUNT;
62
  this.ammo = GAME_CONSTANTS.AMMO_COUNT;
63
  this.bullets = [];
64
- this.activeMissiles = []; // ๋ฐœ์‚ฌ๋œ ๋ฏธ์‚ฌ์ผ
65
  this.lastShootTime = 0;
66
  this.isMouseDown = false; // ๋งˆ์šฐ์Šค ๋ˆ„๋ฆ„ ์ƒํƒœ ์ถ”์ 
67
  this.gunfireAudios = []; // ๊ธฐ๊ด€์ด ์†Œ๋ฆฌ ๋ฐฐ์—ด (์ตœ๋Œ€ 5๊ฐœ)
68
 
69
- // ๋ฌด๊ธฐ ์‹œ์Šคํ…œ
70
- this.currentWeapon = 'mg'; // 'mg' or 'missile'
71
- this.weaponCooldown = 0; // ๋ฌด๊ธฐ ์ฟจ๋‹ค์šด
72
- this.missileTarget = null; // ๋ฏธ์‚ฌ์ผ ํƒ€๊ฒŸ
73
- this.missileLockTimer = 0; // ๋ฝ์˜จ ํƒ€์ด๋จธ
74
- this.missileLockCount = 0; // ๋ฝ์˜จ ์นด์šดํŠธ (3๋ฒˆ ํ•„์š”)
75
- this.lastMissileFire = 0; // ๋งˆ์ง€๋ง‰ ๋ฏธ์‚ฌ์ผ ๋ฐœ์‚ฌ ์‹œ๊ฐ„
76
-
77
  // ์Šคํ†จ ํƒˆ์ถœ์„ ์œ„ํ•œ Fํ‚ค ์ƒํƒœ
78
  this.escapeKeyPressed = false;
79
  this.stallEscapeProgress = 0; // ์Šคํ†จ ํƒˆ์ถœ ์ง„ํ–‰๋„ (0~2์ดˆ)
@@ -652,7 +642,6 @@ class Fighter {
652
  }
653
 
654
  updateBullets(scene, deltaTime) {
655
- // ๊ธฐ๊ด€์ด ํƒ„ํ™˜ ์—…๋ฐ์ดํŠธ
656
  for (let i = this.bullets.length - 1; i >= 0; i--) {
657
  const bullet = this.bullets[i];
658
  bullet.position.add(bullet.velocity.clone().multiplyScalar(deltaTime));
@@ -670,204 +659,6 @@ class Fighter {
670
  this.bullets.splice(i, 1);
671
  }
672
  }
673
-
674
- // ๋ฏธ์‚ฌ์ผ ์—…๋ฐ์ดํŠธ
675
- for (let i = this.activeMissiles.length - 1; i >= 0; i--) {
676
- const missile = this.activeMissiles[i];
677
-
678
- if (missile.target && missile.target.mesh && missile.target.isLoaded) {
679
- // ํƒ€๊ฒŸ์„ ํ–ฅํ•ด ์œ ๋„
680
- const targetDirection = missile.target.position.clone().sub(missile.position).normalize();
681
-
682
- // ๋ถ€๋“œ๋Ÿฌ์šด ํšŒ์ „์„ ์œ„ํ•œ ๋ณด๊ฐ„
683
- missile.velocity.lerp(targetDirection.multiplyScalar(2000), deltaTime * 4); // ๋ฏธ์‚ฌ์ผ ์†๋„ 2000m/s
684
- missile.velocity.normalize().multiplyScalar(2000);
685
-
686
- // ๋ฏธ์‚ฌ์ผ ํšŒ์ „
687
- const missileDirection = missile.velocity.clone().normalize();
688
- const angle = Math.atan2(missileDirection.x, missileDirection.z);
689
- missile.rotation.y = angle;
690
- missile.rotation.x = Math.asin(-missileDirection.y);
691
- }
692
-
693
- // ์œ„์น˜ ์—…๋ฐ์ดํŠธ
694
- missile.position.add(missile.velocity.clone().multiplyScalar(deltaTime));
695
-
696
- // ์—ฐ๊ธฐ ํšจ๊ณผ ์ถ”๊ฐ€
697
- if (Math.random() > 0.7) {
698
- this.createMissileTrail(missile.position);
699
- }
700
-
701
- // 10km ์ด์ƒ ๋‚ ์•„๊ฐ€๊ฑฐ๋‚˜ ์ง€๋ฉด ์ถฉ๋Œ์‹œ ์ œ๊ฑฐ
702
- if (missile.position.distanceTo(missile.startPosition) > 10000 ||
703
- missile.position.y < 0 ||
704
- missile.life > 10) { // 10์ดˆ ํ›„ ์ž๋™ ํŒŒ๊ดด
705
- scene.remove(missile);
706
- this.activeMissiles.splice(i, 1);
707
- } else {
708
- missile.life += deltaTime;
709
- }
710
- }
711
- }
712
-
713
- createMissileTrail(position) {
714
- const trailGeometry = new THREE.SphereGeometry(2, 4, 4);
715
- const trailMaterial = new THREE.MeshBasicMaterial({
716
- color: 0x888888,
717
- transparent: true,
718
- opacity: 0.6
719
- });
720
-
721
- const trail = new THREE.Mesh(trailGeometry, trailMaterial);
722
- trail.position.copy(position);
723
-
724
- this.mesh.parent.add(trail);
725
-
726
- // ํŽ˜์ด๋“œ ์•„์›ƒ ์• ๋‹ˆ๋ฉ”์ด์…˜
727
- const fadeOut = () => {
728
- trail.material.opacity -= 0.02;
729
- trail.scale.multiplyScalar(1.05);
730
-
731
- if (trail.material.opacity > 0) {
732
- requestAnimationFrame(fadeOut);
733
- } else {
734
- this.mesh.parent.remove(trail);
735
- }
736
- };
737
-
738
- fadeOut();
739
- }
740
-
741
- shootMissile(scene, target) {
742
- if (this.missiles <= 0 || !target || !target.mesh) return;
743
-
744
- const currentTime = Date.now();
745
- if (currentTime - this.lastMissileFire < 6000) return; // 6์ดˆ ์ฟจ๋‹ค์šด
746
-
747
- this.missiles--;
748
- this.lastMissileFire = currentTime;
749
- this.weaponCooldown = 6000; // 6์ดˆ ์ฟจ๋‹ค์šด ์„ค์ •
750
-
751
- // ๋ฏธ์‚ฌ์ผ ๋ชจ๋ธ
752
- const missileGeometry = new THREE.CylinderGeometry(0.3, 0.5, 4, 8);
753
- const missileMaterial = new THREE.MeshBasicMaterial({
754
- color: 0xcccccc,
755
- emissive: 0xff6600,
756
- emissiveIntensity: 0.5
757
- });
758
- const missile = new THREE.Mesh(missileGeometry, missileMaterial);
759
-
760
- // ๋‚ ๊ฐœ ์ถ”๊ฐ€
761
- const wingGeometry = new THREE.BoxGeometry(2, 0.1, 0.5);
762
- const wingMaterial = new THREE.MeshBasicMaterial({ color: 0x666666 });
763
- const wing1 = new THREE.Mesh(wingGeometry, wingMaterial);
764
- const wing2 = new THREE.Mesh(wingGeometry, wingMaterial);
765
- wing1.position.z = -1;
766
- wing2.position.z = -1;
767
- wing2.rotation.z = Math.PI / 2;
768
- missile.add(wing1);
769
- missile.add(wing2);
770
-
771
- // ๋ฏธ์‚ฌ์ผ ์ดˆ๊ธฐ ์œ„์น˜ (๋‚ ๊ฐœ ์•„๋ž˜์—์„œ ๋ฐœ์‚ฌ)
772
- const launchOffset = new THREE.Vector3(0, -2, 5);
773
- launchOffset.applyEuler(this.rotation);
774
- missile.position.copy(this.position).add(launchOffset);
775
-
776
- // ๋ฏธ์‚ฌ์ผ ์ดˆ๊ธฐ ์†๋„
777
- const direction = new THREE.Vector3(0, 0, 1);
778
- direction.applyEuler(this.rotation);
779
- missile.velocity = direction.multiplyScalar(1000); // ์ดˆ๊ธฐ ์†๋„
780
-
781
- missile.rotation.copy(this.rotation);
782
- missile.rotateX(Math.PI / 2);
783
-
784
- // ๋ฏธ์‚ฌ์ผ ์†์„ฑ
785
- missile.target = target;
786
- missile.startPosition = missile.position.clone();
787
- missile.life = 0;
788
- missile.type = 'missile';
789
-
790
- scene.add(missile);
791
- this.activeMissiles.push(missile);
792
-
793
- // ๋ฐœ์‚ฌ ์‚ฌ์šด๋“œ
794
- try {
795
- const audio = new Audio('sounds/Towfirelaunch.ogg');
796
- audio.volume = 0.6;
797
- audio.play().catch(e => console.log('Missile launch sound not found'));
798
- } catch (e) {
799
- console.log('Audio error:', e);
800
- }
801
-
802
- // ๋ฝ์˜จ ์ดˆ๊ธฐํ™”
803
- this.missileTarget = null;
804
- this.missileLockCount = 0;
805
- this.missileLockTimer = 0;
806
- }
807
-
808
- updateMissileLock(enemies, deltaTime) {
809
- if (this.currentWeapon !== 'missile' || this.missiles <= 0) {
810
- this.missileTarget = null;
811
- this.missileLockCount = 0;
812
- return;
813
- }
814
-
815
- // ์ฟจ๋‹ค์šด ์—…๋ฐ์ดํŠธ
816
- if (this.weaponCooldown > 0) {
817
- this.weaponCooldown -= deltaTime * 1000;
818
- return;
819
- }
820
-
821
- // ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์  ์ฐพ๊ธฐ
822
- let closestEnemy = null;
823
- let closestDistance = Infinity;
824
-
825
- enemies.forEach(enemy => {
826
- if (!enemy.mesh || !enemy.isLoaded) return;
827
-
828
- const distance = this.position.distanceTo(enemy.position);
829
- if (distance < closestDistance && distance < 5000) { // 5km ์ด๋‚ด
830
- // ์‹œ์•ผ๊ฐ ํ™•์ธ
831
- const toEnemy = enemy.position.clone().sub(this.position).normalize();
832
- const forward = new THREE.Vector3(0, 0, 1);
833
- forward.applyEuler(this.rotation);
834
- const angle = forward.dot(toEnemy);
835
-
836
- if (angle > 0.5) { // ์‹œ์•ผ๊ฐ 60๋„ ์ด๋‚ด
837
- closestEnemy = enemy;
838
- closestDistance = distance;
839
- }
840
- }
841
- });
842
-
843
- // ํƒ€๊ฒŸ ๋ณ€๊ฒฝ์‹œ ๋ฝ์˜จ ์ดˆ๊ธฐํ™”
844
- if (closestEnemy !== this.missileTarget) {
845
- this.missileTarget = closestEnemy;
846
- this.missileLockCount = 0;
847
- this.missileLockTimer = 0;
848
- }
849
-
850
- // ๋ฝ์˜จ ํ”„๋กœ์„ธ์Šค
851
- if (this.missileTarget) {
852
- this.missileLockTimer += deltaTime;
853
-
854
- // 0.5์ดˆ๋งˆ๋‹ค ๋ฝ์˜จ ์นด์šดํŠธ ์ฆ๊ฐ€
855
- if (this.missileLockTimer >= 0.5) {
856
- this.missileLockTimer = 0;
857
- this.missileLockCount++;
858
-
859
- // ๋ฝ์˜จ ์‚ฌ์šด๋“œ (lock.ogg๊ฐ€ ์—†์œผ๋ฉด ๋ฌด์‹œ)
860
- try {
861
- // const lockSound = new Audio('sounds/lock.ogg');
862
- // lockSound.volume = 0.3;
863
- // lockSound.play().catch(e => {});
864
- } catch (e) {}
865
-
866
- if (this.missileLockCount >= 3) {
867
- this.missileLockCount = 3; // ์ตœ๋Œ€ 3
868
- }
869
- }
870
- }
871
  }
872
 
873
  takeDamage(damage) {
@@ -1296,7 +1087,7 @@ class Game {
1296
  this.bgm = null;
1297
  this.bgmPlaying = false;
1298
 
1299
- this.keys = { w: false, a: false, s: false, d: false, f: false, r: false };
1300
  this.isStarted = false;
1301
 
1302
  this.setupScene();
@@ -1537,12 +1328,6 @@ class Game {
1537
  case 'KeyS': this.keys.s = true; break;
1538
  case 'KeyD': this.keys.d = true; break;
1539
  case 'KeyF': this.keys.f = true; break;
1540
- case 'KeyR':
1541
- if (!this.keys.r) {
1542
- this.keys.r = true;
1543
- this.switchWeapon();
1544
- }
1545
- break;
1546
  }
1547
  });
1548
 
@@ -1555,7 +1340,6 @@ class Game {
1555
  case 'KeyS': this.keys.s = false; break;
1556
  case 'KeyD': this.keys.d = false; break;
1557
  case 'KeyF': this.keys.f = false; break;
1558
- case 'KeyR': this.keys.r = false; break;
1559
  }
1560
  });
1561
 
@@ -1573,15 +1357,8 @@ class Game {
1573
  if (!document.pointerLockElement || this.isGameOver || !gameStarted) return;
1574
 
1575
  if (event.button === 0) { // ์™ผ์ชฝ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ
1576
- if (this.fighter.currentWeapon === 'mg') {
1577
- this.fighter.isMouseDown = true;
1578
- this.lastShootTime = 0; // ์ฆ‰์‹œ ๋ฐœ์‚ฌ
1579
- } else if (this.fighter.currentWeapon === 'missile') {
1580
- // ๋ฏธ์‚ฌ์ผ ๋ฐœ์‚ฌ
1581
- if (this.fighter.missileTarget && this.fighter.missileLockCount >= 3) {
1582
- this.fighter.shootMissile(this.scene, this.fighter.missileTarget);
1583
- }
1584
- }
1585
  }
1586
  });
1587
 
@@ -1598,24 +1375,19 @@ class Game {
1598
  });
1599
  }
1600
 
1601
- switchWeapon() {
1602
- if (this.fighter.currentWeapon === 'mg') {
1603
- this.fighter.currentWeapon = 'missile';
1604
- } else {
1605
- this.fighter.currentWeapon = 'mg';
1606
  }
1607
 
1608
- // ๋ฌด๊ธฐ ๋ณ€๊ฒฝ์‹œ ๋ฝ์˜จ ์ดˆ๊ธฐํ™”
1609
- this.fighter.missileTarget = null;
1610
- this.fighter.missileLockCount = 0;
1611
- this.fighter.missileLockTimer = 0;
1612
 
1613
- // ๋ฌด๊ธฐ ๋ณ€๊ฒฝ ์‚ฌ์šด๋“œ (switch.ogg๊ฐ€ ์—†์œผ๋ฉด ๋ฌด์‹œ)
1614
- try {
1615
- // const switchSound = new Audio('sounds/switch.ogg');
1616
- // switchSound.volume = 0.3;
1617
- // switchSound.play().catch(e => {});
1618
- } catch (e) {}
1619
  }
1620
 
1621
  startBGM() {
@@ -1688,47 +1460,7 @@ class Game {
1688
 
1689
  if (scoreElement) scoreElement.textContent = `Score: ${this.score}`;
1690
  if (timeElement) timeElement.textContent = `Time: ${this.gameTime}s`;
1691
-
1692
- // ๋ฌด๊ธฐ ํ‘œ์‹œ ์—…๋ฐ์ดํŠธ
1693
- if (ammoElement) {
1694
- let weaponDisplay = '';
1695
- if (this.fighter.currentWeapon === 'mg') {
1696
- weaponDisplay = `
1697
- <div style="font-size: 12px; margin-bottom: 5px;">R: WEAPON CHANGE</div>
1698
- <div style="font-size: 16px; color: #00ff00;">20MM MG</div>
1699
- <div>AMMO: ${this.fighter.ammo}</div>
1700
- `;
1701
- } else {
1702
- const cooldownSeconds = Math.ceil(this.fighter.weaponCooldown / 1000);
1703
- weaponDisplay = `
1704
- <div style="font-size: 12px; margin-bottom: 5px;">R: WEAPON CHANGE</div>
1705
- <div style="font-size: 16px; color: #ff8800;">AIM-9 MISSILE</div>
1706
- <div>COUNT: ${this.fighter.missiles}</div>
1707
- `;
1708
-
1709
- // ์ฟจ๋‹ค์šด ์ค‘์ด๋ฉด ๋ชจ๋ž˜์‹œ๊ณ„ ํ‘œ์‹œ
1710
- if (this.fighter.weaponCooldown > 0) {
1711
- weaponDisplay += `<div style="font-size: 20px; margin-top: 5px;">โณ ${cooldownSeconds}s</div>`;
1712
- } else if (this.fighter.missileTarget) {
1713
- // ๋ฝ์˜จ ์ง„ํ–‰ ์ƒํƒœ ํ‘œ์‹œ
1714
- const lockSymbols = ['โ—ฏ', 'โ—‰', 'โ—‰'];
1715
- let lockDisplay = '';
1716
- for (let i = 0; i < 3; i++) {
1717
- if (i < this.fighter.missileLockCount) {
1718
- lockDisplay += `<span style="color: #ff0000;">${lockSymbols[i]}</span> `;
1719
- } else {
1720
- lockDisplay += `<span style="color: #666;">${lockSymbols[0]}</span> `;
1721
- }
1722
- }
1723
- weaponDisplay += `<div style="margin-top: 5px;">LOCK: ${lockDisplay}</div>`;
1724
-
1725
- if (this.fighter.missileLockCount >= 3) {
1726
- weaponDisplay += `<div style="color: #ff0000; animation: blink 0.5s infinite;">READY TO FIRE</div>`;
1727
- }
1728
- }
1729
- }
1730
- ammoElement.innerHTML = weaponDisplay;
1731
- }
1732
 
1733
  if (gameStatsElement) {
1734
  gameStatsElement.innerHTML = `
@@ -2163,32 +1895,6 @@ class Game {
2163
  }
2164
  }
2165
 
2166
- // ํ”Œ๋ ˆ์ด์–ด ๋ฏธ์‚ฌ์ผ vs ์ ๊ธฐ ์ถฉ๋Œ
2167
- for (let i = this.fighter.activeMissiles.length - 1; i >= 0; i--) {
2168
- const missile = this.fighter.activeMissiles[i];
2169
-
2170
- if (missile.target && missile.target.mesh && missile.target.isLoaded) {
2171
- const distance = missile.position.distanceTo(missile.target.position);
2172
- if (distance < 50) { // ๋ฏธ์‚ฌ์ผ ์ถฉ๋Œ ๊ฑฐ๋ฆฌ
2173
- this.scene.remove(missile);
2174
- this.fighter.activeMissiles.splice(i, 1);
2175
-
2176
- // ํฐ ํญ๋ฐœ ์ดํŽ™ํŠธ
2177
- this.createMissileExplosion(missile.target.position);
2178
-
2179
- // ๋ฏธ์‚ฌ์ผ ๋ฐ๋ฏธ์ง€ (500)
2180
- if (missile.target.takeDamage(GAME_CONSTANTS.MISSILE_DAMAGE)) {
2181
- const enemyIndex = this.enemies.indexOf(missile.target);
2182
- if (enemyIndex !== -1) {
2183
- missile.target.destroy();
2184
- this.enemies.splice(enemyIndex, 1);
2185
- this.score += 250; // ๋ฏธ์‚ฌ์ผ ๊ฒฉ์ถ”๋Š” ๋” ๋งŽ์€ ์ ์ˆ˜
2186
- }
2187
- }
2188
- }
2189
- }
2190
- }
2191
-
2192
  // ์  ํƒ„ํ™˜ vs ํ”Œ๋ ˆ์ด์–ด ์ถฉ๋Œ
2193
  this.enemies.forEach(enemy => {
2194
  enemy.bullets.forEach((bullet, index) => {
@@ -2207,107 +1913,6 @@ class Game {
2207
  });
2208
  });
2209
  }
2210
-
2211
- createMissileExplosion(position) {
2212
- // ๋Œ€ํ˜• ํญ๋ฐœ ํšจ๊ณผ
2213
- const explosionGroup = new THREE.Group();
2214
- explosionGroup.position.copy(position);
2215
-
2216
- // ์ค‘์•™ ํญ๋ฐœ
2217
- const coreGeometry = new THREE.SphereGeometry(10, 16, 16);
2218
- const coreMaterial = new THREE.MeshBasicMaterial({
2219
- color: 0xffff00,
2220
- emissive: 0xffaa00,
2221
- emissiveIntensity: 2.0,
2222
- transparent: true,
2223
- opacity: 1.0
2224
- });
2225
- const core = new THREE.Mesh(coreGeometry, coreMaterial);
2226
- explosionGroup.add(core);
2227
-
2228
- // ์™ธ๋ถ€ ํญ๋ฐœ ๋ง
2229
- const ringGeometry = new THREE.TorusGeometry(15, 5, 8, 16);
2230
- const ringMaterial = new THREE.MeshBasicMaterial({
2231
- color: 0xff6600,
2232
- emissive: 0xff3300,
2233
- emissiveIntensity: 1.5,
2234
- transparent: true,
2235
- opacity: 0.8
2236
- });
2237
- const ring = new THREE.Mesh(ringGeometry, ringMaterial);
2238
- explosionGroup.add(ring);
2239
-
2240
- // ํŒŒํŽธ ํŒŒํ‹ฐํด
2241
- const particleCount = 30;
2242
- const particles = [];
2243
-
2244
- for (let i = 0; i < particleCount; i++) {
2245
- const particleGeometry = new THREE.SphereGeometry(Math.random() * 2 + 0.5, 4, 4);
2246
- const particleMaterial = new THREE.MeshBasicMaterial({
2247
- color: Math.random() > 0.5 ? 0xffaa00 : 0xff6600,
2248
- emissive: 0xffaa00,
2249
- emissiveIntensity: 1.0,
2250
- transparent: true,
2251
- opacity: 1.0
2252
- });
2253
-
2254
- const particle = new THREE.Mesh(particleGeometry, particleMaterial);
2255
- particle.position.set(
2256
- (Math.random() - 0.5) * 10,
2257
- (Math.random() - 0.5) * 10,
2258
- (Math.random() - 0.5) * 10
2259
- );
2260
-
2261
- particle.velocity = new THREE.Vector3(
2262
- (Math.random() - 0.5) * 200,
2263
- (Math.random() - 0.5) * 200,
2264
- (Math.random() - 0.5) * 200
2265
- );
2266
-
2267
- particle.life = 1.5;
2268
- explosionGroup.add(particle);
2269
- particles.push(particle);
2270
- }
2271
-
2272
- this.scene.add(explosionGroup);
2273
-
2274
- // ํญ๋ฐœ ์• ๋‹ˆ๋ฉ”์ด์…˜
2275
- const animateExplosion = () => {
2276
- // ์ค‘์•™ ํญ๋ฐœ ํ™•์žฅ
2277
- core.scale.multiplyScalar(1.15);
2278
- core.material.opacity *= 0.92;
2279
-
2280
- // ๋ง ํ™•์žฅ ๋ฐ ํšŒ์ „
2281
- ring.scale.multiplyScalar(1.1);
2282
- ring.rotation.x += 0.1;
2283
- ring.rotation.y += 0.15;
2284
- ring.material.opacity *= 0.94;
2285
-
2286
- // ํŒŒํ‹ฐํด ์• ๋‹ˆ๋ฉ”์ด์…˜
2287
- particles.forEach(particle => {
2288
- particle.life -= 0.02;
2289
- particle.position.add(particle.velocity.clone().multiplyScalar(0.02));
2290
- particle.velocity.y -= 3; // ์ค‘๋ ฅ
2291
- particle.material.opacity = particle.life / 1.5;
2292
- particle.scale.multiplyScalar(0.98);
2293
- });
2294
-
2295
- if (core.material.opacity > 0.01) {
2296
- requestAnimationFrame(animateExplosion);
2297
- } else {
2298
- this.scene.remove(explosionGroup);
2299
- }
2300
- };
2301
-
2302
- animateExplosion();
2303
-
2304
- // ํญ๋ฐœ ์‚ฌ์šด๋“œ
2305
- try {
2306
- const explosionSound = new Audio('sounds/explosion.ogg');
2307
- explosionSound.volume = 0.6;
2308
- explosionSound.play().catch(e => console.log('Explosion sound not found'));
2309
- } catch (e) {}
2310
- }
2311
 
2312
  createHitEffect(position) {
2313
  // ํ”ผ๊ฒฉ ํŒŒํ‹ฐํด ํšจ๊ณผ ์ƒ์„ฑ
@@ -2399,7 +2004,7 @@ class Game {
2399
  try {
2400
  const hitSound = new Audio('sounds/hit.ogg');
2401
  hitSound.volume = 0.3;
2402
- hitSound.play().catch(e => console.log('Hit sound not found'));
2403
  } catch (e) {}
2404
  }
2405
 
@@ -2470,10 +2075,8 @@ class Game {
2470
  this.fighter.updatePhysics(deltaTime);
2471
  this.fighter.updateBullets(this.scene, deltaTime);
2472
 
2473
- // ์ค‘๋ณต๋œ ๋ฏธ์‚ฌ์ผ ๋ฝ์˜จ ์—…๋ฐ์ดํŠธ ๋ผ์ธ ์ œ๊ฑฐ (์ด๋ฏธ ์œ„์— ์žˆ์Œ)
2474
-
2475
  // ๋งˆ์šฐ์Šค ๋ˆ„๋ฆ„ ์ƒํƒœ์ผ ๋•Œ ์—ฐ์† ๋ฐœ์‚ฌ
2476
- if (this.fighter.isMouseDown && this.isStarted && this.fighter.currentWeapon === 'mg') {
2477
  const currentShootTime = Date.now();
2478
  if (!this.lastShootTime || currentShootTime - this.lastShootTime >= 100) { // 0.1์ดˆ๋งˆ๋‹ค
2479
  this.fighter.shoot(this.scene);
@@ -2481,11 +2084,6 @@ class Game {
2481
  }
2482
  }
2483
 
2484
- // ๋ฏธ์‚ฌ์ผ ๋ฝ์˜จ ์—…๋ฐ์ดํŠธ
2485
- if (this.fighter.currentWeapon === 'missile') {
2486
- this.fighter.updateMissileLock(this.enemies, deltaTime);
2487
- }
2488
-
2489
  if (this.isStarted) {
2490
  // ์ ๊ธฐ๋“ค์—๊ฒŒ ์„œ๋กœ์˜ ์ฐธ์กฐ ์ „๋‹ฌ (์ถฉ๋Œ ํšŒํ”ผ์šฉ)
2491
  this.enemies.forEach(enemy => {
 
20
  MISSILE_COUNT: 6,
21
  AMMO_COUNT: 940, // 940๋ฐœ๋กœ ๋ณ€๊ฒฝ
22
  BULLET_DAMAGE: 25, // ๋ฐœ๋‹น 25 ๋ฐ๋ฏธ์ง€
 
23
  MAX_HEALTH: 1000 // ์ฒด๋ ฅ 1000
24
  };
25
 
 
60
  this.missiles = GAME_CONSTANTS.MISSILE_COUNT;
61
  this.ammo = GAME_CONSTANTS.AMMO_COUNT;
62
  this.bullets = [];
 
63
  this.lastShootTime = 0;
64
  this.isMouseDown = false; // ๋งˆ์šฐ์Šค ๋ˆ„๋ฆ„ ์ƒํƒœ ์ถ”์ 
65
  this.gunfireAudios = []; // ๊ธฐ๊ด€์ด ์†Œ๋ฆฌ ๋ฐฐ์—ด (์ตœ๋Œ€ 5๊ฐœ)
66
 
 
 
 
 
 
 
 
 
67
  // ์Šคํ†จ ํƒˆ์ถœ์„ ์œ„ํ•œ Fํ‚ค ์ƒํƒœ
68
  this.escapeKeyPressed = false;
69
  this.stallEscapeProgress = 0; // ์Šคํ†จ ํƒˆ์ถœ ์ง„ํ–‰๋„ (0~2์ดˆ)
 
642
  }
643
 
644
  updateBullets(scene, deltaTime) {
 
645
  for (let i = this.bullets.length - 1; i >= 0; i--) {
646
  const bullet = this.bullets[i];
647
  bullet.position.add(bullet.velocity.clone().multiplyScalar(deltaTime));
 
659
  this.bullets.splice(i, 1);
660
  }
661
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  }
663
 
664
  takeDamage(damage) {
 
1087
  this.bgm = null;
1088
  this.bgmPlaying = false;
1089
 
1090
+ this.keys = { w: false, a: false, s: false, d: false, f: false };
1091
  this.isStarted = false;
1092
 
1093
  this.setupScene();
 
1328
  case 'KeyS': this.keys.s = true; break;
1329
  case 'KeyD': this.keys.d = true; break;
1330
  case 'KeyF': this.keys.f = true; break;
 
 
 
 
 
 
1331
  }
1332
  });
1333
 
 
1340
  case 'KeyS': this.keys.s = false; break;
1341
  case 'KeyD': this.keys.d = false; break;
1342
  case 'KeyF': this.keys.f = false; break;
 
1343
  }
1344
  });
1345
 
 
1357
  if (!document.pointerLockElement || this.isGameOver || !gameStarted) return;
1358
 
1359
  if (event.button === 0) { // ์™ผ์ชฝ ๋งˆ์šฐ์Šค ๋ฒ„ํŠผ
1360
+ this.fighter.isMouseDown = true;
1361
+ this.lastShootTime = 0; // ์ฆ‰์‹œ ๋ฐœ์‚ฌ
 
 
 
 
 
 
 
1362
  }
1363
  });
1364
 
 
1375
  });
1376
  }
1377
 
1378
+ startGame() {
1379
+ if (!this.isLoaded) {
1380
+ console.log('๊ฒŒ์ž„์ด ์•„์ง ๋กœ๋”ฉ ์ค‘์ž…๋‹ˆ๋‹ค...');
1381
+ return;
 
1382
  }
1383
 
1384
+ this.isStarted = true;
1385
+ this.startGameTimer();
 
 
1386
 
1387
+ // ์—”์ง„ ์†Œ๋ฆฌ ์‹œ์ž‘
1388
+ this.fighter.startEngineSound();
1389
+
1390
+ console.log('๊ฒŒ์ž„ ์‹œ์ž‘!');
 
 
1391
  }
1392
 
1393
  startBGM() {
 
1460
 
1461
  if (scoreElement) scoreElement.textContent = `Score: ${this.score}`;
1462
  if (timeElement) timeElement.textContent = `Time: ${this.gameTime}s`;
1463
+ if (ammoElement) ammoElement.textContent = `AMMO: ${this.fighter.ammo}`;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1464
 
1465
  if (gameStatsElement) {
1466
  gameStatsElement.innerHTML = `
 
1895
  }
1896
  }
1897
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1898
  // ์  ํƒ„ํ™˜ vs ํ”Œ๋ ˆ์ด์–ด ์ถฉ๋Œ
1899
  this.enemies.forEach(enemy => {
1900
  enemy.bullets.forEach((bullet, index) => {
 
1913
  });
1914
  });
1915
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1916
 
1917
  createHitEffect(position) {
1918
  // ํ”ผ๊ฒฉ ํŒŒํ‹ฐํด ํšจ๊ณผ ์ƒ์„ฑ
 
2004
  try {
2005
  const hitSound = new Audio('sounds/hit.ogg');
2006
  hitSound.volume = 0.3;
2007
+ hitSound.play().catch(e => {});
2008
  } catch (e) {}
2009
  }
2010
 
 
2075
  this.fighter.updatePhysics(deltaTime);
2076
  this.fighter.updateBullets(this.scene, deltaTime);
2077
 
 
 
2078
  // ๋งˆ์šฐ์Šค ๋ˆ„๋ฆ„ ์ƒํƒœ์ผ ๋•Œ ์—ฐ์† ๋ฐœ์‚ฌ
2079
+ if (this.fighter.isMouseDown && this.isStarted) {
2080
  const currentShootTime = Date.now();
2081
  if (!this.lastShootTime || currentShootTime - this.lastShootTime >= 100) { // 0.1์ดˆ๋งˆ๋‹ค
2082
  this.fighter.shoot(this.scene);
 
2084
  }
2085
  }
2086
 
 
 
 
 
 
2087
  if (this.isStarted) {
2088
  // ์ ๊ธฐ๋“ค์—๊ฒŒ ์„œ๋กœ์˜ ์ฐธ์กฐ ์ „๋‹ฌ (์ถฉ๋Œ ํšŒํ”ผ์šฉ)
2089
  this.enemies.forEach(enemy => {