Spaces:
Running
Running
cutechicken
commited on
Commit
β’
e4939a8
1
Parent(s):
e43a395
Update game.js
Browse files
game.js
CHANGED
@@ -744,6 +744,8 @@ class Game {
|
|
744 |
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
745 |
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
746 |
this.renderer.shadowMap.enabled = true;
|
|
|
|
|
747 |
document.getElementById('gameContainer').appendChild(this.renderer.domElement);
|
748 |
|
749 |
|
@@ -781,163 +783,188 @@ class Game {
|
|
781 |
}
|
782 |
|
783 |
async initialize() {
|
784 |
-
|
785 |
-
|
786 |
const startSounds = ['sounds/start1.ogg', 'sounds/start2.ogg', 'sounds/start3.ogg'];
|
787 |
const randomStartSound = startSounds[Math.floor(Math.random() * startSounds.length)];
|
788 |
const startAudio = new Audio(randomStartSound);
|
789 |
startAudio.volume = 0.5;
|
790 |
startAudio.play();
|
791 |
-
|
792 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
793 |
this.scene.background = new THREE.Color(0x87CEEB);
|
794 |
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
941 |
}
|
942 |
|
943 |
// λ μ΄λ μ
λ°μ΄νΈ λ©μλ μΆκ°
|
|
|
744 |
this.renderer = new THREE.WebGLRenderer({ antialias: true });
|
745 |
this.renderer.setSize(window.innerWidth, window.innerHeight);
|
746 |
this.renderer.shadowMap.enabled = true;
|
747 |
+
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; // λΆλλ¬μ΄ κ·Έλ¦Όμ
|
748 |
+
this.renderer.outputEncoding = THREE.sRGBEncoding; // λ μ νν μμ νν
|
749 |
document.getElementById('gameContainer').appendChild(this.renderer.domElement);
|
750 |
|
751 |
|
|
|
783 |
}
|
784 |
|
785 |
async initialize() {
|
786 |
+
try {
|
787 |
+
// μμ μ¬μ΄λ μ¬μ
|
788 |
const startSounds = ['sounds/start1.ogg', 'sounds/start2.ogg', 'sounds/start3.ogg'];
|
789 |
const randomStartSound = startSounds[Math.floor(Math.random() * startSounds.length)];
|
790 |
const startAudio = new Audio(randomStartSound);
|
791 |
startAudio.volume = 0.5;
|
792 |
startAudio.play();
|
793 |
+
|
794 |
+
// λ λλ¬ μ€μ κ°μ
|
795 |
+
this.renderer.shadowMap.enabled = true;
|
796 |
+
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
|
797 |
+
this.renderer.outputEncoding = THREE.sRGBEncoding;
|
798 |
+
|
799 |
+
// μκ° ν¨κ³Ό
|
800 |
+
this.scene.fog = new THREE.FogExp2(0x87CEEB, 0.0008);
|
801 |
this.scene.background = new THREE.Color(0x87CEEB);
|
802 |
|
803 |
+
// μ£Όλ³κ΄ μ€μ
|
804 |
+
const ambientLight = new THREE.AmbientLight(0xffffff, 0.4);
|
805 |
+
this.scene.add(ambientLight);
|
806 |
+
|
807 |
+
// λ©μΈ νμκ΄ μ€μ
|
808 |
+
const mainLight = new THREE.DirectionalLight(0xffffff, 1.0);
|
809 |
+
mainLight.position.set(100, 100, 50);
|
810 |
+
mainLight.castShadow = true;
|
811 |
+
|
812 |
+
// κ·Έλ¦Όμ νμ§ ν₯μ
|
813 |
+
mainLight.shadow.mapSize.width = 2048;
|
814 |
+
mainLight.shadow.mapSize.height = 2048;
|
815 |
+
mainLight.shadow.camera.near = 0.5;
|
816 |
+
mainLight.shadow.camera.far = 500;
|
817 |
+
mainLight.shadow.camera.left = -100;
|
818 |
+
mainLight.shadow.camera.right = 100;
|
819 |
+
mainLight.shadow.camera.top = 100;
|
820 |
+
mainLight.shadow.camera.bottom = -100;
|
821 |
+
mainLight.shadow.bias = -0.001;
|
822 |
+
mainLight.shadow.radius = 2;
|
823 |
+
|
824 |
+
this.scene.add(mainLight);
|
825 |
+
|
826 |
+
// 보쑰 νμκ΄ μΆκ°
|
827 |
+
const secondaryLight = new THREE.DirectionalLight(0xffffff, 0.3);
|
828 |
+
secondaryLight.position.set(-50, 50, -50);
|
829 |
+
this.scene.add(secondaryLight);
|
830 |
+
|
831 |
+
// νκ²½κ΄ μΆκ°
|
832 |
+
const hemisphereLight = new THREE.HemisphereLight(
|
833 |
+
0x87CEEB, // νλμ
|
834 |
+
0xFFE87C, // λ°λ»ν λ
Έλμ
|
835 |
+
0.3
|
836 |
+
);
|
837 |
+
this.scene.add(hemisphereLight);
|
838 |
+
|
839 |
+
// μ§ν μμ± μμ
|
840 |
+
const groundGeometry = new THREE.PlaneGeometry(MAP_SIZE, MAP_SIZE, 100, 100);
|
841 |
+
const groundMaterial = new THREE.MeshStandardMaterial({
|
842 |
+
color: 0xD2B48C,
|
843 |
+
roughness: 0.8,
|
844 |
+
metalness: 0.2,
|
845 |
+
envMapIntensity: 1.0
|
846 |
+
});
|
847 |
+
|
848 |
+
const ground = new THREE.Mesh(groundGeometry, groundMaterial);
|
849 |
+
ground.rotation.x = -Math.PI / 2;
|
850 |
+
ground.receiveShadow = true;
|
851 |
+
|
852 |
+
// μ§ν λμ΄ μ€μ
|
853 |
+
const vertices = ground.geometry.attributes.position.array;
|
854 |
+
const heightScale = 15;
|
855 |
+
const baseFrequency = 0.008;
|
856 |
+
|
857 |
+
// νμ§ μμ μ μ
|
858 |
+
const flatlandRadius = MAP_SIZE * 0.3;
|
859 |
+
const transitionZone = MAP_SIZE * 0.1;
|
860 |
+
|
861 |
+
for (let i = 0; i < vertices.length; i += 3) {
|
862 |
+
const x = vertices[i];
|
863 |
+
const y = vertices[i + 1];
|
864 |
+
|
865 |
+
const distanceFromCenter = Math.sqrt(x * x + y * y);
|
866 |
+
|
867 |
+
if (distanceFromCenter < flatlandRadius) {
|
868 |
+
vertices[i + 2] = 0;
|
869 |
+
}
|
870 |
+
else if (distanceFromCenter < flatlandRadius + transitionZone) {
|
871 |
+
const transitionFactor = (distanceFromCenter - flatlandRadius) / transitionZone;
|
872 |
+
let height = 0;
|
873 |
+
|
874 |
+
height += Math.sin(x * baseFrequency) * Math.cos(y * baseFrequency) * heightScale;
|
875 |
+
height += Math.sin(x * baseFrequency * 2) * Math.cos(y * baseFrequency * 2) * (heightScale * 0.5);
|
876 |
+
height += Math.sin(x * baseFrequency * 4) * Math.cos(y * baseFrequency * 4) * (heightScale * 0.25);
|
877 |
+
|
878 |
+
vertices[i + 2] = height * transitionFactor;
|
879 |
+
}
|
880 |
+
else {
|
881 |
+
let height = 0;
|
882 |
+
height += Math.sin(x * baseFrequency) * Math.cos(y * baseFrequency) * heightScale;
|
883 |
+
height += Math.sin(x * baseFrequency * 2) * Math.cos(y * baseFrequency * 2) * (heightScale * 0.5);
|
884 |
+
height += Math.sin(x * baseFrequency * 4) * Math.cos(y * baseFrequency * 4) * (heightScale * 0.25);
|
885 |
+
vertices[i + 2] = height;
|
886 |
+
}
|
887 |
+
}
|
888 |
+
|
889 |
+
ground.geometry.attributes.position.needsUpdate = true;
|
890 |
+
ground.geometry.computeVertexNormals();
|
891 |
+
this.ground = ground;
|
892 |
+
this.scene.add(ground);
|
893 |
+
|
894 |
+
// λ±κ³ μ ν¨κ³Ό
|
895 |
+
const contourMaterial = new THREE.LineBasicMaterial({
|
896 |
+
color: 0x000000,
|
897 |
+
opacity: 0.15,
|
898 |
+
transparent: true
|
899 |
+
});
|
900 |
+
|
901 |
+
const contourLines = new THREE.LineSegments(
|
902 |
+
new THREE.EdgesGeometry(groundGeometry),
|
903 |
+
contourMaterial
|
904 |
+
);
|
905 |
+
contourLines.rotation.x = -Math.PI / 2;
|
906 |
+
contourLines.position.y = 0.1;
|
907 |
+
this.scene.add(contourLines);
|
908 |
+
|
909 |
+
// 격μ ν¨κ³Ό
|
910 |
+
const gridHelper = new THREE.GridHelper(flatlandRadius * 2, 50, 0x000000, 0x000000);
|
911 |
+
gridHelper.material.opacity = 0.1;
|
912 |
+
gridHelper.material.transparent = true;
|
913 |
+
gridHelper.position.y = 0.1;
|
914 |
+
this.scene.add(gridHelper);
|
915 |
+
|
916 |
+
// μ¬λ§ μ₯μ μΆκ°
|
917 |
+
await this.addDesertDecorations();
|
918 |
+
|
919 |
+
// ν±ν¬ μ΄κΈ°ν
|
920 |
+
await this.tank.initialize(this.scene, this.loader);
|
921 |
+
if (!this.tank.isLoaded) {
|
922 |
+
throw new Error('Tank loading failed');
|
923 |
+
}
|
924 |
+
|
925 |
+
// μ€ν° μμΉ κ²μ¦ λ° μ¬μμ λ‘μ§
|
926 |
+
const spawnPos = this.findValidSpawnPosition();
|
927 |
+
const heightAtSpawn = this.getHeightAtPosition(spawnPos.x, spawnPos.z);
|
928 |
+
const slopeCheckPoints = [
|
929 |
+
{ x: spawnPos.x + 2, z: spawnPos.z },
|
930 |
+
{ x: spawnPos.x - 2, z: spawnPos.z },
|
931 |
+
{ x: spawnPos.x, z: spawnPos.z + 2 },
|
932 |
+
{ x: spawnPos.x, z: spawnPos.z - 2 }
|
933 |
+
];
|
934 |
+
|
935 |
+
const slopes = slopeCheckPoints.map(point => {
|
936 |
+
const pointHeight = this.getHeightAtPosition(point.x, point.z);
|
937 |
+
return Math.abs(pointHeight - heightAtSpawn) / 2;
|
938 |
+
});
|
939 |
+
|
940 |
+
const maxSlope = Math.max(...slopes);
|
941 |
+
if (maxSlope > 0.3) {
|
942 |
+
location.reload();
|
943 |
+
return;
|
944 |
+
}
|
945 |
+
|
946 |
+
// μΉ΄λ©λΌ μ΄κΈ° μμΉ μ€μ
|
947 |
+
const tankPosition = this.tank.getPosition();
|
948 |
+
this.camera.position.set(
|
949 |
+
tankPosition.x,
|
950 |
+
tankPosition.y + 15,
|
951 |
+
tankPosition.z - 30
|
952 |
+
);
|
953 |
+
this.camera.lookAt(tankPosition);
|
954 |
+
|
955 |
+
// λ‘λ© μλ£
|
956 |
+
this.isLoading = false;
|
957 |
+
document.getElementById('loading').style.display = 'none';
|
958 |
+
|
959 |
+
// κ²μ μμ
|
960 |
+
this.animate();
|
961 |
+
this.spawnEnemies();
|
962 |
+
this.startGameTimer();
|
963 |
+
|
964 |
+
} catch (error) {
|
965 |
+
console.error('Game initialization error:', error);
|
966 |
+
this.handleLoadingError();
|
967 |
+
}
|
968 |
}
|
969 |
|
970 |
// λ μ΄λ μ
λ°μ΄νΈ λ©μλ μΆκ°
|