cutechicken commited on
Commit
57a9965
โ€ข
1 Parent(s): 75e71ec

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +132 -66
game.js CHANGED
@@ -327,8 +327,50 @@ class Game {
327
  // ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์„ค์ •
328
  this.setupEventListeners();
329
  this.initialize();
 
330
  }
331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  async initialize() {
333
  try {
334
  // ์กฐ๋ช… ์„ค์ •
@@ -587,22 +629,30 @@ createBuildings() {
587
  }
588
  }
589
 
590
- spawnEnemies() {
591
- const spawnEnemy = () => {
592
- if (this.enemies.length < ENEMY_COUNT_MAX && !this.isGameOver) {
593
- const position = this.getValidEnemySpawnPosition();
594
- if (position) {
595
- const type = Math.random() < 0.7 ? 'tank' : 'heavy';
596
- const enemy = new Enemy(this.scene, position, type);
597
- enemy.initialize(this.loader);
598
- this.enemies.push(enemy);
599
- }
 
 
 
 
 
 
600
  }
601
- setTimeout(spawnEnemy, 3000);
602
- };
603
 
604
- spawnEnemy();
605
- }
 
 
 
606
 
607
  getValidEnemySpawnPosition() {
608
  const margin = 20;
@@ -666,41 +716,47 @@ createBuildings() {
666
  }
667
 
668
  checkCollisions() {
669
- if (this.isLoading || !this.tank.isLoaded) return;
670
 
671
- const tankPosition = this.tank.getPosition();
 
672
 
673
- this.enemies.forEach(enemy => {
674
- if (!enemy.mesh || !enemy.isLoaded) return;
675
-
676
- enemy.bullets.forEach(bullet => {
677
- const distance = bullet.position.distanceTo(tankPosition);
678
- if (distance < 1) {
679
- if (this.tank.takeDamage(10)) {
680
- this.endGame();
681
- }
682
- this.scene.remove(bullet);
683
- enemy.bullets = enemy.bullets.filter(b => b !== bullet);
684
-
685
- this.createExplosion(bullet.position);
686
- document.getElementById('health').style.width =
687
- `${(this.tank.health / MAX_HEALTH) * 100}%`;
688
- }
689
- });
690
- });
691
 
692
- const tankBoundingBox = new THREE.Box3().setFromObject(this.tank.body);
693
- for (const building of this.buildings) {
694
- const buildingBox = new THREE.Box3().setFromObject(building);
695
- if (tankBoundingBox.intersectsBox(buildingBox)) {
696
- this.tank.body.position.copy(this.previousTankPosition);
697
- break;
 
 
 
 
 
 
 
 
 
 
698
  }
699
  }
700
-
701
- this.previousTankPosition = this.tank.body.position.clone();
702
  }
703
 
 
 
 
 
 
 
 
 
 
 
 
 
704
  endGame() {
705
  this.isGameOver = true;
706
  const gameOverDiv = document.createElement('div');
@@ -728,36 +784,46 @@ createBuildings() {
728
  }
729
 
730
  animate() {
731
- if (this.isGameOver) return;
732
 
733
- requestAnimationFrame(() => this.animate());
734
 
735
- const currentTime = performance.now();
736
- const deltaTime = (currentTime - this.lastTime) / 1000;
737
- this.lastTime = currentTime;
738
 
739
- if (this.isLoading) {
740
- this.renderer.render(this.scene, this.camera);
741
- return;
742
- }
743
 
744
- this.handleMovement();
745
- this.tank.update(this.mouse.x, this.mouse.y);
 
 
 
 
 
 
 
 
 
746
 
747
- const tankPosition = this.tank.getPosition();
748
- this.enemies.forEach(enemy => {
749
- enemy.update(tankPosition);
750
-
751
- if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
752
- enemy.shoot(tankPosition);
753
- }
754
- });
755
 
756
- this.updateParticles();
757
- this.checkCollisions();
758
- this.updateUI();
759
- this.renderer.render(this.scene, this.camera);
760
- }
 
761
 
762
  updateUI() {
763
  const healthBar = document.getElementById('health');
 
327
  // ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ ์„ค์ •
328
  this.setupEventListeners();
329
  this.initialize();
330
+ this.disposedObjects = new Set(); // ์ œ๊ฑฐ๋œ ๊ฐ์ฒด ์ถ”์ 
331
  }
332
 
333
+ // ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ๋ฅผ ์œ„ํ•œ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
334
+ dispose(object) {
335
+ if (this.disposedObjects.has(object)) return;
336
+
337
+ if (object.geometry) object.geometry.dispose();
338
+ if (object.material) {
339
+ if (Array.isArray(object.material)) {
340
+ object.material.forEach(material => material.dispose());
341
+ } else {
342
+ object.material.dispose();
343
+ }
344
+ }
345
+ if (object.parent) object.parent.remove(object);
346
+ this.disposedObjects.add(object);
347
+ }
348
+ // ์ด์•Œ ์ œ๊ฑฐ ์‹œ ๋ฆฌ์†Œ์Šค ์ •๋ฆฌ
349
+ cleanupBullets() {
350
+ // ํ”Œ๋ ˆ์ด์–ด ์ด์•Œ ์ •๋ฆฌ
351
+ for (let i = this.tank.bullets.length - 1; i >= 0; i--) {
352
+ const bullet = this.tank.bullets[i];
353
+ if (Math.abs(bullet.position.x) > MAP_SIZE/2 ||
354
+ Math.abs(bullet.position.z) > MAP_SIZE/2) {
355
+ this.dispose(bullet);
356
+ this.tank.bullets.splice(i, 1);
357
+ }
358
+ }
359
+ // ์  ์ด์•Œ ์ •๋ฆฌ
360
+ this.enemies.forEach(enemy => {
361
+ for (let i = enemy.bullets.length - 1; i >= 0; i--) {
362
+ const bullet = enemy.bullets[i];
363
+ if (Math.abs(bullet.position.x) > MAP_SIZE/2 ||
364
+ Math.abs(bullet.position.z) > MAP_SIZE/2) {
365
+ this.dispose(bullet);
366
+ enemy.bullets.splice(i, 1);
367
+ }
368
+ }
369
+ });
370
+ }
371
+ }
372
+
373
+
374
  async initialize() {
375
  try {
376
  // ์กฐ๋ช… ์„ค์ •
 
629
  }
630
  }
631
 
632
+ spawnEnemies() {
633
+ let spawnTimeout;
634
+
635
+ const spawnEnemy = () => {
636
+ if (this.isGameOver) {
637
+ clearTimeout(spawnTimeout);
638
+ return;
639
+ }
640
+
641
+ if (this.enemies.length < ENEMY_COUNT_MAX) {
642
+ const position = this.getValidEnemySpawnPosition();
643
+ if (position) {
644
+ const type = Math.random() < 0.7 ? 'tank' : 'heavy';
645
+ const enemy = new Enemy(this.scene, position, type);
646
+ enemy.initialize(this.loader).catch(console.error);
647
+ this.enemies.push(enemy);
648
  }
649
+ }
 
650
 
651
+ spawnTimeout = setTimeout(spawnEnemy, 3000);
652
+ };
653
+
654
+ spawnEnemy();
655
+ }
656
 
657
  getValidEnemySpawnPosition() {
658
  const margin = 20;
 
716
  }
717
 
718
  checkCollisions() {
719
+ if (this.isLoading || !this.tank.isLoaded) return;
720
 
721
+ const tankPosition = this.tank.getPosition();
722
+ const tankBoundingBox = new THREE.Box3().setFromObject(this.tank.body);
723
 
724
+ // ์  ์ด์•Œ๊ณผ์˜ ์ถฉ๋Œ ๊ฒ€์‚ฌ๋ฅผ ์ตœ์ ํ™”
725
+ for (const enemy of this.enemies) {
726
+ if (!enemy.mesh || !enemy.isLoaded) continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
727
 
728
+ for (let i = enemy.bullets.length - 1; i >= 0; i--) {
729
+ const bullet = enemy.bullets[i];
730
+ const distance = bullet.position.distanceTo(tankPosition);
731
+
732
+ if (distance > 50) continue; // ๋จผ ๏ฟฝ๏ฟฝ์•Œ์€ ๊ฒ€์‚ฌ ์Šคํ‚ต
733
+
734
+ if (distance < 1) {
735
+ if (this.tank.takeDamage(10)) {
736
+ this.endGame();
737
+ return;
738
+ }
739
+ this.dispose(bullet);
740
+ enemy.bullets.splice(i, 1);
741
+ this.createExplosion(bullet.position);
742
+ document.getElementById('health').style.width =
743
+ `${(this.tank.health / MAX_HEALTH) * 100}%`;
744
  }
745
  }
 
 
746
  }
747
 
748
+ // ๊ฑด๋ฌผ๊ณผ์˜ ์ถฉ๋Œ ๊ฒ€์‚ฌ ์ตœ์ ํ™”
749
+ for (const building of this.buildings) {
750
+ const buildingBox = new THREE.Box3().setFromObject(building);
751
+ if (tankBoundingBox.intersectsBox(buildingBox)) {
752
+ this.tank.body.position.copy(this.previousTankPosition);
753
+ break;
754
+ }
755
+ }
756
+
757
+ this.previousTankPosition = this.tank.body.position.clone();
758
+ }
759
+
760
  endGame() {
761
  this.isGameOver = true;
762
  const gameOverDiv = document.createElement('div');
 
784
  }
785
 
786
  animate() {
787
+ if (this.isGameOver) return;
788
 
789
+ requestAnimationFrame(() => this.animate());
790
 
791
+ const currentTime = performance.now();
792
+ const deltaTime = (currentTime - this.lastTime) / 1000;
793
+ this.lastTime = currentTime;
794
 
795
+ if (this.isLoading) {
796
+ this.renderer.render(this.scene, this.camera);
797
+ return;
798
+ }
799
 
800
+ // ํ”„๋ ˆ์ž„ ์ œํ•œ (60fps)
801
+ if (deltaTime < 1/60) return;
802
+
803
+ this.handleMovement();
804
+ this.tank.update(this.mouse.x, this.mouse.y);
805
+
806
+ const tankPosition = this.tank.getPosition();
807
+
808
+ // ํ™”๋ฉด์— ๋ณด์ด๋Š” ์ ๋งŒ ์—…๋ฐ์ดํŠธ
809
+ this.enemies.forEach(enemy => {
810
+ if (!enemy.mesh || !enemy.isLoaded) return;
811
 
812
+ const distance = enemy.mesh.position.distanceTo(tankPosition);
813
+ if (distance > 200) return; // ๋จผ ์ ์€ ์—…๋ฐ์ดํŠธ ์Šคํ‚ต
814
+
815
+ enemy.update(tankPosition);
816
+ if (distance < ENEMY_CONFIG.ATTACK_RANGE) {
817
+ enemy.shoot(tankPosition);
818
+ }
819
+ });
820
 
821
+ this.updateParticles();
822
+ this.checkCollisions();
823
+ this.cleanupBullets();
824
+ this.updateUI();
825
+ this.renderer.render(this.scene, this.camera);
826
+ }
827
 
828
  updateUI() {
829
  const healthBar = document.getElementById('health');