cutechicken commited on
Commit
3b6a2d6
โ€ข
1 Parent(s): 954c69c

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +113 -61
game.js CHANGED
@@ -4,14 +4,14 @@ import { PointerLockControls } from 'three/addons/controls/PointerLockControls.j
4
 
5
  // ๊ฒŒ์ž„ ์ƒ์ˆ˜
6
  const GAME_DURATION = 180;
7
- const MAP_SIZE = 400;
8
  const TANK_HEIGHT = 0.5;
9
  const ENEMY_GROUND_HEIGHT = 0;
10
  const ENEMY_SCALE = 1;
11
  const MAX_HEALTH = 1000;
12
  const ENEMY_MOVE_SPEED = 0.1;
13
  const ENEMY_COUNT_MAX = 3;
14
- const PARTICLE_COUNT = 5;
15
  const BUILDING_COUNT = 30;
16
  const ENEMY_CONFIG = {
17
  ATTACK_RANGE: 100,
@@ -160,15 +160,6 @@ class TankPlayer {
160
 
161
  async initialize(scene, loader) {
162
  try {
163
- // ๊ทธ๋ฆผ์ž ํ‰๋ฉด ๋จผ์ € ์ƒ์„ฑ
164
- const shadowPlaneGeometry = new THREE.PlaneGeometry(8, 8);
165
- const shadowPlaneMaterial = new THREE.ShadowMaterial({
166
- opacity: 0.3
167
- });
168
- this.shadowPlane = new THREE.Mesh(shadowPlaneGeometry, shadowPlaneMaterial);
169
- this.shadowPlane.receiveShadow = true;
170
- this.shadowPlane.rotation.x = -Math.PI / 2;
171
-
172
  const bodyResult = await loader.loadAsync('/models/abramsBody.glb');
173
  this.body = bodyResult.scene;
174
 
@@ -179,14 +170,7 @@ class TankPlayer {
179
  this.turretGroup.add(this.turret);
180
  this.body.add(this.turretGroup);
181
 
182
- // ํƒฑํฌ ์œ„์น˜ ๋†’์ด ์กฐ์ •
183
- this.body.position.y = 1.5;
184
-
185
- // ๊ทธ๋ฆผ์ž ํ‰๋ฉด ์œ„์น˜ ์กฐ์ • (body๊ฐ€ ์ƒ์„ฑ๋œ ํ›„์—)
186
- this.shadowPlane.position.y = -1.0;
187
- this.body.add(this.shadowPlane);
188
-
189
- // ๊ทธ๋ฆผ์ž ์„ค์ •
190
  this.body.traverse((child) => {
191
  if (child.isMesh) {
192
  child.castShadow = true;
@@ -205,15 +189,68 @@ class TankPlayer {
205
  }
206
  });
207
 
208
- // ์Šคํฐ ์œ„์น˜ ์„ค์ •
 
 
 
 
 
 
 
 
 
 
 
209
  const spawnPosition = new THREE.Vector3(
210
- (Math.random() - 0.5) * (MAP_SIZE * 0.8),
211
- TANK_HEIGHT,
212
  (Math.random() - 0.5) * (MAP_SIZE * 0.8)
213
  );
214
 
215
  this.body.position.copy(spawnPosition);
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  scene.add(this.body);
218
  this.isLoaded = true;
219
  this.updateAmmoDisplay();
@@ -608,7 +645,6 @@ class Enemy {
608
  this.mesh = result.scene;
609
  this.mesh.position.copy(this.position);
610
  this.mesh.scale.set(ENEMY_SCALE, ENEMY_SCALE, ENEMY_SCALE);
611
- this.mesh.position.y = 1.5; // ์  ํƒฑํฌ๋„ ๊ฐ™์€ ๋†’์ด๋กœ ์กฐ์ •
612
 
613
  this.mesh.traverse((child) => {
614
  if (child.isMesh) {
@@ -919,8 +955,6 @@ class Game {
919
  this.enemyLabels = new Map(); // ์  ๋ผ๋ฒจ์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ Map ์ถ”๊ฐ€
920
  this.raycaster = new THREE.Raycaster();
921
  this.crosshair = document.getElementById('crosshair');
922
- // ์„ฑ๋Šฅ ๊ด€๋ จ ์„ค์ • ์ถ”๊ฐ€
923
- this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // ํ”ฝ์…€ ๋น„์œจ ์ œํ•œ
924
  document.getElementById('gameContainer').appendChild(this.renderer.domElement);
925
 
926
 
@@ -966,7 +1000,7 @@ class Game {
966
 
967
  // ๋ Œ๋”๋Ÿฌ ์„ค์ •
968
  this.renderer.shadowMap.enabled = true;
969
- this.renderer.shadowMap.type = THREE.PCFShadowMap; // PCFSoftShadowMap์—์„œ ๋ณ€๊ฒฝ
970
  this.renderer.setPixelRatio(window.devicePixelRatio);
971
 
972
  // ์นด๋ฉ”๋ผ ์ดˆ๊ธฐ ์„ค์ •
@@ -1009,13 +1043,13 @@ class Game {
1009
  // ๊ธฐ๋ณธ ์”ฌ ์„ค์ •
1010
  this.setupScene();
1011
 
1012
- // ์•ˆ๊ฐœ ํšจ๊ณผ (๋„์‹œ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์กฐ์ •)
1013
- this.scene.fog = new THREE.FogExp2(0x888888, 0.002);
1014
- this.scene.background = new THREE.Color(0x888888);
1015
 
1016
  // ์กฐ๋ช… ์„ค์ •
1017
  // ์ฃผ๋ณ€๊ด‘
1018
- const ambientLight = new THREE.AmbientLight(0xffffff, 0.6); // ๋„์‹œ ํ™˜๊ฒฝ์„ ์œ„ํ•ด ๋ฐ๊ธฐ ์ฆ๊ฐ€
1019
  this.scene.add(ambientLight);
1020
 
1021
  // ๋ฉ”์ธ ํƒœ์–‘๊ด‘
@@ -1024,8 +1058,8 @@ class Game {
1024
  mainLight.castShadow = true;
1025
 
1026
  // ๊ทธ๋ฆผ์ž ์„ค์ •
1027
- mainLight.shadow.mapSize.width = 2048; // 4096์—์„œ ์ถ•์†Œ
1028
- mainLight.shadow.mapSize.height = 2048;
1029
  mainLight.shadow.camera.near = 0.5;
1030
  mainLight.shadow.camera.far = MAP_SIZE * 2;
1031
  mainLight.shadow.camera.left = -MAP_SIZE;
@@ -1038,34 +1072,52 @@ class Game {
1038
 
1039
  this.scene.add(mainLight);
1040
 
1041
- // ๋ณด์กฐ ์กฐ๋ช… (๋„์‹œ ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์กฐ์ •)
1042
- const secondaryLight = new THREE.DirectionalLight(0xffffff, 0.5);
1043
  secondaryLight.position.set(-50, 50, -50);
1044
  this.scene.add(secondaryLight);
1045
 
1046
- // ๋„์‹œ ๋งต ๋กœ๋“œ
1047
- try {
1048
- const cityMap = await this.loader.loadAsync('/models/map.glb');
1049
- cityMap.scene.scale.set(3, 3, 3); // ์Šค์ผ€์ผ์„ 3๋ฐฐ๋กœ ์ฆ๊ฐ€
1050
- cityMap.scene.traverse((child) => {
1051
- if (child.isMesh) {
1052
- child.castShadow = true;
1053
- child.receiveShadow = true;
1054
- child.material.needsUpdate = true;
1055
-
1056
- // ์ถฉ๋Œ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•ด obstacles ๋ฐฐ์—ด์— ์ถ”๊ฐ€
1057
- if (child.geometry) {
1058
- // ์Šค์ผ€์ผ์ด ์ ์šฉ๋œ ์ƒํƒœ๋กœ ์ถฉ๋Œ ๋ฐ•์Šค ์ƒ์„ฑ
1059
- child.geometry.computeBoundingBox();
1060
- this.obstacles.push(child);
1061
- }
 
 
 
 
 
 
 
 
1062
  }
1063
- });
1064
- this.scene.add(cityMap.scene);
1065
- } catch (error) {
1066
- console.error('Error loading city map:', error);
1067
- }
1068
-
 
 
 
 
 
 
 
 
 
 
1069
  // ํƒฑํฌ ์ดˆ๊ธฐํ™”
1070
  await this.tank.initialize(this.scene, this.loader);
1071
  if (!this.tank.isLoaded) {
@@ -1111,11 +1163,11 @@ class Game {
1111
  this.spawnEnemies();
1112
  this.startGameTimer();
1113
 
1114
- } catch (error) {
1115
- console.error('Game initialization error:', error);
1116
- this.handleLoadingError();
1117
- }
1118
- }
1119
 
1120
  // ๋ ˆ์ด๋” ์—…๋ฐ์ดํŠธ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
1121
  updateRadar() {
 
4
 
5
  // ๊ฒŒ์ž„ ์ƒ์ˆ˜
6
  const GAME_DURATION = 180;
7
+ const MAP_SIZE = 1000;
8
  const TANK_HEIGHT = 0.5;
9
  const ENEMY_GROUND_HEIGHT = 0;
10
  const ENEMY_SCALE = 1;
11
  const MAX_HEALTH = 1000;
12
  const ENEMY_MOVE_SPEED = 0.1;
13
  const ENEMY_COUNT_MAX = 3;
14
+ const PARTICLE_COUNT = 15;
15
  const BUILDING_COUNT = 30;
16
  const ENEMY_CONFIG = {
17
  ATTACK_RANGE: 100,
 
160
 
161
  async initialize(scene, loader) {
162
  try {
 
 
 
 
 
 
 
 
 
163
  const bodyResult = await loader.loadAsync('/models/abramsBody.glb');
164
  this.body = bodyResult.scene;
165
 
 
170
  this.turretGroup.add(this.turret);
171
  this.body.add(this.turretGroup);
172
 
173
+ // ๊ทธ๋ฆผ์ž ์„ค์ •์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€
 
 
 
 
 
 
 
174
  this.body.traverse((child) => {
175
  if (child.isMesh) {
176
  child.castShadow = true;
 
189
  }
190
  });
191
 
192
+ // ๊ทธ๋ฆผ์ž ํ‰๋ฉด
193
+ const shadowPlaneGeometry = new THREE.PlaneGeometry(8, 8);
194
+ const shadowPlaneMaterial = new THREE.ShadowMaterial({
195
+ opacity: 0.3
196
+ });
197
+ this.shadowPlane = new THREE.Mesh(shadowPlaneGeometry, shadowPlaneMaterial);
198
+ this.shadowPlane.receiveShadow = true;
199
+ this.shadowPlane.rotation.x = -Math.PI / 2;
200
+ this.shadowPlane.position.y = 0.1;
201
+ this.body.add(this.shadowPlane);
202
+
203
+ // ๊ฐ„๋‹จํ•œ ์Šคํฐ ์œ„์น˜ ์„ค์ •
204
  const spawnPosition = new THREE.Vector3(
205
+ (Math.random() - 0.5) * (MAP_SIZE * 0.8), // MAP_SIZE์˜ 80%๋งŒ ์‚ฌ์šฉ
206
+ TANK_HEIGHT, // ๊ณ ์ •๋œ ๋†’์ด ์‚ฌ์šฉ
207
  (Math.random() - 0.5) * (MAP_SIZE * 0.8)
208
  );
209
 
210
  this.body.position.copy(spawnPosition);
211
 
212
+ // ํญ๋ฐœ ์ดํŽ™ํŠธ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
213
+ this.createExplosionEffect = (scene, position) => {
214
+ // ํญ๋ฐœ ํŒŒํ‹ฐํด
215
+ for (let i = 0; i < 15; i++) {
216
+ const size = Math.random() * 0.2 + 0.1;
217
+ const geometry = new THREE.SphereGeometry(size);
218
+ const material = new THREE.MeshBasicMaterial({
219
+ color: Math.random() < 0.5 ? 0xff4500 : 0xff8c00
220
+ });
221
+ const particle = new THREE.Mesh(geometry, material);
222
+ particle.position.copy(position);
223
+
224
+ const speed = Math.random() * 0.3 + 0.2;
225
+ const angle = Math.random() * Math.PI * 2;
226
+ const elevation = Math.random() * Math.PI - Math.PI / 2;
227
+
228
+ particle.velocity = new THREE.Vector3(
229
+ Math.cos(angle) * Math.cos(elevation) * speed,
230
+ Math.sin(elevation) * speed,
231
+ Math.sin(angle) * Math.cos(elevation) * speed
232
+ );
233
+
234
+ particle.gravity = -0.01;
235
+ particle.life = Math.random() * 20 + 20;
236
+ particle.fadeRate = 1 / particle.life;
237
+
238
+ scene.add(particle);
239
+ window.gameInstance.particles.push({
240
+ mesh: particle,
241
+ velocity: particle.velocity,
242
+ gravity: particle.gravity,
243
+ life: particle.life,
244
+ fadeRate: particle.fadeRate
245
+ });
246
+ }
247
+
248
+ // ์ถฉ๋Œ ์‚ฌ์šด๋“œ ์žฌ์ƒ
249
+ const explosionSound = new Audio('sounds/explosion.ogg');
250
+ explosionSound.volume = 0.3;
251
+ explosionSound.play();
252
+ };
253
+
254
  scene.add(this.body);
255
  this.isLoaded = true;
256
  this.updateAmmoDisplay();
 
645
  this.mesh = result.scene;
646
  this.mesh.position.copy(this.position);
647
  this.mesh.scale.set(ENEMY_SCALE, ENEMY_SCALE, ENEMY_SCALE);
 
648
 
649
  this.mesh.traverse((child) => {
650
  if (child.isMesh) {
 
955
  this.enemyLabels = new Map(); // ์  ๋ผ๋ฒจ์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ Map ์ถ”๊ฐ€
956
  this.raycaster = new THREE.Raycaster();
957
  this.crosshair = document.getElementById('crosshair');
 
 
958
  document.getElementById('gameContainer').appendChild(this.renderer.domElement);
959
 
960
 
 
1000
 
1001
  // ๋ Œ๋”๋Ÿฌ ์„ค์ •
1002
  this.renderer.shadowMap.enabled = true;
1003
+ this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
1004
  this.renderer.setPixelRatio(window.devicePixelRatio);
1005
 
1006
  // ์นด๋ฉ”๋ผ ์ดˆ๊ธฐ ์„ค์ •
 
1043
  // ๊ธฐ๋ณธ ์”ฌ ์„ค์ •
1044
  this.setupScene();
1045
 
1046
+ // ์•ˆ๊ฐœ ํšจ๊ณผ
1047
+ this.scene.fog = new THREE.FogExp2(0x87CEEB, 0.0008);
1048
+ this.scene.background = new THREE.Color(0x87CEEB);
1049
 
1050
  // ์กฐ๋ช… ์„ค์ •
1051
  // ์ฃผ๋ณ€๊ด‘
1052
+ const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
1053
  this.scene.add(ambientLight);
1054
 
1055
  // ๋ฉ”์ธ ํƒœ์–‘๊ด‘
 
1058
  mainLight.castShadow = true;
1059
 
1060
  // ๊ทธ๋ฆผ์ž ์„ค์ •
1061
+ mainLight.shadow.mapSize.width = 4096;
1062
+ mainLight.shadow.mapSize.height = 4096;
1063
  mainLight.shadow.camera.near = 0.5;
1064
  mainLight.shadow.camera.far = MAP_SIZE * 2;
1065
  mainLight.shadow.camera.left = -MAP_SIZE;
 
1072
 
1073
  this.scene.add(mainLight);
1074
 
1075
+ // ๋ณด์กฐ ํƒœ์–‘๊ด‘
1076
+ const secondaryLight = new THREE.DirectionalLight(0xffffff, 0.3);
1077
  secondaryLight.position.set(-50, 50, -50);
1078
  this.scene.add(secondaryLight);
1079
 
1080
+ // ํ™˜๊ฒฝ๊ด‘
1081
+ const hemisphereLight = new THREE.HemisphereLight(
1082
+ 0x87CEEB,
1083
+ 0xFFE87C,
1084
+ 0.3
1085
+ );
1086
+ this.scene.add(hemisphereLight);
1087
+ // ์ง€ํ˜• ์ƒ์„ฑ
1088
+ const groundGeometry = new THREE.PlaneGeometry(MAP_SIZE, MAP_SIZE, 100, 100);
1089
+ const groundMaterial = new THREE.MeshStandardMaterial({
1090
+ color: 0xD2B48C,
1091
+ roughness: 0.8,
1092
+ metalness: 0.2,
1093
+ envMapIntensity: 1.0
1094
+ });
1095
+
1096
+ const ground = new THREE.Mesh(groundGeometry, groundMaterial);
1097
+ ground.rotation.x = -Math.PI / 2;
1098
+ ground.receiveShadow = true;
1099
+
1100
+ // ์ง€ํ˜• ๋†’์ด ์„ค์ •
1101
+ const vertices = ground.geometry.attributes.position.array;
1102
+ for (let i = 0; i < vertices.length; i += 3) {
1103
+ vertices[i + 2] = 0; // ๋ชจ๋“  ๋†’์ด๋ฅผ 0์œผ๋กœ ์„ค์ •
1104
  }
1105
+
1106
+ ground.geometry.attributes.position.needsUpdate = true;
1107
+ ground.geometry.computeVertexNormals();
1108
+ this.ground = ground;
1109
+ this.scene.add(ground);
1110
+
1111
+ // ๊ฒฉ์ž ํšจ๊ณผ ์ถ”๊ฐ€
1112
+ const gridHelper = new THREE.GridHelper(MAP_SIZE, 50, 0x000000, 0x000000);
1113
+ gridHelper.material.opacity = 0.1;
1114
+ gridHelper.material.transparent = true;
1115
+ gridHelper.position.y = 0.1;
1116
+ this.scene.add(gridHelper);
1117
+
1118
+ // ์‚ฌ๋ง‰ ์žฅ์‹ ์ถ”๊ฐ€
1119
+ await this.addDesertDecorations();
1120
+
1121
  // ํƒฑํฌ ์ดˆ๊ธฐํ™”
1122
  await this.tank.initialize(this.scene, this.loader);
1123
  if (!this.tank.isLoaded) {
 
1163
  this.spawnEnemies();
1164
  this.startGameTimer();
1165
 
1166
+ } catch (error) {
1167
+ console.error('Game initialization error:', error);
1168
+ this.handleLoadingError();
1169
+ }
1170
+ }
1171
 
1172
  // ๋ ˆ์ด๋” ์—…๋ฐ์ดํŠธ ๋ฉ”์„œ๋“œ ์ถ”๊ฐ€
1173
  updateRadar() {