gini1 commited on
Commit
473090a
Β·
verified Β·
1 Parent(s): 9bb6543

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +102 -60
game.js CHANGED
@@ -1,4 +1,3 @@
1
- // game.js
2
  import * as THREE from 'three';
3
  import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
4
  import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
@@ -10,12 +9,11 @@ const HELICOPTER_HEIGHT = 50;
10
  const ENEMY_SCALE = 3;
11
  const MAX_HEALTH = 1000;
12
  const ENEMY_MODELS = [
13
- './models/enemy1.glb', // μ‹€μ œ λͺ¨λΈ 파일 경둜둜 μˆ˜μ •
14
  './models/enemy2.glb',
15
  './models/enemy3.glb',
16
  './models/enemy4.glb'
17
  ];
18
-
19
  const ENEMY_CONFIG = {
20
  ATTACK_RANGE: 100,
21
  ATTACK_INTERVAL: 2000,
@@ -32,28 +30,46 @@ let ammo = 30;
32
  let currentStage = 1;
33
  let isGameOver = false;
34
 
35
- // μ‚¬μš΄λ“œ ν’€ 생성 ν•¨μˆ˜
36
- const createSoundPool = (soundUrl, poolSize = 10) => {
37
- const sounds = [];
38
- for (let i = 0; i < poolSize; i++) {
39
- const sound = new Audio(soundUrl);
40
- sounds.push(sound);
 
 
 
 
 
 
41
  }
42
- let currentIndex = 0;
43
-
44
- return {
45
- play: function() {
46
- sounds[currentIndex].currentTime = 0;
47
- sounds[currentIndex].play();
48
- currentIndex = (currentIndex + 1) % poolSize;
 
 
 
 
 
 
 
 
 
 
49
  }
50
- };
51
- };
 
 
52
 
53
  // μ‚¬μš΄λ“œ μ΄ˆκΈ°ν™”
54
  const sounds = {
55
  bgm: new Audio('Music.wav'),
56
- gunshot: createSoundPool('gun.wav', 10)
57
  };
58
  sounds.bgm.loop = true;
59
 
@@ -93,6 +109,13 @@ function init() {
93
  // Controls μ„€μ •
94
  controls = new PointerLockControls(camera, document.body);
95
 
 
 
 
 
 
 
 
96
  // 이벀트 λ¦¬μŠ€λ„ˆ μ„€μ •
97
  document.addEventListener('click', onClick);
98
  document.addEventListener('keydown', onKeyDown);
@@ -102,7 +125,7 @@ function init() {
102
  // μ§€ν˜• 생성
103
  createTerrain();
104
 
105
- // 적 λ‘œλ“œ
106
  loadEnemies();
107
  }
108
 
@@ -130,29 +153,12 @@ function createTerrain() {
130
  addObstacles();
131
  }
132
 
133
- function addObstacles() {
134
- const rockGeometry = new THREE.DodecahedronGeometry(10);
135
- const rockMaterial = new THREE.MeshStandardMaterial({
136
- color: 0x8B4513,
137
- roughness: 0.9
138
- });
139
-
140
- for (let i = 0; i < 100; i++) {
141
- const rock = new THREE.Mesh(rockGeometry, rockMaterial);
142
- rock.position.set(
143
- (Math.random() - 0.5) * MAP_SIZE * 0.9,
144
- Math.random() * 10,
145
- (Math.random() - 0.5) * MAP_SIZE * 0.9
146
- );
147
- rock.rotation.set(
148
- Math.random() * Math.PI,
149
- Math.random() * Math.PI,
150
- Math.random() * Math.PI
151
- );
152
- rock.castShadow = true;
153
- rock.receiveShadow = true;
154
- scene.add(rock);
155
- }
156
  }
157
 
158
  function loadEnemies() {
@@ -160,21 +166,32 @@ function loadEnemies() {
160
  const enemyCount = 3 + currentStage;
161
 
162
  for (let i = 0; i < enemyCount; i++) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  const modelPath = ENEMY_MODELS[i % ENEMY_MODELS.length];
164
-
165
- loader.load(modelPath,
166
  (gltf) => {
167
- console.log('Enemy model loaded successfully:', modelPath);
168
  const enemy = gltf.scene;
169
  enemy.scale.set(ENEMY_SCALE, ENEMY_SCALE, ENEMY_SCALE);
170
-
171
- const angle = (i / enemyCount) * Math.PI * 2;
172
- const radius = 200;
173
- enemy.position.set(
174
- Math.cos(angle) * radius,
175
- 10,
176
- Math.sin(angle) * radius
177
- );
178
 
179
  enemy.traverse((node) => {
180
  if (node.isMesh) {
@@ -185,13 +202,13 @@ function loadEnemies() {
185
  }
186
  });
187
 
 
 
188
  scene.add(enemy);
189
- enemies.push({
190
- model: enemy,
191
- health: 100,
192
- speed: 0.3 + (currentStage * 0.1),
193
- lastAttackTime: 0
194
- });
195
  },
196
  (xhr) => {
197
  console.log((xhr.loaded / xhr.total * 100) + '% loaded');
@@ -203,6 +220,31 @@ function loadEnemies() {
203
  }
204
  }
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  function onClick() {
207
  if (!controls.isLocked) {
208
  controls.lock();
 
 
1
  import * as THREE from 'three';
2
  import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
3
  import { PointerLockControls } from 'three/addons/controls/PointerLockControls.js';
 
9
  const ENEMY_SCALE = 3;
10
  const MAX_HEALTH = 1000;
11
  const ENEMY_MODELS = [
12
+ './models/enemy1.glb',
13
  './models/enemy2.glb',
14
  './models/enemy3.glb',
15
  './models/enemy4.glb'
16
  ];
 
17
  const ENEMY_CONFIG = {
18
  ATTACK_RANGE: 100,
19
  ATTACK_INTERVAL: 2000,
 
30
  let currentStage = 1;
31
  let isGameOver = false;
32
 
33
+ // μ‚¬μš΄λ“œ ν’€ 클래슀
34
+ class SoundPool {
35
+ constructor(soundUrl, poolSize = 10) {
36
+ this.sounds = [];
37
+ this.currentIndex = 0;
38
+ this.poolSize = poolSize;
39
+
40
+ for (let i = 0; i < poolSize; i++) {
41
+ const sound = new Audio(soundUrl);
42
+ sound.preload = 'auto';
43
+ this.sounds.push(sound);
44
+ }
45
  }
46
+
47
+ play() {
48
+ const sound = this.sounds[this.currentIndex];
49
+
50
+ // ν˜„μž¬ μž¬μƒ 쀑인 μ‚¬μš΄λ“œ μ΄ˆκΈ°ν™”
51
+ sound.pause();
52
+ sound.currentTime = 0;
53
+
54
+ // μƒˆλ‘œμš΄ Promise둜 μ‚¬μš΄λ“œ μž¬μƒ
55
+ const playPromise = sound.play();
56
+
57
+ if (playPromise !== undefined) {
58
+ playPromise.catch(error => {
59
+ console.error("Sound play error:", error);
60
+ // 였λ₯˜ λ°œμƒ μ‹œ μƒˆλ‘œμš΄ Audio 객체둜 ꡐ체
61
+ this.sounds[this.currentIndex] = new Audio(sound.src);
62
+ });
63
  }
64
+
65
+ this.currentIndex = (this.currentIndex + 1) % this.poolSize;
66
+ }
67
+ }
68
 
69
  // μ‚¬μš΄λ“œ μ΄ˆκΈ°ν™”
70
  const sounds = {
71
  bgm: new Audio('Music.wav'),
72
+ gunshot: new SoundPool('gun.wav', 20)
73
  };
74
  sounds.bgm.loop = true;
75
 
 
109
  // Controls μ„€μ •
110
  controls = new PointerLockControls(camera, document.body);
111
 
112
+ // 디버그 헬퍼 μΆ”κ°€
113
+ const axesHelper = new THREE.AxesHelper(5);
114
+ scene.add(axesHelper);
115
+
116
+ const gridHelper = new THREE.GridHelper(1000, 100);
117
+ scene.add(gridHelper);
118
+
119
  // 이벀트 λ¦¬μŠ€λ„ˆ μ„€μ •
120
  document.addEventListener('click', onClick);
121
  document.addEventListener('keydown', onKeyDown);
 
125
  // μ§€ν˜• 생성
126
  createTerrain();
127
 
128
+ console.log('Starting to load enemies...');
129
  loadEnemies();
130
  }
131
 
 
153
  addObstacles();
154
  }
155
 
156
+ function createTemporaryEnemy(position) {
157
+ const geometry = new THREE.BoxGeometry(5, 5, 5);
158
+ const material = new THREE.MeshPhongMaterial({ color: 0xff0000 });
159
+ const cube = new THREE.Mesh(geometry, material);
160
+ cube.position.copy(position);
161
+ return cube;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  }
163
 
164
  function loadEnemies() {
 
166
  const enemyCount = 3 + currentStage;
167
 
168
  for (let i = 0; i < enemyCount; i++) {
169
+ const angle = (i / enemyCount) * Math.PI * 2;
170
+ const radius = 200;
171
+ const position = new THREE.Vector3(
172
+ Math.cos(angle) * radius,
173
+ 10,
174
+ Math.sin(angle) * radius
175
+ );
176
+
177
+ // μž„μ‹œ 적 생성
178
+ const tempEnemy = createTemporaryEnemy(position);
179
+ scene.add(tempEnemy);
180
+ enemies.push({
181
+ model: tempEnemy,
182
+ health: 100,
183
+ speed: 0.3 + (currentStage * 0.1),
184
+ lastAttackTime: 0
185
+ });
186
+
187
+ // GLB λͺ¨λΈ λ‘œλ“œ μ‹œλ„
188
  const modelPath = ENEMY_MODELS[i % ENEMY_MODELS.length];
189
+ loader.load(modelPath,
 
190
  (gltf) => {
191
+ console.log('Enemy model loaded:', modelPath);
192
  const enemy = gltf.scene;
193
  enemy.scale.set(ENEMY_SCALE, ENEMY_SCALE, ENEMY_SCALE);
194
+ enemy.position.copy(position);
 
 
 
 
 
 
 
195
 
196
  enemy.traverse((node) => {
197
  if (node.isMesh) {
 
202
  }
203
  });
204
 
205
+ // μž„μ‹œ 적을 μ‹€μ œ λͺ¨λΈλ‘œ ꡐ체
206
+ scene.remove(tempEnemy);
207
  scene.add(enemy);
208
+ const index = enemies.findIndex(e => e.model === tempEnemy);
209
+ if (index !== -1) {
210
+ enemies[index].model = enemy;
211
+ }
 
 
212
  },
213
  (xhr) => {
214
  console.log((xhr.loaded / xhr.total * 100) + '% loaded');
 
220
  }
221
  }
222
 
223
+ function addObstacles() {
224
+ const rockGeometry = new THREE.DodecahedronGeometry(10);
225
+ const rockMaterial = new THREE.MeshStandardMaterial({
226
+ color: 0x8B4513,
227
+ roughness: 0.9
228
+ });
229
+
230
+ for (let i = 0; i < 100; i++) {
231
+ const rock = new THREE.Mesh(rockGeometry, rockMaterial);
232
+ rock.position.set(
233
+ (Math.random() - 0.5) * MAP_SIZE * 0.9,
234
+ Math.random() * 10,
235
+ (Math.random() - 0.5) * MAP_SIZE * 0.9
236
+ );
237
+ rock.rotation.set(
238
+ Math.random() * Math.PI,
239
+ Math.random() * Math.PI,
240
+ Math.random() * Math.PI
241
+ );
242
+ rock.castShadow = true;
243
+ rock.receiveShadow = true;
244
+ scene.add(rock);
245
+ }
246
+ }
247
+
248
  function onClick() {
249
  if (!controls.isLocked) {
250
  controls.lock();