Spaces:
Running
Running
cutechicken
commited on
Commit
โข
23275ba
1
Parent(s):
5ca5ee0
Update game.js
Browse files
game.js
CHANGED
@@ -732,119 +732,111 @@ class Enemy {
|
|
732 |
|
733 |
// ๋ฉ์ธ ์
๋ฐ์ดํธ ํจ์
|
734 |
update(playerPosition) {
|
735 |
-
|
736 |
|
737 |
-
|
738 |
-
|
739 |
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
// ๊ฒฝ๋ก ์
๋ฐ์ดํธ ์ฃผ๊ธฐ ์ฒดํฌ
|
746 |
-
if (currentTime - this.lastPathUpdateTime > this.pathUpdateInterval) {
|
747 |
-
if (!hasLineOfSight) {
|
748 |
-
this.alternativePath = this.findAlternativePath(playerPosition);
|
749 |
-
}
|
750 |
-
this.lastPathUpdateTime = currentTime;
|
751 |
-
}
|
752 |
-
if (!hasLineOfSight) {
|
753 |
-
if (this.alternativePath) {
|
754 |
-
const pathDirection = new THREE.Vector3()
|
755 |
-
.subVectors(this.alternativePath, this.mesh.position)
|
756 |
-
.normalize();
|
757 |
-
this.mesh.position.add(pathDirection.multiplyScalar(this.moveSpeed));
|
758 |
-
|
759 |
-
const targetRotation = Math.atan2(pathDirection.x, pathDirection.z);
|
760 |
-
this.mesh.rotation.y = this.smoothRotation(this.mesh.rotation.y, targetRotation, 0.1);
|
761 |
-
}
|
762 |
-
} else {
|
763 |
-
this.alternativePath = null;
|
764 |
-
|
765 |
-
// ๊ฑฐ๋ฆฌ์ ๋ฐ๋ฅธ ํ๋ ๊ฒฐ์
|
766 |
-
if (distanceToPlayer > ENEMY_CONFIG.ATTACK_RANGE * 0.7) {
|
767 |
-
const moveDirection = new THREE.Vector3()
|
768 |
-
.subVectors(playerPosition, this.mesh.position)
|
769 |
-
.normalize();
|
770 |
-
this.mesh.position.add(moveDirection.multiplyScalar(this.moveSpeed));
|
771 |
-
} else if (distanceToPlayer < ENEMY_CONFIG.ATTACK_RANGE * 0.3) {
|
772 |
-
const retreatDirection = new THREE.Vector3()
|
773 |
-
.subVectors(this.mesh.position, playerPosition)
|
774 |
-
.normalize();
|
775 |
-
this.mesh.position.add(retreatDirection.multiplyScalar(this.moveSpeed));
|
776 |
-
}
|
777 |
-
|
778 |
-
// ํ๋ ์ด์ด ๋ฐฉํฅ์ผ๋ก ํ์
|
779 |
-
const directionToPlayer = new THREE.Vector3()
|
780 |
-
.subVectors(playerPosition, this.mesh.position)
|
781 |
-
.normalize();
|
782 |
-
const targetRotation = Math.atan2(directionToPlayer.x, directionToPlayer.z);
|
783 |
-
this.mesh.rotation.y = this.smoothRotation(this.mesh.rotation.y, targetRotation, 0.1);
|
784 |
|
785 |
-
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
}
|
|
|
790 |
}
|
791 |
-
}
|
792 |
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
}
|
800 |
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
const avoidMove = this.pathfinding.avoidanceDirection.multiplyScalar(this.moveSpeed);
|
808 |
-
this.mesh.position.add(avoidMove);
|
809 |
-
}
|
810 |
} else {
|
811 |
-
|
812 |
-
|
813 |
-
case 'pursue':
|
814 |
-
this.findPathToTarget(playerPosition);
|
815 |
-
this.moveAlongPath();
|
816 |
-
break;
|
817 |
-
case 'flank':
|
818 |
-
const flankPosition = this.calculateFlankPosition(playerPosition);
|
819 |
-
this.findPathToTarget(flankPosition);
|
820 |
-
this.moveAlongPath();
|
821 |
-
break;
|
822 |
-
case 'retreat':
|
823 |
-
const retreatPosition = this.calculateRetreatPosition(playerPosition);
|
824 |
-
this.findPathToTarget(retreatPosition);
|
825 |
-
this.moveAlongPath();
|
826 |
-
break;
|
827 |
-
}
|
828 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
829 |
|
830 |
-
|
831 |
-
|
832 |
-
if (combatMove.length() > 0) {
|
833 |
-
this.mesh.position.add(combatMove.multiplyScalar(this.moveSpeed));
|
834 |
}
|
|
|
|
|
|
|
835 |
|
836 |
-
//
|
837 |
-
|
838 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
839 |
}
|
840 |
|
841 |
-
//
|
842 |
-
|
|
|
|
|
|
|
|
|
|
|
843 |
|
844 |
-
|
845 |
-
|
|
|
|
|
846 |
}
|
847 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
848 |
if (!this.mesh) return false;
|
849 |
|
850 |
const startPos = this.mesh.position.clone();
|
|
|
732 |
|
733 |
// ๋ฉ์ธ ์
๋ฐ์ดํธ ํจ์
|
734 |
update(playerPosition) {
|
735 |
+
if (!this.mesh || !this.isLoaded) return;
|
736 |
|
737 |
+
// AI ์ํ ์
๋ฐ์ดํธ
|
738 |
+
this.updateAIState(playerPosition);
|
739 |
|
740 |
+
// ์ฅ์ ๋ฌผ ๊ฐ์ง ๋ฐ ์์ผ ์ฒดํฌ
|
741 |
+
const obstacles = this.detectObstacles();
|
742 |
+
const currentTime = Date.now();
|
743 |
+
const hasLineOfSight = this.checkLineOfSight(playerPosition);
|
744 |
+
const distanceToPlayer = this.mesh.position.distanceTo(playerPosition);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
745 |
|
746 |
+
// ๊ฒฝ๋ก ์
๋ฐ์ดํธ ์ฃผ๊ธฐ ์ฒดํฌ
|
747 |
+
if (currentTime - this.lastPathUpdateTime > this.pathUpdateInterval) {
|
748 |
+
if (!hasLineOfSight) {
|
749 |
+
this.alternativePath = this.findAlternativePath(playerPosition);
|
750 |
}
|
751 |
+
this.lastPathUpdateTime = currentTime;
|
752 |
}
|
|
|
753 |
|
754 |
+
// ์ฅ์ ๋ฌผ ํํผ ๋ก์ง
|
755 |
+
if (obstacles.length > 0 && !this.pathfinding.isAvoidingObstacle) {
|
756 |
+
this.pathfinding.isAvoidingObstacle = true;
|
757 |
+
this.pathfinding.avoidanceDirection = this.calculateAvoidanceDirection(obstacles);
|
758 |
+
this.pathfinding.avoidanceTime = 0;
|
759 |
+
}
|
|
|
760 |
|
761 |
+
// ์ด๋ ๋ก์ง ์คํ
|
762 |
+
if (this.pathfinding.isAvoidingObstacle) {
|
763 |
+
// ํํผ ๋์
|
764 |
+
this.pathfinding.avoidanceTime += 16;
|
765 |
+
if (this.pathfinding.avoidanceTime >= this.pathfinding.maxAvoidanceTime) {
|
766 |
+
this.pathfinding.isAvoidingObstacle = false;
|
|
|
|
|
|
|
767 |
} else {
|
768 |
+
const avoidMove = this.pathfinding.avoidanceDirection.multiplyScalar(this.moveSpeed);
|
769 |
+
this.mesh.position.add(avoidMove);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
770 |
}
|
771 |
+
} else if (!hasLineOfSight) {
|
772 |
+
// ์์ผ๊ฐ ์์ ๋์ ์ด๋
|
773 |
+
if (this.alternativePath) {
|
774 |
+
const pathDirection = new THREE.Vector3()
|
775 |
+
.subVectors(this.alternativePath, this.mesh.position)
|
776 |
+
.normalize();
|
777 |
+
this.mesh.position.add(pathDirection.multiplyScalar(this.moveSpeed));
|
778 |
|
779 |
+
const targetRotation = Math.atan2(pathDirection.x, pathDirection.z);
|
780 |
+
this.mesh.rotation.y = this.smoothRotation(this.mesh.rotation.y, targetRotation, 0.1);
|
|
|
|
|
781 |
}
|
782 |
+
} else {
|
783 |
+
// ์์ผ๊ฐ ์์ ๋์ ์ด๋
|
784 |
+
this.alternativePath = null;
|
785 |
|
786 |
+
// AI ์ํ์ ๋ฐ๋ฅธ ์ด๋
|
787 |
+
switch (this.aiState.mode) {
|
788 |
+
case 'pursue':
|
789 |
+
if (distanceToPlayer > ENEMY_CONFIG.ATTACK_RANGE * 0.7) {
|
790 |
+
const moveDirection = new THREE.Vector3()
|
791 |
+
.subVectors(playerPosition, this.mesh.position)
|
792 |
+
.normalize();
|
793 |
+
this.mesh.position.add(moveDirection.multiplyScalar(this.moveSpeed));
|
794 |
+
}
|
795 |
+
break;
|
796 |
+
|
797 |
+
case 'flank':
|
798 |
+
const flankPosition = this.calculateFlankPosition(playerPosition);
|
799 |
+
this.findPathToTarget(flankPosition);
|
800 |
+
this.moveAlongPath();
|
801 |
+
break;
|
802 |
+
|
803 |
+
case 'retreat':
|
804 |
+
if (distanceToPlayer < ENEMY_CONFIG.ATTACK_RANGE * 0.3) {
|
805 |
+
const retreatDirection = new THREE.Vector3()
|
806 |
+
.subVectors(this.mesh.position, playerPosition)
|
807 |
+
.normalize();
|
808 |
+
this.mesh.position.add(retreatDirection.multiplyScalar(this.moveSpeed));
|
809 |
+
}
|
810 |
+
break;
|
811 |
}
|
812 |
|
813 |
+
// ํ๋ ์ด์ด ๋ฐฉํฅ์ผ๋ก ํ์
|
814 |
+
const directionToPlayer = new THREE.Vector3()
|
815 |
+
.subVectors(playerPosition, this.mesh.position)
|
816 |
+
.normalize();
|
817 |
+
const targetRotation = Math.atan2(directionToPlayer.x, directionToPlayer.z);
|
818 |
+
this.mesh.rotation.y = this.smoothRotation(this.mesh.rotation.y, targetRotation, 0.1);
|
819 |
+
}
|
820 |
|
821 |
+
// ์ ํฌ ๊ฑฐ๋ฆฌ ์กฐ์
|
822 |
+
const combatMove = this.maintainCombatDistance(playerPosition);
|
823 |
+
if (combatMove.length() > 0) {
|
824 |
+
this.mesh.position.add(combatMove.multiplyScalar(this.moveSpeed));
|
825 |
}
|
826 |
+
|
827 |
+
// ๊ณต๊ฒฉ ์ฒ๋ฆฌ
|
828 |
+
if (hasLineOfSight && distanceToPlayer <= ENEMY_CONFIG.ATTACK_RANGE && this.canShoot(playerPosition)) {
|
829 |
+
this.shoot(playerPosition);
|
830 |
+
}
|
831 |
+
|
832 |
+
// ์ด์ ์
๋ฐ์ดํธ
|
833 |
+
this.updateBullets();
|
834 |
+
|
835 |
+
// ํฑํฌ ๊ธฐ์ธ๊ธฐ ์กฐ์
|
836 |
+
this.adjustTankTilt();
|
837 |
+
}
|
838 |
+
|
839 |
+
checkLineOfSight(targetPosition) {
|
840 |
if (!this.mesh) return false;
|
841 |
|
842 |
const startPos = this.mesh.position.clone();
|