Spaces:
Running
Running
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];
|