cutechicken commited on
Commit
5eea967
β€’
1 Parent(s): f0eec51

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +119 -82
game.js CHANGED
@@ -32,69 +32,91 @@ class TankPlayer {
32
  this.turretGroup = new THREE.Group();
33
  this.health = MAX_HEALTH;
34
  this.isLoaded = false;
35
- this.ammo = 1; // λ³€κ²½: 10 -> 1
36
- this.maxAmmo = 1; // μΆ”κ°€: μ΅œλŒ€ 포탄 수
37
- this.isReloading = false; // μΆ”κ°€: 재μž₯μ „ μƒνƒœ
38
- this.reloadTime = 3000; // μΆ”κ°€: 3초 재μž₯μ „ μ‹œκ°„
39
  this.lastShootTime = 0;
40
  this.bullets = [];
41
  this.obstacles = [];
42
  this.scene = new THREE.Scene();
43
  this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
44
  this.renderer = new THREE.WebGLRenderer({ antialias: true });
 
 
 
 
 
 
 
 
 
45
  }
46
- // λ³„λ„μ˜ λ©”μ„œλ“œλ‘œ 뢄리
47
  createExplosionEffect(scene, position) {
48
- // 폭발 쀑심 ν”Œλž˜μ‹œ
49
- const flashGeometry = new THREE.SphereGeometry(3);
50
- const flashMaterial = new THREE.MeshBasicMaterial({
51
- color: 0xffff00,
52
- transparent: true,
53
- opacity: 1
54
- });
55
- const flash = new THREE.Mesh(flashGeometry, flashMaterial);
56
- flash.position.copy(position);
57
- scene.add(flash);
58
 
59
- // 폭발 νŒŒν‹°ν΄
60
- for (let i = 0; i < 30; i++) {
61
- const size = Math.random() * 0.5 + 0.3;
62
- const geometry = new THREE.SphereGeometry(size);
63
-
64
- // λ‹€μ–‘ν•œ μƒ‰μƒμ˜ νŒŒν‹°ν΄
65
- const colors = [0xff4500, 0xff8c00, 0xff0000, 0xffd700];
66
- const material = new THREE.MeshBasicMaterial({
67
- color: colors[Math.floor(Math.random() * colors.length)],
68
  transparent: true,
69
  opacity: 1
70
  });
71
-
72
- const particle = new THREE.Mesh(geometry, material);
73
- particle.position.copy(position);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
- // νŒŒν‹°ν΄ 속도와 λ°©ν–₯ μ„€μ •
76
- const speed = Math.random() * 0.5 + 0.3;
77
- const angle = Math.random() * Math.PI * 2;
78
- const elevation = Math.random() * Math.PI - Math.PI / 2;
79
 
80
- particle.velocity = new THREE.Vector3(
81
- Math.cos(angle) * Math.cos(elevation) * speed,
82
- Math.sin(elevation) * speed,
83
- Math.sin(angle) * Math.cos(elevation) * speed
84
- );
85
 
86
- particle.gravity = -0.015;
87
- particle.life = Math.random() * 30 + 30;
88
- particle.fadeRate = 0.97;
 
 
 
 
 
 
 
 
 
 
89
 
90
- scene.add(particle);
91
- window.gameInstance.particles.push({
92
- mesh: particle,
93
- velocity: particle.velocity,
94
- gravity: particle.gravity,
95
- life: particle.life,
96
- fadeRate: particle.fadeRate
97
- });
98
  }
99
 
100
  // 폭발 링 μ΄νŽ™νŠΈ
@@ -1491,6 +1513,11 @@ class Game {
1491
  this.enemyLabels = new Map(); // 적 라벨을 μΆ”μ ν•˜κΈ° μœ„ν•œ Map μΆ”κ°€
1492
  this.raycaster = new THREE.Raycaster();
1493
  this.crosshair = document.getElementById('crosshair');
 
 
 
 
 
1494
  document.getElementById('gameContainer').appendChild(this.renderer.domElement);
1495
 
1496
 
@@ -2600,49 +2627,59 @@ updateCrosshair() {
2600
  }
2601
 
2602
  animate() {
2603
- if (this.isGameOver) {
2604
- if (this.animationFrameId) {
2605
- cancelAnimationFrame(this.animationFrameId);
2606
- }
2607
- return;
2608
- }
 
 
 
 
2609
 
2610
- this.animationFrameId = requestAnimationFrame(() => this.animate());
2611
- // κ²Œμž„μ΄ μ‹œμž‘λ˜μ§€ μ•Šμ•˜μœΌλ©΄ λ Œλ”λ§λ§Œ μˆ˜ν–‰
 
2612
  if (!this.isStarted) {
2613
  this.renderer.render(this.scene, this.camera);
 
 
2614
  return;
2615
  }
2616
 
2617
- const currentTime = performance.now();
2618
- const deltaTime = (currentTime - this.lastTime) / 1000;
2619
- this.lastTime = currentTime;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2620
 
2621
- if (!this.isLoading) {
2622
- this.handleMovement();
2623
- this.tank.update(this.mouse.x, this.mouse.y, this.scene);
2624
-
2625
- const tankPosition = this.tank.getPosition();
2626
- this.enemies.forEach(enemy => {
2627
- enemy.update(tankPosition);
2628
-
2629
- if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
2630
- enemy.shoot(tankPosition);
2631
- }
2632
- });
2633
- this.updateEnemyLabels(); // 적 라벨 μ—…λ°μ΄νŠΈ μΆ”κ°€
2634
- this.updateParticles();
2635
- this.checkCollisions();
2636
- this.updateUI();
2637
- this.updateRadar(); // λ ˆμ΄λ” μ—…λ°μ΄νŠΈ μΆ”κ°€
2638
- // ν¬λ‘œμŠ€ν—€μ–΄ μ—…λ°μ΄νŠΈ μΆ”κ°€
2639
- this.updateCrosshair();
2640
- }
2641
-
2642
- this.renderer.render(this.scene, this.camera);
2643
- }
2644
- }
2645
 
 
 
 
 
 
 
 
2646
  // Start game
