Spaces:
Running
Running
cutechicken
commited on
Commit
โข
02a151f
1
Parent(s):
7bb432f
Update game.js
Browse files
game.js
CHANGED
@@ -614,62 +614,152 @@ class Enemy {
|
|
614 |
const distanceToPlayer = this.mesh.position.distanceTo(playerPosition);
|
615 |
const minDistance = 50;
|
616 |
|
617 |
-
|
|
|
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(
|
|
|
|
|
|
|
625 |
newPosition.y = heightAtNewPos + TANK_HEIGHT;
|
626 |
|
627 |
-
//
|
628 |
-
const
|
629 |
-
|
630 |
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
const
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
654 |
|
655 |
-
|
656 |
-
const
|
|
|
|
|
|
|
|
|
657 |
|
658 |
-
|
659 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
660 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
661 |
}
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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];
|