cutechicken commited on
Commit
02a151f
โ€ข
1 Parent(s): 7bb432f

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +198 -45
game.js CHANGED
@@ -614,62 +614,152 @@ class Enemy {
614
  const distanceToPlayer = this.mesh.position.distanceTo(playerPosition);
615
  const minDistance = 50;
616
 
617
- this.mesh.lookAt(playerPosition);
 
618
 
619
  if (distanceToPlayer > minDistance) {
620
  const moveVector = direction.multiplyScalar(this.moveSpeed);
621
  const newPosition = this.mesh.position.clone().add(moveVector);
622
 
623
- // ์ƒˆ๋กœ์šด ์œ„์น˜์˜ ์ง€ํ˜• ๋†’์ด ๊ฐ€์ ธ์˜ค๊ธฐ
624
- const heightAtNewPos = window.gameInstance.getHeightAtPosition(newPosition.x, newPosition.z);
 
 
 
625
  newPosition.y = heightAtNewPos + TANK_HEIGHT;
626
 
627
- // ๊ฒฝ์‚ฌ ์ฒดํฌ
628
- const heightDifference = Math.abs(newPosition.y - this.mesh.position.y);
629
- const maxClimbAngle = 0.5;
630
 
631
- if (heightDifference / this.moveSpeed < maxClimbAngle) {
632
- this.mesh.position.copy(newPosition);
633
-
634
- // ์  ํƒฑํฌ ๊ธฐ์šธ๊ธฐ ์กฐ์ •
635
- const forwardVector = new THREE.Vector3(0, 0, 1).applyQuaternion(this.mesh.quaternion);
636
- const rightVector = new THREE.Vector3(1, 0, 0).applyQuaternion(this.mesh.quaternion);
637
-
638
- const frontHeight = window.gameInstance.getHeightAtPosition(
639
- newPosition.x + forwardVector.x,
640
- newPosition.z + forwardVector.z
641
- );
642
- const backHeight = window.gameInstance.getHeightAtPosition(
643
- newPosition.x - forwardVector.x,
644
- newPosition.z - forwardVector.z
645
- );
646
- const rightHeight = window.gameInstance.getHeightAtPosition(
647
- newPosition.x + rightVector.x,
648
- newPosition.z + rightVector.z
649
- );
650
- const leftHeight = window.gameInstance.getHeightAtPosition(
651
- newPosition.x - rightVector.x,
652
- newPosition.z - rightVector.z
653
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
654
 
655
- const pitch = Math.atan2(frontHeight - backHeight, 2);
656
- const roll = Math.atan2(rightHeight - leftHeight, 2);
 
 
 
 
657
 
658
- this.mesh.rotation.x = pitch;
659
- this.mesh.rotation.z = roll;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
660
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
661
  }
662
-
663
-
664
- // ์ด์•Œ ์—…๋ฐ์ดํŠธ ๋ถ€๋ถ„
665
- for (let i = this.bullets.length - 1; i >= 0; i--) {
666
- const bullet = this.bullets[i];
667
- bullet.position.add(bullet.velocity);
668
-
669
- if (Math.abs(bullet.position.x) > MAP_SIZE ||
670
- Math.abs(bullet.position.z) > MAP_SIZE) {
671
- this.scene.remove(bullet);
672
- this.bullets.splice(i, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  }
674
  }
675
  }
@@ -1482,14 +1572,33 @@ class Game {
1482
  const tankPosition = this.tank.getPosition();
1483
  const tankBoundingBox = new THREE.Box3().setFromObject(this.tank.body);
1484
 
1485
- // ํƒฑํฌ์™€ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ์ฒดํฌ
1486
  this.obstacles.forEach(obstacle => {
1487
  const obstacleBoundingBox = new THREE.Box3().setFromObject(obstacle);
1488
  if (tankBoundingBox.intersectsBox(obstacleBoundingBox)) {
1489
  // ์ถฉ๋Œ ์‹œ ์ด์ „ ์œ„์น˜๋กœ ๋˜๋Œ๋ฆฌ๊ธฐ
1490
  this.tank.body.position.copy(this.previousTankPosition);
 
 
 
 
 
1491
  }
1492
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1493
 
1494
  // ์  ์ด์•Œ๊ณผ ํ”Œ๋ ˆ์ด์–ด ํƒฑํฌ ์ถฉ๋Œ ์ฒดํฌ
1495
  this.enemies.forEach(enemy => {
@@ -1516,6 +1625,50 @@ class Game {
1516
  });
1517
  });
1518
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1519
  // ํ”Œ๋ ˆ์ด์–ด ์ด์•Œ๊ณผ ์  ์ถฉ๋Œ ์ฒดํฌ
1520
  for (let i = this.tank.bullets.length - 1; i >= 0; i--) {
1521
  const bullet = this.tank.bullets[i];
 
614
  const distanceToPlayer = this.mesh.position.distanceTo(playerPosition);
615
  const minDistance = 50;
616
 
617
+ // ์ด์ „ ์œ„์น˜ ์ €์žฅ
618
+ const previousPosition = this.mesh.position.clone();
619
 
620
  if (distanceToPlayer > minDistance) {
621
  const moveVector = direction.multiplyScalar(this.moveSpeed);
622
  const newPosition = this.mesh.position.clone().add(moveVector);
623
 
624
+ // ์ง€ํ˜• ๋†’์ด ๊ฐ€์ ธ์˜ค๊ธฐ
625
+ const heightAtNewPos = window.gameInstance.getHeightAtPosition(
626
+ newPosition.x,
627
+ newPosition.z
628
+ );
629
  newPosition.y = heightAtNewPos + TANK_HEIGHT;
630
 
631
+ // ์ž„์‹œ๋กœ ์œ„์น˜ ์ด๋™ํ•˜์—ฌ ์ถฉ๋Œ ์ฒดํฌ
632
+ const originalPosition = this.mesh.position.clone();
633
+ this.mesh.position.copy(newPosition);
634
 
635
+ // ์žฅ์• ๋ฌผ๊ณผ ์ถฉ๋Œ ์ฒดํฌ
636
+ const enemyBox = new THREE.Box3().setFromObject(this.mesh);
637
+ let hasCollision = false;
638
+
639
+ // ๋ชจ๋“  ์žฅ์• ๋ฌผ์— ๋Œ€ํ•ด ์ถฉ๋Œ ๊ฒ€์‚ฌ
640
+ for (const obstacle of window.gameInstance.obstacles) {
641
+ const obstacleBox = new THREE.Box3().setFromObject(obstacle);
642
+ if (enemyBox.intersectsBox(obstacleBox)) {
643
+ hasCollision = true;
644
+ break;
645
+ }
646
+ }
647
+
648
+ // ๋‹ค๋ฅธ ์  ํƒฑํฌ์™€์˜ ์ถฉ๋Œ ๊ฒ€์‚ฌ
649
+ if (!hasCollision) {
650
+ for (const otherEnemy of window.gameInstance.enemies) {
651
+ if (otherEnemy !== this && otherEnemy.mesh) {
652
+ const otherEnemyBox = new THREE.Box3().setFromObject(otherEnemy.mesh);
653
+ if (enemyBox.intersectsBox(otherEnemyBox)) {
654
+ hasCollision = true;
655
+ break;
656
+ }
657
+ }
658
+ }
659
+ }
660
+
661
+ // ๋งต ๊ฒฝ๊ณ„ ์ฒดํฌ
662
+ const mapBoundary = MAP_SIZE / 2;
663
+ if (Math.abs(newPosition.x) > mapBoundary ||
664
+ Math.abs(newPosition.z) > mapBoundary) {
665
+ hasCollision = true;
666
+ }
667
+
668
+ // ์ถฉ๋Œ์ด ์žˆ์œผ๋ฉด ์ด์ „ ์œ„์น˜๋กœ ๋ณต๊ท€, ์—†์œผ๋ฉด ์ƒˆ ์œ„์น˜ ์œ ์ง€
669
+ if (hasCollision) {
670
+ this.mesh.position.copy(previousPosition);
671
 
672
+ // ์ถฉ๋Œ ์‹œ ์šฐํšŒ ๊ฒฝ๋กœ ์‹œ๋„
673
+ const alternateDirections = [
674
+ new THREE.Vector3(-direction.z, 0, direction.x), // ์™ผ์ชฝ์œผ๋กœ 90๋„
675
+ new THREE.Vector3(direction.z, 0, -direction.x), // ์˜ค๋ฅธ์ชฝ์œผ๋กœ 90๋„
676
+ new THREE.Vector3(-direction.x, 0, -direction.z) // 180๋„ ํšŒ์ „
677
+ ];
678
 
679
+ for (const altDirection of alternateDirections) {
680
+ const altMoveVector = altDirection.multiplyScalar(this.moveSpeed);
681
+ const altNewPosition = previousPosition.clone().add(altMoveVector);
682
+
683
+ this.mesh.position.copy(altNewPosition);
684
+ const altEnemyBox = new THREE.Box3().setFromObject(this.mesh);
685
+
686
+ let altHasCollision = false;
687
+
688
+ // ์ƒˆ๋กœ์šด ๋ฐฉํ–ฅ์— ๋Œ€ํ•œ ์ถฉ๋Œ ๊ฒ€์‚ฌ
689
+ for (const obstacle of window.gameInstance.obstacles) {
690
+ const obstacleBox = new THREE.Box3().setFromObject(obstacle);
691
+ if (altEnemyBox.intersectsBox(obstacleBox)) {
692
+ altHasCollision = true;
693
+ break;
694
+ }
695
+ }
696
+
697
+ if (!altHasCollision) {
698
+ // ์šฐํšŒ ๊ฒฝ๋กœ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋ฉด ๊ทธ ๋ฐฉํ–ฅ์œผ๋กœ ์ด๋™
699
+ break;
700
+ } else {
701
+ // ์šฐํšŒ๋„ ๋ถˆ๊ฐ€๋Šฅํ•˜๋ฉด ์ด์ „ ์œ„์น˜๋กœ ๋ณต๊ท€
702
+ this.mesh.position.copy(previousPosition);
703
+ }
704
+ }
705
  }
706
+
707
+ // ์ง€ํ˜•์— ๋”ฐ๋ฅธ ๊ธฐ์šธ๊ธฐ ์กฐ์ •
708
+ const forwardVector = new THREE.Vector3(0, 0, 1).applyQuaternion(this.mesh.quaternion);
709
+ const rightVector = new THREE.Vector3(1, 0, 0).applyQuaternion(this.mesh.quaternion);
710
+
711
+ const frontHeight = window.gameInstance.getHeightAtPosition(
712
+ this.mesh.position.x + forwardVector.x,
713
+ this.mesh.position.z + forwardVector.z
714
+ );
715
+ const backHeight = window.gameInstance.getHeightAtPosition(
716
+ this.mesh.position.x - forwardVector.x,
717
+ this.mesh.position.z - forwardVector.z
718
+ );
719
+ const rightHeight = window.gameInstance.getHeightAtPosition(
720
+ this.mesh.position.x + rightVector.x,
721
+ this.mesh.position.z + rightVector.z
722
+ );
723
+ const leftHeight = window.gameInstance.getHeightAtPosition(
724
+ this.mesh.position.x - rightVector.x,
725
+ this.mesh.position.z - rightVector.z
726
+ );
727
+
728
+ const pitch = Math.atan2(frontHeight - backHeight, 2);
729
+ const roll = Math.atan2(rightHeight - leftHeight, 2);
730
+
731
+ // ํ˜„์žฌ ํšŒ์ „ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ธฐ์šธ๊ธฐ๋งŒ ์ ์šฉ
732
+ const currentRotation = this.mesh.rotation.y;
733
+ this.mesh.rotation.set(pitch, currentRotation, roll);
734
  }
735
+
736
+ // ํ”Œ๋ ˆ์ด์–ด๋ฅผ ํ–ฅํ•ด ํฌํƒ‘ ํšŒ์ „
737
+ this.mesh.lookAt(playerPosition);
738
+
739
+ // ์ด์•Œ ์—…๋ฐ์ดํŠธ
740
+ if (this.bullets) {
741
+ for (let i = this.bullets.length - 1; i >= 0; i--) {
742
+ const bullet = this.bullets[i];
743
+ bullet.position.add(bullet.velocity);
744
+
745
+ // ์ด์•Œ์ด ๋งต ๋ฐ–์œผ๋กœ ๋‚˜๊ฐ€๊ฑฐ๋‚˜ ์žฅ์• ๋ฌผ๊ณผ ์ถฉ๋Œํ•˜๋ฉด ์ œ๊ฑฐ
746
+ if (Math.abs(bullet.position.x) > MAP_SIZE / 2 ||
747
+ Math.abs(bullet.position.z) > MAP_SIZE / 2) {
748
+ this.scene.remove(bullet);
749
+ this.bullets.splice(i, 1);
750
+ continue;
751
+ }
752
+
753
+ // ์ด์•Œ๊ณผ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ์ฒดํฌ
754
+ const bulletBox = new THREE.Box3().setFromObject(bullet);
755
+ for (const obstacle of window.gameInstance.obstacles) {
756
+ const obstacleBox = new THREE.Box3().setFromObject(obstacle);
757
+ if (bulletBox.intersectsBox(obstacleBox)) {
758
+ this.scene.remove(bullet);
759
+ this.bullets.splice(i, 1);
760
+ break;
761
+ }
762
+ }
763
  }
764
  }
765
  }
 
1572
  const tankPosition = this.tank.getPosition();
1573
  const tankBoundingBox = new THREE.Box3().setFromObject(this.tank.body);
1574
 
1575
+ // ํƒฑํฌ์™€ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ์ฒดํฌ (๊ฐœ์„ )
1576
  this.obstacles.forEach(obstacle => {
1577
  const obstacleBoundingBox = new THREE.Box3().setFromObject(obstacle);
1578
  if (tankBoundingBox.intersectsBox(obstacleBoundingBox)) {
1579
  // ์ถฉ๋Œ ์‹œ ์ด์ „ ์œ„์น˜๋กœ ๋˜๋Œ๋ฆฌ๊ธฐ
1580
  this.tank.body.position.copy(this.previousTankPosition);
1581
+
1582
+ // ์ถฉ๋Œ ์‚ฌ์šด๋“œ ์žฌ์ƒ
1583
+ //const collisionSound = new Audio('sounds/collision.ogg');
1584
+ //collisionSound.volume = 0.3;
1585
+ //collisionSound.play();
1586
  }
1587
  });
1588
+ // ์  ํƒฑํฌ์™€ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ์ฒดํฌ (์ถ”๊ฐ€)
1589
+ this.enemies.forEach(enemy => {
1590
+ if (!enemy.mesh || !enemy.isLoaded) return;
1591
+
1592
+ const enemyBoundingBox = new THREE.Box3().setFromObject(enemy.mesh);
1593
+ const enemyPreviousPosition = enemy.mesh.position.clone();
1594
+
1595
+ this.obstacles.forEach(obstacle => {
1596
+ const obstacleBoundingBox = new THREE.Box3().setFromObject(obstacle);
1597
+ if (enemyBoundingBox.intersectsBox(obstacleBoundingBox)) {
1598
+ enemy.mesh.position.copy(enemyPreviousPosition);
1599
+ }
1600
+ });
1601
+ });
1602
 
1603
  // ์  ์ด์•Œ๊ณผ ํ”Œ๋ ˆ์ด์–ด ํƒฑํฌ ์ถฉ๋Œ ์ฒดํฌ
1604
  this.enemies.forEach(enemy => {
 
1625
  });
1626
  });
1627
 
1628
+ // ํฌํƒ„๊ณผ ์žฅ์• ๋ฌผ ์ถฉ๋Œ ์ฒดํฌ (์ถ”๊ฐ€)
1629
+ // ํ”Œ๋ ˆ์ด์–ด ํฌํƒ„
1630
+ for (let i = this.tank.bullets.length - 1; i >= 0; i--) {
1631
+ const bullet = this.tank.bullets[i];
1632
+ const bulletBox = new THREE.Box3().setFromObject(bullet);
1633
+
1634
+ for (const obstacle of this.obstacles) {
1635
+ const obstacleBox = new THREE.Box3().setFromObject(obstacle);
1636
+ if (bulletBox.intersectsBox(obstacleBox)) {
1637
+ // ํญ๋ฐœ ์ดํŽ™ํŠธ ์ƒ์„ฑ
1638
+ this.tank.createExplosionEffect(this.scene, bullet.position);
1639
+
1640
+ // ํฌํƒ„ ์ œ๊ฑฐ
1641
+ this.scene.remove(bullet);
1642
+ this.tank.bullets.splice(i, 1);
1643
+ break;
1644
+ }
1645
+ }
1646
+ }
1647
+
1648
+ // ์  ํฌํƒ„
1649
+ this.enemies.forEach(enemy => {
1650
+ if (!enemy.bullets) return;
1651
+
1652
+ for (let i = enemy.bullets.length - 1; i >= 0; i--) {
1653
+ const bullet = enemy.bullets[i];
1654
+ const bulletBox = new THREE.Box3().setFromObject(bullet);
1655
+
1656
+ for (const obstacle of this.obstacles) {
1657
+ const obstacleBox = new THREE.Box3().setFromObject(obstacle);
1658
+ if (bulletBox.intersectsBox(obstacleBox)) {
1659
+ // ํญ๋ฐœ ์ดํŽ™ํŠธ ์ƒ์„ฑ
1660
+ this.tank.createExplosionEffect(this.scene, bullet.position);
1661
+
1662
+ // ํฌํƒ„ ์ œ๊ฑฐ
1663
+ this.scene.remove(bullet);
1664
+ enemy.bullets.splice(i, 1);
1665
+ break;
1666
+ }
1667
+ }
1668
+ }
1669
+ });
1670
+
1671
+
1672
  // ํ”Œ๋ ˆ์ด์–ด ์ด์•Œ๊ณผ ์  ์ถฉ๋Œ ์ฒดํฌ
1673
  for (let i = this.tank.bullets.length - 1; i >= 0; i--) {
1674
  const bullet = this.tank.bullets[i];