2647
  window.startGame = function() {
2648
  document.getElementById('startScreen').style.display = 'none';
 
32
  this.turretGroup = new THREE.Group();
33
  this.health = MAX_HEALTH;
34
  this.isLoaded = false;
35
+ this.ammo = 1;
36
+ this.maxAmmo = 1;
37
+ this.isReloading = false;
38
+ this.reloadTime = 3000;
39
  this.lastShootTime = 0;
40
  this.bullets = [];
41
  this.obstacles = [];
42
  this.scene = new THREE.Scene();
43
  this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
44
  this.renderer = new THREE.WebGLRenderer({ antialias: true });
45
+
46
+ // FPS μ œν•œμ„ μœ„ν•œ 속성 μΆ”κ°€
47
+ this.fps = 60;
48
+ this.frameInterval = 1000 / this.fps;
49
+ this.lastFrameTime = performance.now();
50
+ this.deltaTime = 0;
51
+
52
+ // λ Œλ”λŸ¬ FPS μ œν•œ μ„€μ •
53
+ this.renderer.setAnimationLoop(null); // κΈ°λ³Έ μ• λ‹ˆλ©”μ΄μ…˜ 루프 λΉ„ν™œμ„±ν™”
54
  }
55
+
56
  createExplosionEffect(scene, position) {
57
+ // ν˜„μž¬ μ‹œκ°„ 확인
58
+ const currentTime = performance.now();
59
+ this.deltaTime += currentTime - this.lastFrameTime;
60
+ this.lastFrameTime = currentTime;
 
 
 
 
 
 
61
 
62
+ // FPS μ œν•œ 체크
63
+ if (this.deltaTime < this.frameInterval) {
64
+ return;
65
+ }
66
+
67
+ // 폭발 쀑심 ν”Œλž˜μ‹œ
68
+ const flashGeometry = new THREE.SphereGeometry(3);
69
+ const flashMaterial = new THREE.MeshBasicMaterial({
70
+ color: 0xffff00,
71
  transparent: true,
72
  opacity: 1
73
  });
74
+ const flash = new THREE.Mesh(flashGeometry, flashMaterial);
75
+ flash.position.copy(position);
76
+ scene.add(flash);
77
+
78
+ // 폭발 νŒŒν‹°ν΄ (FPS에 맞좰 μ—…λ°μ΄νŠΈ)
79
+ const particleCount = Math.floor(30 * (this.deltaTime / this.frameInterval));
80
+ for (let i = 0; i < particleCount; i++) {
81
+ const size = Math.random() * 0.5 + 0.3;
82
+ const geometry = new THREE.SphereGeometry(size);
83
+
84
+ const colors = [0xff4500, 0xff8c00, 0xff0000, 0xffd700];
85
+ const material = new THREE.MeshBasicMaterial({
86
+ color: colors[Math.floor(Math.random() * colors.length)],
87
+ transparent: true,
88
+ opacity: 1
89
+ });
90
+
91
+ const particle = new THREE.Mesh(geometry, material);
92
+ particle.position.copy(position);
93
 
94
+ const speed = Math.random() * 0.5 + 0.3;
95
+ const angle = Math.random() * Math.PI * 2;
96
+ const elevation = Math.random() * Math.PI - Math.PI / 2;
 
97
 
98
+ particle.velocity = new THREE.Vector3(
99
+ Math.cos(angle) * Math.cos(elevation) * speed,
100
+ Math.sin(elevation) * speed,
101
+ Math.sin(angle) * Math.cos(elevation) * speed
102
+ );
103
 
104
+ particle.gravity = -0.015;
105
+ particle.life = Math.random() * 30 + 30;
106
+ particle.fadeRate = 0.97;
107
+
108
+ scene.add(particle);
109
+ window.gameInstance.particles.push({
110
+ mesh: particle,
111
+ velocity: particle.velocity,
112
+ gravity: particle.gravity,
113
+ life: particle.life,
114
+ fadeRate: particle.fadeRate
115
+ });
116
+ }
117
 
118
+ // deltaTime 리셋
119
+ this.deltaTime = 0;
 
 
 
 
 
 
120
  }
