cutechicken commited on
Commit
022d403
Β·
verified Β·
1 Parent(s): 3e7d780

Update game.js

Browse files
Files changed (1) hide show
  1. game.js +148 -127
game.js CHANGED
@@ -547,137 +547,158 @@ class Game {
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 tankPosition = this.tank.getPosition();
661
- this.camera.position.set(
662
- tankPosition.x,
663
- tankPosition.y + 15,
664
- tankPosition.z - 30
665
- );
666
- this.camera.lookAt(tankPosition);
667
-
668
- // λ‘œλ”© μ™„λ£Œ
669
- this.isLoading = false;
670
- document.getElementById('loading').style.display = 'none';
671
-
672
- // κ²Œμž„ μ‹œμž‘
673
- this.animate();
674
- this.spawnEnemies();
675
- this.startGameTimer();
676
-
677
- } catch (error) {
678
- console.error('Game initialization error:', error);
679
- this.handleLoadingError();
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
  // λ ˆμ΄λ” μ—…λ°μ΄νŠΈ λ©”μ„œλ“œ μΆ”κ°€