Spaces:
Running
Running
cutechicken
commited on
Update game.js
Browse files
game.js
CHANGED
@@ -547,137 +547,158 @@ class Game {
|
|
547 |
this.initialize();
|
548 |
}
|
549 |
|
550 |
-
|
551 |
-
|
552 |
// μκ° ν¨κ³Ό μ κ±°
|
553 |
this.scene.fog = null;
|
554 |
this.scene.background = new THREE.Color(0x87CEEB);
|
555 |
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
-
|
619 |
-
|
620 |
-
|
621 |
-
|
622 |
-
|
623 |
-
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
681 |
}
|
682 |
|
683 |
// λ μ΄λ μ
λ°μ΄νΈ λ©μλ μΆκ°
|
|
|
547 |
this.initialize();
|
548 |
}
|
549 |
|
550 |
+
async initialize() {
|
551 |
+
try {
|
552 |
// μκ° ν¨κ³Ό μ κ±°
|
553 |
this.scene.fog = null;
|
554 |
this.scene.background = new THREE.Color(0x87CEEB);
|
555 |
|
556 |
+
// μ£Όλ³κ΄ μ€μ - λ λ°κ²
|
557 |
+
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
558 |
+
this.scene.add(ambientLight);
|
559 |
+
|
560 |
+
// νμκ΄ μ€μ
|
561 |
+
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
562 |
+
directionalLight.position.set(100, 100, 50);
|
563 |
+
directionalLight.castShadow = true;
|
564 |
+
directionalLight.shadow.mapSize.width = 1024;
|
565 |
+
directionalLight.shadow.mapSize.height = 1024;
|
566 |
+
this.scene.add(directionalLight);
|
567 |
+
|
568 |
+
// μ§ν μμ± μμ
|
569 |
+
const groundGeometry = new THREE.PlaneGeometry(MAP_SIZE, MAP_SIZE, 100, 100);
|
570 |
+
const groundMaterial = new THREE.MeshStandardMaterial({
|
571 |
+
color: 0xD2B48C,
|
572 |
+
roughness: 0.8,
|
573 |
+
metalness: 0.2,
|
574 |
+
wireframe: false
|
575 |
+
});
|
576 |
+
|
577 |
+
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
|
578 |
+
ground.rotation.x = -Math.PI / 2;
|
579 |
+
ground.receiveShadow = true;
|
580 |
+
|
581 |
+
// μ§ν λμ΄ μ€μ
|
582 |
+
const vertices = ground.geometry.attributes.position.array;
|
583 |
+
const heightScale = 15;
|
584 |
+
const baseFrequency = 0.008;
|
585 |
+
|
586 |
+
// νμ§ μμ μ μ
|
587 |
+
const flatlandRadius = MAP_SIZE * 0.3; // νμ§ μμμ λ°κ²½
|
588 |
+
const transitionZone = MAP_SIZE * 0.1; // νμ§μ μΈλ μ¬μ΄μ μ ν ꡬμ
|
589 |
+
|
590 |
+
for (let i = 0; i < vertices.length; i += 3) {
|
591 |
+
const x = vertices[i];
|
592 |
+
const y = vertices[i + 1];
|
593 |
+
|
594 |
+
// μ€μ¬μ μΌλ‘λΆν°μ 거리 κ³μ°
|
595 |
+
const distanceFromCenter = Math.sqrt(x * x + y * y);
|
596 |
+
|
597 |
+
// νμ§ μμμ΄λ©΄ λμ΄λ₯Ό 0μΌλ‘ μ€μ
|
598 |
+
if (distanceFromCenter < flatlandRadius) {
|
599 |
+
vertices[i + 2] = 0;
|
600 |
+
}
|
601 |
+
// μ ν ꡬμμ΄λ©΄ λΆλλ½κ² λμ΄ μ¦κ°
|
602 |
+
else if (distanceFromCenter < flatlandRadius + transitionZone) {
|
603 |
+
const transitionFactor = (distanceFromCenter - flatlandRadius) / transitionZone;
|
604 |
+
let height = 0;
|
605 |
+
|
606 |
+
// μΈλ λμ΄ κ³μ°
|
607 |
+
height += Math.sin(x * baseFrequency) * Math.cos(y * baseFrequency) * heightScale;
|
608 |
+
height += Math.sin(x * baseFrequency * 2) * Math.cos(y * baseFrequency * 2) * (heightScale * 0.5);
|
609 |
+
height += Math.sin(x * baseFrequency * 4) * Math.cos(y * baseFrequency * 4) * (heightScale * 0.25);
|
610 |
+
|
611 |
+
vertices[i + 2] = height * transitionFactor;
|
612 |
+
}
|
613 |
+
// μΈλ μμ
|
614 |
+
else {
|
615 |
+
let height = 0;
|
616 |
+
height += Math.sin(x * baseFrequency) * Math.cos(y * baseFrequency) * heightScale;
|
617 |
+
height += Math.sin(x * baseFrequency * 2) * Math.cos(y * baseFrequency * 2) * (heightScale * 0.5);
|
618 |
+
height += Math.sin(x * baseFrequency * 4) * Math.cos(y * baseFrequency * 4) * (heightScale * 0.25);
|
619 |
+
vertices[i + 2] = height;
|
620 |
+
}
|
621 |
+
}
|
622 |
+
|
623 |
+
ground.geometry.attributes.position.needsUpdate = true;
|
624 |
+
ground.geometry.computeVertexNormals();
|
625 |
+
this.ground = ground;
|
626 |
+
this.scene.add(ground);
|
627 |
+
|
628 |
+
// λ±κ³ μ ν¨κ³Ό (μΈλ μμμλ§ μ μ©)
|
629 |
+
const contourMaterial = new THREE.LineBasicMaterial({
|
630 |
+
color: 0x000000,
|
631 |
+
opacity: 0.15,
|
632 |
+
transparent: true
|
633 |
+
});
|
634 |
+
|
635 |
+
const contourLines = new THREE.LineSegments(
|
636 |
+
new THREE.EdgesGeometry(groundGeometry),
|
637 |
+
contourMaterial
|
638 |
+
);
|
639 |
+
contourLines.rotation.x = -Math.PI / 2;
|
640 |
+
contourLines.position.y = 0.1;
|
641 |
+
this.scene.add(contourLines);
|
642 |
+
|
643 |
+
// 격μ ν¨κ³Ό (νμ§ μμμλ§ μ μ©)
|
644 |
+
const gridHelper = new THREE.GridHelper(flatlandRadius * 2, 50, 0x000000, 0x000000);
|
645 |
+
gridHelper.material.opacity = 0.1;
|
646 |
+
gridHelper.material.transparent = true;
|
647 |
+
gridHelper.position.y = 0.1;
|
648 |
+
this.scene.add(gridHelper);
|
649 |
+
|
650 |
+
// μ¬λ§ μ₯μ μΆκ°
|
651 |
+
await this.addDesertDecorations();
|
652 |
+
|
653 |
+
// ν±ν¬ μ΄κΈ°ν
|
654 |
+
await this.tank.initialize(this.scene, this.loader);
|
655 |
+
if (!this.tank.isLoaded) {
|
656 |
+
throw new Error('Tank loading failed');
|
657 |
+
}
|
658 |
+
|
659 |
+
// μ€ν° μμΉ κ²μ¦ λ° μ¬μμ λ‘μ§ μΆκ°
|
660 |
+
const spawnPos = this.findValidSpawnPosition();
|
661 |
+
const heightAtSpawn = this.getHeightAtPosition(spawnPos.x, spawnPos.z);
|
662 |
+
const slopeCheckPoints = [
|
663 |
+
{ x: spawnPos.x + 2, z: spawnPos.z },
|
664 |
+
{ x: spawnPos.x - 2, z: spawnPos.z },
|
665 |
+
{ x: spawnPos.x, z: spawnPos.z + 2 },
|
666 |
+
{ x: spawnPos.x, z: spawnPos.z - 2 }
|
667 |
+
];
|
668 |
+
|
669 |
+
const slopes = slopeCheckPoints.map(point => {
|
670 |
+
const pointHeight = this.getHeightAtPosition(point.x, point.z);
|
671 |
+
return Math.abs(pointHeight - heightAtSpawn) / 2;
|
672 |
+
});
|
673 |
+
|
674 |
+
const maxSlope = Math.max(...slopes);
|
675 |
+
if (maxSlope > 0.3) { // κ²½μ¬κ° λ무 κ°νλ₯΄λ©΄
|
676 |
+
location.reload(); // κ²μ μλ μ¬μμ
|
677 |
+
return;
|
678 |
+
}
|
679 |
+
|
680 |
+
// μΉ΄λ©λΌ μ΄κΈ° μμΉ μ€μ
|
681 |
+
const tankPosition = this.tank.getPosition();
|
682 |
+
this.camera.position.set(
|
683 |
+
tankPosition.x,
|
684 |
+
tankPosition.y + 15,
|
685 |
+
tankPosition.z - 30
|
686 |
+
);
|
687 |
+
this.camera.lookAt(tankPosition);
|
688 |
+
|
689 |
+
// λ‘λ© μλ£
|
690 |
+
this.isLoading = false;
|
691 |
+
document.getElementById('loading').style.display = 'none';
|
692 |
+
|
693 |
+
// κ²μ μμ
|
694 |
+
this.animate();
|
695 |
+
this.spawnEnemies();
|
696 |
+
this.startGameTimer();
|
697 |
+
|
698 |
+
} catch (error) {
|
699 |
+
console.error('Game initialization error:', error);
|
700 |
+
this.handleLoadingError();
|
701 |
+
}
|
702 |
}
|
703 |
|
704 |
// λ μ΄λ μ
λ°μ΄νΈ λ©μλ μΆκ°
|