cutechicken commited on
Commit
3d35704
β€’
1 Parent(s): 522c84b

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +108 -57
game.js CHANGED
@@ -836,6 +836,21 @@ class Enemy {
836
  this.adjustTankTilt();
837
  }
838
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
839
 
840
  findAlternativePath(playerPosition) {
841
  const currentPos = this.mesh.position.clone();
@@ -872,6 +887,13 @@ findAlternativePath(playerPosition) {
872
  return null;
873
  }
874
 
 
 
 
 
 
 
 
875
 
876
  async initialize(loader) {
877
  try {
@@ -898,22 +920,56 @@ findAlternativePath(playerPosition) {
898
 
899
  // μ‹œμ•Ό 확인 λ©”μ„œλ“œ (κΈ°μ‘΄ μ½”λ“œ μˆ˜μ •)
900
  checkLineOfSight(playerPosition) {
901
- if (!this.mesh) return false;
902
 
903
- const startPos = this.mesh.position.clone();
904
- startPos.y += 2; // 포탑 λ†’μ΄μ—μ„œ μ‹œμž‘
905
-
906
- const direction = new THREE.Vector3()
907
- .subVectors(playerPosition, startPos)
908
- .normalize();
909
- const distance = startPos.distanceTo(playerPosition);
910
 
911
- const raycaster = new THREE.Raycaster(startPos, direction, 0, distance);
912
- const intersects = raycaster.intersectObjects(window.gameInstance.obstacles, true);
913
 
914
- // μž₯애물이 μžˆμ„ 경우 false λ°˜ν™˜
915
- return intersects.length === 0;
916
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
917
  // 경둜 μœ νš¨μ„± 확인
918
  checkPathClear(start, end) {
919
  const direction = new THREE.Vector3().subVectors(end, start).normalize();
@@ -1521,7 +1577,7 @@ class Game {
1521
  this.obstacles = [];
1522
  }
1523
 
1524
- const BUILDING_COUNT = 50; // λ°”μœ„ λŒ€μ‹  건물둜 λ³€κ²½
1525
  const buildingModels = [
1526
  'models/house1.glb',
1527
  'models/house2.glb',
@@ -2317,52 +2373,47 @@ updateCrosshair() {
2317
  }
2318
 
2319
  animate() {
2320
- if (this.isGameOver) {
2321
- if (this.animationFrameId) {
2322
- cancelAnimationFrame(this.animationFrameId);
2323
- }
2324
- return;
2325
- }
2326
 
2327
- this.animationFrameId = requestAnimationFrame(() => this.animate());
2328
-
2329
- // κ²Œμž„μ΄ μ‹œμž‘λ˜μ§€ μ•Šμ•˜μœΌλ©΄ λ Œλ”λ§λ§Œ μˆ˜ν–‰
2330
- if (!this.isStarted) {
2331
- this.renderer.render(this.scene, this.camera);
2332
- return;
2333
- }
2334
 
2335
- const currentTime = performance.now();
2336
- const deltaTime = (currentTime - this.lastTime) / 1000;
2337
- this.lastTime = currentTime;
2338
 
2339
- if (!this.isLoading) {
2340
- this.handleMovement();
2341
- this.tank.update(this.mouse.x, this.mouse.y, this.scene);
2342
-
2343
- const tankPosition = this.tank.getPosition();
2344
-
2345
- // 각 적 탱크 μ—…λ°μ΄νŠΈ
2346
- this.enemies.forEach(enemy => {
2347
- enemy.update(tankPosition);
2348
-
2349
- // 적이 λ‘œλ“œλ˜μ—ˆκ³ , μ‹œμ•Ό ν™•λ³΄λ˜μ—ˆμ„ λ•Œλ§Œ λ°œμ‚¬
2350
- if (enemy.isLoaded &&
2351
- enemy.checkLineOfSight(tankPosition) &&
2352
- enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
2353
- enemy.shoot(tankPosition);
2354
- }
2355
- });
2356
-
2357
- this.updateEnemyLabels();
2358
- this.updateParticles();
2359
- this.checkCollisions();
2360
- this.updateUI();
2361
- this.updateRadar();
2362
- this.updateCrosshair();
2363
- }
2364
-
2365
- this.renderer.render(this.scene, this.camera);
2366
  }
2367
 
2368
  // Start game
 
836
  this.adjustTankTilt();
837
  }
838
 
839
+ checkLineOfSight(targetPosition) {
840
+ if (!this.mesh) return false;
841
+
842
+ const startPos = this.mesh.position.clone();
843
+ startPos.y += 2; // 포탑 높이
844
+ const direction = new THREE.Vector3()
845
+ .subVectors(targetPosition, startPos)
846
+ .normalize();
847
+ const distance = startPos.distanceTo(targetPosition);
848
+
849
+ const raycaster = new THREE.Raycaster(startPos, direction, 0, distance);
850
+ const intersects = raycaster.intersectObjects(window.gameInstance.obstacles, true);
851
+
852
+ return intersects.length === 0;
853
+ }
854
 
855
  findAlternativePath(playerPosition) {
856
  const currentPos = this.mesh.position.clone();
 
887
  return null;
888
  }
889
 
890
+ checkPathClear(start, end) {
891
+ const direction = new THREE.Vector3().subVectors(end, start).normalize();
892
+ const distance = start.distanceTo(end);
893
+ const raycaster = new THREE.Raycaster(start, direction, 0, distance);
894
+ const intersects = raycaster.intersectObjects(window.gameInstance.obstacles, true);
895
+ return intersects.length === 0;
896
+ }
897
 
898
  async initialize(loader) {
899
  try {
 
920
 
921
  // μ‹œμ•Ό 확인 λ©”μ„œλ“œ (κΈ°μ‘΄ μ½”λ“œ μˆ˜μ •)
922
  checkLineOfSight(playerPosition) {
923
+ if (!this.mesh) return false;
924
 
925
+ const startPos = this.mesh.position.clone();
926
+ startPos.y += 2; // 포탑 높이
927
+ const direction = new THREE.Vector3()
928
+ .subVectors(playerPosition, startPos)
929
+ .normalize();
930
+ const distance = startPos.distanceTo(playerPosition);
 
931
 
932
+ const raycaster = new THREE.Raycaster(startPos, direction, 0, distance);
933
+ const intersects = raycaster.intersectObjects(window.gameInstance.obstacles, true);
934
 
935
+ // μž₯μ• λ¬Όκ³Όμ˜ 좩돌이 μžˆλŠ”μ§€ 확인
936
+ return intersects.length === 0;
937
+ }
938
+ // λŒ€μ²΄ 경둜 μ°ΎκΈ° λ©”μ„œλ“œ
939
+ findAlternativePath(playerPosition) {
940
+ const currentPos = this.mesh.position.clone();
941
+ const directionToPlayer = new THREE.Vector3()
942
+ .subVectors(playerPosition, currentPos)
943
+ .normalize();
944
+
945
+ // 쒌우 90도 λ°©ν–₯ 계산
946
+ const leftDirection = new THREE.Vector3()
947
+ .copy(directionToPlayer)
948
+ .applyAxisAngle(new THREE.Vector3(0, 1, 0), Math.PI / 2);
949
+ const rightDirection = new THREE.Vector3()
950
+ .copy(directionToPlayer)
951
+ .applyAxisAngle(new THREE.Vector3(0, 1, 0), -Math.PI / 2);
952
+
953
+ // 쒌우 30λ―Έν„° 지점 확인
954
+ const checkDistance = 30;
955
+ const leftPoint = currentPos.clone().add(leftDirection.multiplyScalar(checkDistance));
956
+ const rightPoint = currentPos.clone().add(rightDirection.multiplyScalar(checkDistance));
957
+
958
+ // 각 λ°©ν–₯의 μž₯μ• λ¬Ό 체크
959
+ const leftClear = this.checkPathClear(currentPos, leftPoint);
960
+ const rightClear = this.checkPathClear(currentPos, rightPoint);
961
+
962
+ if (leftClear && rightClear) {
963
+ // λ‘˜ λ‹€ κ°€λŠ₯ν•˜λ©΄ 랜덀 선택
964
+ return Math.random() < 0.5 ? leftPoint : rightPoint;
965
+ } else if (leftClear) {
966
+ return leftPoint;
967
+ } else if (rightClear) {
968
+ return rightPoint;
969
+ }
970
+
971
+ return null;
972
+ }
973
  // 경둜 μœ νš¨μ„± 확인
974
  checkPathClear(start, end) {
975
  const direction = new THREE.Vector3().subVectors(end, start).normalize();
 
1577
  this.obstacles = [];
1578
  }
1579
 
1580
+ const BUILDING_COUNT = 70; // λ°”μœ„ λŒ€μ‹  건물둜 λ³€κ²½
1581
  const buildingModels = [
1582
  'models/house1.glb',
1583
  'models/house2.glb',
 
2373
  }
2374
 
2375
  animate() {
2376
+ if (this.isGameOver) {
2377
+ if (this.animationFrameId) {
2378
+ cancelAnimationFrame(this.animationFrameId);
2379
+ }
2380
+ return;
2381
+ }
2382
 
2383
+ this.animationFrameId = requestAnimationFrame(() => this.animate());
2384
+ // κ²Œμž„μ΄ μ‹œμž‘λ˜μ§€ μ•Šμ•˜μœΌλ©΄ λ Œλ”λ§λ§Œ μˆ˜ν–‰
2385
+ if (!this.isStarted) {
2386
+ this.renderer.render(this.scene, this.camera);
2387
+ return;
2388
+ }
 
2389
 
2390
+ const currentTime = performance.now();
2391
+ const deltaTime = (currentTime - this.lastTime) / 1000;
2392
+ this.lastTime = currentTime;
2393
 
2394
+ if (!this.isLoading) {
2395
+ this.handleMovement();
2396
+ this.tank.update(this.mouse.x, this.mouse.y, this.scene);
2397
+
2398
+ const tankPosition = this.tank.getPosition();
2399
+ this.enemies.forEach(enemy => {
2400
+ enemy.update(tankPosition);
2401
+
2402
+ if (enemy.isLoaded && enemy.mesh.position.distanceTo(tankPosition) < ENEMY_CONFIG.ATTACK_RANGE) {
2403
+ enemy.shoot(tankPosition);
2404
+ }
2405
+ });
2406
+ this.updateEnemyLabels(); // 적 라벨 μ—…λ°μ΄νŠΈ μΆ”κ°€
2407
+ this.updateParticles();
2408
+ this.checkCollisions();
2409
+ this.updateUI();
2410
+ this.updateRadar(); // λ ˆμ΄λ” μ—…λ°μ΄νŠΈ μΆ”κ°€
2411
+ // ν¬λ‘œμŠ€ν—€μ–΄ μ—…λ°μ΄νŠΈ μΆ”κ°€
2412
+ this.updateCrosshair();
2413
+ }
2414
+
2415
+ this.renderer.render(this.scene, this.camera);
2416
+ }
 
 
 
 
2417
  }
2418
 
2419
  // Start game