121
 
122
  // 폭발 링 μ΄νŽ™νŠΈ
 
1513
  this.enemyLabels = new Map(); // 적 라벨을 μΆ”μ ν•˜κΈ° μœ„ν•œ Map μΆ”κ°€
1514
  this.raycaster = new THREE.Raycaster();
1515
  this.crosshair = document.getElementById('crosshair');
1516
+ // FPS κ΄€λ ¨ 속성 μΆ”κ°€
1517
+ this.fps = 60;
1518
+ this.frameInterval = 1000 / this.fps;
1519
+ this.lastFrameTime = performance.now();
1520
+ this.deltaTime = 0;
1521
  document.getElementById('gameContainer').appendChild(this.renderer.domElement);
1522
 
1523
 
 
2627
  }
2628
 
2629
  animate() {
2630
+ if (this.isGameOver) {
2631
+ if (this.animationFrameId) {
2632
+ cancelAnimationFrame(this.animationFrameId);
2633
+ }
2634
+ return;
2635
+ }
2636
+
2637
+ const currentTime = performance.now();
2638
+ this.deltaTime += currentTime - this.lastFrameTime;
2639
+ this.lastFrameTime = currentTime;
2640
 
2641
+ // FPS μ œν•œμ„ μœ„ν•œ ν”„λ ˆμž„ μŠ€ν‚΅
2642
+ if (this.deltaTime >= this.frameInterval) {
2643
+ // κ²Œμž„μ΄ μ‹œμž‘λ˜μ§€ μ•Šμ•˜μœΌλ©΄ λ Œλ”λ§λ§Œ μˆ˜ν–‰
2644
  if (!this.isStarted) {
2645
  this.renderer.render(this.scene, this.camera);
2646
+ this.deltaTime = Math.min(this.deltaTime - this.frameInterval, this.frameInterval);
2647
+ this.animationFrameId = requestAnimationFrame(() => this.animate());
2648
  return;
2649
  }
2650
 
2651
+ // ν”„λ ˆμž„ μ—…λ°μ΄νŠΈ
2652
+ if (!this.isLoading) {
2653
+ this.handleMovement();
2654
+ this.tank.update(this.mouse.x, this.mouse.y, this.scene);
2655
+
2656
+ const tankPosition = this.tank.getPosition();
2657
+ this.enemies.forEach(enemy => {
2658
+ enemy.update(tankPosition);
2659
+
2660
+ if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
2661
+ enemy.shoot(tankPosition);
2662
+ }
2663
+ });
2664
+
2665
+ this.updateEnemyLabels();
2666
+ this.updateParticles();
2667
+ this.checkCollisions();
2668
+ this.updateUI();
2669
+ this.updateRadar();
2670
+ this.updateCrosshair();
2671
+ }
2672
 
2673
+ // λ Œλ”λ§
2674
+ this.renderer.render(this.scene, this.camera);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2675
 
2676
+ // deltaTime 리셋 (남은 μ‹œκ°„ μœ μ§€)
2677
+ this.deltaTime = Math.min(this.deltaTime - this.frameInterval, this.frameInterval);
2678
+ }
2679
+
2680
+ // λ‹€μŒ ν”„λ ˆμž„ μš”μ²­
2681
+ this.animationFrameId = requestAnimationFrame(() => this.animate());
2682
+ }
2683
  // Start game
2684
  window.startGame = function() {
2685
  document.getElementById('startScreen').style.display = 'none';