cutechicken commited on
Commit
b9ec0db
ยท
verified ยท
1 Parent(s): 96fd1d3

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +138 -116
index.html CHANGED
@@ -1,17 +1,4 @@
1
- // ์‹ค์‹œ๊ฐ„ ๊ฐ๋„ ๊ฐ•์ œ ๋ณด์ • (ํ•˜๋“œ ๋ฆฌ๋ฏธํŠธ)
2
- const maxAllowedPitch = Math.PI / 4.5; // 40๋„
3
- const maxAllowedRoll = Math.PI * 0.8; // 144๋„
4
-
5
- // ํ˜„์žฌ ํšŒ์ „๊ฐ์ด ํ•œ๊ณ„๋ฅผ ์ดˆ๊ณผํ•˜๋ฉด ๊ฐ•์ œ๋กœ ๋˜๋Œ๋ฆฌ๊ธฐ
6
- if (Math.abs(this.rotation.x) > maxAllowedPitch) {
7
- this.rotation.x = Math.sign(this.rotation.x) * maxAllowedPitch;
8
- this.targetPitch = this.rotation.x;
9
- }
10
-
11
- if (Math.abs(this.rotation.z) > maxAllowedRoll) {
12
- this.rotation.z = Math.sign(this.rotation.z) * maxAllowedRoll;
13
- this.targetRoll = this.rotation.z;
14
- }<!DOCTYPE html>
15
  <html>
16
  <head>
17
  <meta charset="utf-8">
@@ -100,55 +87,55 @@
100
  }
101
 
102
  #crosshair {
103
- position: fixed;
104
- top: 25%;
105
- left: 50%;
106
- transform: translate(-50%, -50%);
107
- width: 40px;
108
- height: 40px;
109
- border: 2px solid #00ff00;
110
- border-radius: 50%;
111
- z-index: 1001;
112
- pointer-events: none;
113
- transition: all 0.2s ease;
114
- }
115
-
116
- /* ๋ฌผ์ฒด๊ฐ€ ๊ฐ์ง€๋˜์—ˆ์„ ๋•Œ์˜ ์Šคํƒ€์ผ */
117
- #crosshair.target-detected {
118
- border-color: #ff0000;
119
- border-width: 3px;
120
- box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
121
- }
122
-
123
- #crosshair::before,
124
- #crosshair::after {
125
- content: '';
126
- position: absolute;
127
- background: #00ff00;
128
- transition: all 0.2s ease;
129
- }
130
-
131
- #crosshair::before {
132
- top: 50%;
133
- left: -10px;
134
- right: -10px;
135
- height: 2px;
136
- transform: translateY(-50%);
137
- }
138
-
139
- #crosshair::after {
140
- left: 50%;
141
- top: -10px;
142
- bottom: -10px;
143
- width: 2px;
144
- transform: translateX(-50%);
145
- }
146
-
147
- /* ๋ฌผ์ฒด๊ฐ€ ๊ฐ์ง€๋˜์—ˆ์„ ๋•Œ์˜ ํฌ๋กœ์Šค ๋ผ์ธ ์Šคํƒ€์ผ */
148
- #crosshair.target-detected::before,
149
- #crosshair.target-detected::after {
150
- background: #ff0000;
151
- }
152
 
153
  #healthBar {
154
  position: absolute;
@@ -186,7 +173,7 @@
186
 
187
  #gameTitle {
188
  position: absolute;
189
- top: 10px;
190
  left: 50%;
191
  transform: translateX(-50%);
192
  color: #0f0;
@@ -564,15 +551,19 @@
564
  this.lastShootTime = 0;
565
 
566
  // ์นด๋ฉ”๋ผ ์„ค์ •
567
- this.cameraDistance = 300; // ๋” ๋ฉ€๋ฆฌ
568
- this.cameraHeight = 60; // ๋” ๋†’๊ฒŒ
569
- this.cameraLag = 0.06;
570
 
571
  // ๊ฒฝ๊ณ  ์‹œ์Šคํ…œ
572
  this.altitudeWarning = false;
573
  this.stallWarning = false;
574
  this.warningBlinkTimer = 0;
575
  this.warningBlinkState = false;
 
 
 
 
576
  }
577
 
578
  async initialize(scene, loader) {
@@ -645,30 +636,45 @@
645
  }
646
 
647
  updateMouseInput(deltaX, deltaY) {
 
 
 
 
 
 
 
 
 
 
 
 
648
  // ๋งˆ์šฐ์Šค ๊ฐ๋„ ์กฐ์ •
649
- const sensitivity = GAME_CONSTANTS.MOUSE_SENSITIVITY * 1.8;
650
 
651
- // ๋งˆ์šฐ์Šค ์›€์ง์ž„์„ ์ง์ ‘ ํšŒ์ „ ๊ฐ๋„์— ๋ˆ„์  ์ ์šฉ (์ƒ๋Œ€์  ์ž…๋ ฅ)
652
- // X์ถ• (์ขŒ/์šฐ) -> ๋กค ๋ณ€ํ™”๋Ÿ‰
653
- this.targetRoll += deltaX * sensitivity;
654
 
655
- // Y์ถ• (์œ„/์•„๋ž˜) -> ํ”ผ์น˜ ๋ณ€ํ™”๋Ÿ‰ (๋ฐ˜์ „: ๋งˆ์šฐ์Šค ์•„๋ž˜ = ๊ธฐ์ˆ˜ ์œ„๋กœ)
656
- this.targetPitch -= deltaY * sensitivity;
 
657
 
658
- // ๋Œ€์นญ์ ์ธ ๊ฐ๋„ ์ œํ•œ (์œ„/์•„๋ž˜ ๋™์ผ)
659
- const maxPitchAngle = Math.PI / 4; // 45๋„ (์œ„/์•„๋ž˜ ๋™์ผ)
660
- const maxRollAngle = Math.PI * 0.9; // 162๋„
661
 
662
- // ํ•˜๋“œ ํด๋žจํ”„ - ์ ˆ๋Œ€ ์ดˆ๊ณผ ๋ถˆ๊ฐ€
663
  this.targetPitch = Math.max(-maxPitchAngle, Math.min(maxPitchAngle, this.targetPitch));
664
  this.targetRoll = Math.max(-maxRollAngle, Math.min(maxRollAngle, this.targetRoll));
665
 
666
- // ๋กค ๊ฐ๋„ ์ •๊ทœํ™” (180๋„ ์ด๋‚ด๋กœ ์ œํ•œ)
667
- if (this.targetRoll > Math.PI * 0.9) {
668
- this.targetRoll = Math.PI * 0.9;
669
- } else if (this.targetRoll < -Math.PI * 0.9) {
670
- this.targetRoll = -Math.PI * 0.9;
671
  }
 
 
672
  }
673
 
674
  updateControls(keys, deltaTime) {
@@ -699,12 +705,23 @@
699
  updatePhysics(deltaTime) {
700
  if (!this.mesh) return;
701
 
 
 
 
 
702
  // ๋ถ€๋“œ๋Ÿฌ์šด ํšŒ์ „ ๋ณด๊ฐ„
703
- const rotationSpeed = deltaTime * 3.0;
704
  this.rotation.x = THREE.MathUtils.lerp(this.rotation.x, this.targetPitch, rotationSpeed);
705
  this.rotation.y = THREE.MathUtils.lerp(this.rotation.y, this.targetYaw, rotationSpeed);
706
  this.rotation.z = THREE.MathUtils.lerp(this.rotation.z, this.targetRoll, rotationSpeed);
707
 
 
 
 
 
 
 
 
708
  // ๊ธฐ๋ณธ ์†๋„ ๊ณ„์‚ฐ
709
  const minSpeed = 100;
710
  const maxSpeed = 300;
@@ -856,50 +873,54 @@
856
  return this.health <= 0;
857
  }
858
 
859
- // ๊ฐœ์„ ๋œ ์นด๋ฉ”๋ผ ์‹œ์Šคํ…œ (ํด๋ฆฌํ•‘ ๋ฐฉ์ง€)
860
  getCameraPosition() {
861
- // ์ „ํˆฌ๊ธฐ ๊ธฐ์ค€ ์นด๋ฉ”๋ผ ์œ„์น˜ ๊ณ„์‚ฐ
862
- const distance = this.cameraDistance;
863
- const height = this.cameraHeight;
864
-
865
- // ์ „ํˆฌ๊ธฐ์˜ ๋’ค์ชฝ ๋ฐฉํ–ฅ ๊ณ„์‚ฐ (์š” ํšŒ์ „๋งŒ ์ ์šฉ)
866
- const yawOnly = new THREE.Euler(0, this.rotation.y, 0);
 
 
867
  const backward = new THREE.Vector3(0, 0, -1);
868
- backward.applyEuler(yawOnly);
869
 
870
- // ๊ธฐ๋ณธ ์นด๋ฉ”๋ผ ์œ„์น˜ (์•ˆ์ „ํ•œ ๊ฑฐ๋ฆฌ ํ™•๋ณด)
871
- let cameraPos = this.position.clone()
872
- .add(backward.multiplyScalar(distance))
873
- .add(new THREE.Vector3(0, height, 0));
874
 
875
- // ํ”ผ์น˜์— ๋”ฐ๋ฅธ ๋ถ€๋“œ๋Ÿฌ์šด ์นด๋ฉ”๋ผ ์กฐ์ • (ํด๋ฆฌํ•‘ ๋ฐฉ์ง€)
876
- const pitchAngle = this.rotation.x;
877
- const pitchAdjustment = Math.sin(pitchAngle) * distance * 0.2; // ์ค„์ž„
878
- cameraPos.y += Math.max(pitchAdjustment, -height * 0.5); // ์ตœ์†Œ ๋†’์ด ๋ณด์žฅ
879
- cameraPos.z -= Math.abs(pitchAdjustment) * 0.3;
880
 
881
- // ๋กค์— ๋”ฐ๋ฅธ ๋ถ€๋“œ๋Ÿฌ์šด ์นด๋ฉ”๋ผ ์กฐ์ •
882
- const rollAngle = this.rotation.z;
883
- const rollAdjustment = Math.sin(rollAngle) * 40;
884
- cameraPos.x += rollAdjustment;
885
- cameraPos.y += Math.abs(rollAdjustment) * 0.2;
 
 
 
 
 
 
 
 
886
 
887
- // ์ตœ์†Œ ๊ณ ๋„ ๋ณด์žฅ (์ง€๋ฉด ํด๋ฆฌํ•‘ ๋ฐฉ์ง€)
888
- cameraPos.y = Math.max(cameraPos.y, this.position.y + 20);
889
 
890
- return cameraPos;
891
  }
892
 
893
  getCameraTarget() {
894
- // ์ „ํˆฌ๊ธฐ ์•ž์ชฝ ๋ฐฉํ–ฅ์œผ๋กœ ์˜ˆ์ธก ํฌ์ธํŠธ
895
  const forward = new THREE.Vector3(0, 0, 1);
896
- forward.applyEuler(new THREE.Euler(0, this.rotation.y, 0));
897
-
898
- // ํƒ€๊ฒŸ ๋†’์ด๋„ ์•ˆ์ „ํ•˜๊ฒŒ ์„ค์ •
899
- const target = this.position.clone().add(forward.multiplyScalar(100));
900
- target.y = Math.max(target.y, 10); // ์ตœ์†Œ ๋†’์ด ๋ณด์žฅ
901
 
902
- return target;
903
  }
904
  }
905
 
@@ -1091,7 +1112,7 @@
1091
  class Game {
1092
  constructor() {
1093
  this.scene = new THREE.Scene();
1094
- this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1.0, 50000); // near๋ฅผ 1.0์œผ๋กœ ์ฆ๊ฐ€
1095
  this.renderer = new THREE.WebGLRenderer({ antialias: true });
1096
  this.renderer.setSize(window.innerWidth, window.innerHeight);
1097
  this.renderer.shadowMap.enabled = true;
@@ -1612,6 +1633,7 @@
1612
 
1613
  const gameOverDiv = document.createElement('div');
1614
  gameOverDiv.className = 'start-screen';
 
1615
  gameOverDiv.innerHTML = `
1616
  <h1 style="color: ${victory ? '#0f0' : '#f00'}; font-size: 48px;">
1617
  ${victory ? 'MISSION ACCOMPLISHED!' : 'SHOT DOWN!'}
 
1
+ <!DOCTYPE html>
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <html>
3
  <head>
4
  <meta charset="utf-8">
 
87
  }
88
 
89
  #crosshair {
90
+ position: fixed;
91
+ top: 50%;
92
+ left: 50%;
93
+ transform: translate(-50%, -50%);
94
+ width: 40px;
95
+ height: 40px;
96
+ border: 2px solid #00ff00;
97
+ border-radius: 50%;
98
+ z-index: 1001;
99
+ pointer-events: none;
100
+ transition: all 0.2s ease;
101
+ }
102
+
103
+ /* ๋ฌผ์ฒด๊ฐ€ ๊ฐ์ง€๋˜์—ˆ์„ ๋•Œ์˜ ์Šคํƒ€์ผ */
104
+ #crosshair.target-detected {
105
+ border-color: #ff0000;
106
+ border-width: 3px;
107
+ box-shadow: 0 0 10px rgba(255, 0, 0, 0.5);
108
+ }
109
+
110
+ #crosshair::before,
111
+ #crosshair::after {
112
+ content: '';
113
+ position: absolute;
114
+ background: #00ff00;
115
+ transition: all 0.2s ease;
116
+ }
117
+
118
+ #crosshair::before {
119
+ top: 50%;
120
+ left: -10px;
121
+ right: -10px;
122
+ height: 2px;
123
+ transform: translateY(-50%);
124
+ }
125
+
126
+ #crosshair::after {
127
+ left: 50%;
128
+ top: -10px;
129
+ bottom: -10px;
130
+ width: 2px;
131
+ transform: translateX(-50%);
132
+ }
133
+
134
+ /* ๋ฌผ์ฒด๊ฐ€ ๊ฐ์ง€๋˜์—ˆ์„ ๋•Œ์˜ ํฌ๋กœ์Šค ๋ผ์ธ ์Šคํƒ€์ผ */
135
+ #crosshair.target-detected::before,
136
+ #crosshair.target-detected::after {
137
+ background: #ff0000;
138
+ }
139
 
140
  #healthBar {
141
  position: absolute;
 
173
 
174
  #gameTitle {
175
  position: absolute;
176
+ top: 60px; /* 10px์—์„œ 60px๋กœ ๋ณ€๊ฒฝ - ํ™”๋ฉด ์ž˜๋ฆผ ๋ฌธ์ œ ํ•ด๊ฒฐ */
177
  left: 50%;
178
  transform: translateX(-50%);
179
  color: #0f0;
 
551
  this.lastShootTime = 0;
552
 
553
  // ์นด๋ฉ”๋ผ ์„ค์ •
554
+ this.cameraDistance = 300; // ์ ์ ˆํ•œ ๊ฑฐ๋ฆฌ
555
+ this.cameraHeight = 80; // ๋†’์ด ์ฆ๊ฐ€
556
+ this.cameraLag = 0.08; // ๋ถ€๋“œ๋Ÿฌ์šด ์ถ”์ 
557
 
558
  // ๊ฒฝ๊ณ  ์‹œ์Šคํ…œ
559
  this.altitudeWarning = false;
560
  this.stallWarning = false;
561
  this.warningBlinkTimer = 0;
562
  this.warningBlinkState = false;
563
+
564
+ // ๋งˆ์šฐ์Šค ์ž…๋ ฅ ๋ˆ„์  ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ๋ณ€์ˆ˜ ์ถ”๊ฐ€
565
+ this.mouseInputBuffer = { x: 0, y: 0 };
566
+ this.lastMouseUpdate = 0;
567
  }
568
 
569
  async initialize(scene, loader) {
 
636
  }
637
 
638
  updateMouseInput(deltaX, deltaY) {
639
+ const currentTime = Date.now();
640
+
641
+ // ๋งˆ์šฐ์Šค ์ž…๋ ฅ ๋ˆ„์  ๋ฒ„ํผ ์ดˆ๊ธฐํ™” (๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค)
642
+ if (currentTime - this.lastMouseUpdate > 16) { // ์•ฝ 60fps
643
+ this.mouseInputBuffer.x = 0;
644
+ this.mouseInputBuffer.y = 0;
645
+ }
646
+
647
+ // ํ˜„์žฌ ํ”„๋ ˆ์ž„์˜ ๋งˆ์šฐ์Šค ์ž…๋ ฅ ๋ˆ„์ 
648
+ this.mouseInputBuffer.x += deltaX;
649
+ this.mouseInputBuffer.y += deltaY;
650
+
651
  // ๋งˆ์šฐ์Šค ๊ฐ๋„ ์กฐ์ •
652
+ const sensitivity = GAME_CONSTANTS.MOUSE_SENSITIVITY * 1.5;
653
 
654
+ // ๋ˆ„์ ๋œ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชฉํ‘œ ํšŒ์ „๊ฐ’ ์„ค์ •
655
+ const rollChange = this.mouseInputBuffer.x * sensitivity;
656
+ const pitchChange = -this.mouseInputBuffer.y * sensitivity;
657
 
658
+ // ๋Œ€์นญ์ ์ธ ๊ฐ๋„ ์ œํ•œ
659
+ const maxPitchAngle = Math.PI / 3; // 60๋„๋กœ ์ฆ๊ฐ€
660
+ const maxRollAngle = Math.PI; // 180๋„ ์™„์ „ ํ—ˆ์šฉ
661
 
662
+ // ๋ชฉํ‘œ๊ฐ’ ์—…๋ฐ์ดํŠธ (์ ˆ๋Œ€๊ฐ’์ด ์•„๋‹Œ ๋ณ€ํ™”๋Ÿ‰์œผ๋กœ)
663
+ this.targetRoll += rollChange;
664
+ this.targetPitch += pitchChange;
665
 
666
+ // ์—„๊ฒฉํ•œ ์ œํ•œ ์ ์šฉ
667
  this.targetPitch = Math.max(-maxPitchAngle, Math.min(maxPitchAngle, this.targetPitch));
668
  this.targetRoll = Math.max(-maxRollAngle, Math.min(maxRollAngle, this.targetRoll));
669
 
670
+ // ๋กค ๊ฐ๋„ ์ •๊ทœํ™”
671
+ if (this.targetRoll > Math.PI) {
672
+ this.targetRoll -= 2 * Math.PI;
673
+ } else if (this.targetRoll < -Math.PI) {
674
+ this.targetRoll += 2 * Math.PI;
675
  }
676
+
677
+ this.lastMouseUpdate = currentTime;
678
  }
679
 
680
  updateControls(keys, deltaTime) {
 
705
  updatePhysics(deltaTime) {
706
  if (!this.mesh) return;
707
 
708
+ // ๋งˆ์šฐ์Šค ์ž…๋ ฅ ๋ฒ„ํผ ๋ฆฌ์…‹ (๋ฌผ๋ฆฌ ์—…๋ฐ์ดํŠธ ํ›„)
709
+ this.mouseInputBuffer.x *= 0.9; // ์„œ์„œํžˆ ๊ฐ์†Œ
710
+ this.mouseInputBuffer.y *= 0.9;
711
+
712
  // ๋ถ€๋“œ๋Ÿฌ์šด ํšŒ์ „ ๋ณด๊ฐ„
713
+ const rotationSpeed = deltaTime * 2.5; // ์•ฝ๊ฐ„ ๋А๋ฆฌ๊ฒŒ
714
  this.rotation.x = THREE.MathUtils.lerp(this.rotation.x, this.targetPitch, rotationSpeed);
715
  this.rotation.y = THREE.MathUtils.lerp(this.rotation.y, this.targetYaw, rotationSpeed);
716
  this.rotation.z = THREE.MathUtils.lerp(this.rotation.z, this.targetRoll, rotationSpeed);
717
 
718
+ // ์ถ”๊ฐ€ ์•ˆ์ „์žฅ์น˜: ๋ฌผ๋ฆฌ ์—…๋ฐ์ดํŠธ ์ค‘์—๋„ ๊ฐ๋„ ์ œํ•œ
719
+ const maxPitchAngle = Math.PI / 3;
720
+ const maxRollAngle = Math.PI;
721
+
722
+ this.rotation.x = Math.max(-maxPitchAngle, Math.min(maxPitchAngle, this.rotation.x));
723
+ this.rotation.z = Math.max(-maxRollAngle, Math.min(maxRollAngle, this.rotation.z));
724
+
725
  // ๊ธฐ๋ณธ ์†๋„ ๊ณ„์‚ฐ
726
  const minSpeed = 100;
727
  const maxSpeed = 300;
 
873
  return this.health <= 0;
874
  }
875
 
876
+ // ๊ฐœ์„ ๋œ ์นด๋ฉ”๋ผ ์‹œ์Šคํ…œ - ์ •ํ™•ํ•œ ๊ผฌ๋ฆฌ ์ถ”์ 
877
  getCameraPosition() {
878
+ // ์ „ํˆฌ๊ธฐ์˜ ํ˜„์žฌ ํšŒ์ „์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๋ฐฉํ–ฅ ๋ฒกํ„ฐ
879
+ const fighterRotation = new THREE.Euler(
880
+ this.rotation.x,
881
+ this.rotation.y,
882
+ this.rotation.z
883
+ );
884
+
885
+ // ๋’ค์ชฝ ๋ฐฉํ–ฅ ๋ฒกํ„ฐ (์ „ํˆฌ๊ธฐ ๊ธฐ์ค€)
886
  const backward = new THREE.Vector3(0, 0, -1);
887
+ backward.applyEuler(fighterRotation);
888
 
889
+ // ์œ„์ชฝ ๋ฐฉํ–ฅ ๋ฒกํ„ฐ (์ „ํˆฌ๊ธฐ ๊ธฐ์ค€)
890
+ const up = new THREE.Vector3(0, 1, 0);
891
+ up.applyEuler(fighterRotation);
 
892
 
893
+ // ์นด๋ฉ”๋ผ ์œ„์น˜ ๊ณ„์‚ฐ - ์ „ํˆฌ๊ธฐ ๋’ค์ชฝ๊ณผ ์œ„์ชฝ
894
+ const cameraPosition = this.position.clone()
895
+ .add(backward.multiplyScalar(this.cameraDistance))
896
+ .add(up.multiplyScalar(this.cameraHeight));
 
897
 
898
+ // ๊ทน๋‹จ์ ์ธ ๊ธฐ๋™ ์‹œ ์นด๋ฉ”๋ผ ์•ˆ์ •ํ™”
899
+ const pitchAngle = Math.abs(this.rotation.x);
900
+ if (pitchAngle > Math.PI / 3) { // 60๋„ ์ด์ƒ
901
+ // ์›”๋“œ ์—… ๋ฒกํ„ฐ์™€ ๋ธ”๋ Œ๋”ฉํ•˜์—ฌ ์•ˆ์ •ํ™”
902
+ const worldUp = new THREE.Vector3(0, 1, 0);
903
+ const stabilizeFactor = (pitchAngle - Math.PI / 3) / (Math.PI / 6);
904
+ const stabilizedUp = up.lerp(worldUp, Math.min(stabilizeFactor, 0.7));
905
+
906
+ // ์•ˆ์ •ํ™”๋œ ์œ„์น˜๋กœ ์žฌ๊ณ„์‚ฐ
907
+ cameraPosition.copy(this.position)
908
+ .add(backward.multiplyScalar(this.cameraDistance))
909
+ .add(stabilizedUp.multiplyScalar(this.cameraHeight * 1.2));
910
+ }
911
 
912
+ // ์ตœ์†Œ ์นด๋ฉ”๋ผ ๊ณ ๋„ ๋ณด์žฅ
913
+ cameraPosition.y = Math.max(cameraPosition.y, this.position.y - 50);
914
 
915
+ return cameraPosition;
916
  }
917
 
918
  getCameraTarget() {
919
+ // ์ „ํˆฌ๊ธฐ ์ค‘์‹ฌ์„ ์•ฝ๊ฐ„ ์•ž์ชฝ์œผ๋กœ ์ด๋™ํ•œ ์ง€์ 
920
  const forward = new THREE.Vector3(0, 0, 1);
921
+ forward.applyEuler(this.rotation);
 
 
 
 
922
 
923
+ return this.position.clone().add(forward.multiplyScalar(50));
924
  }
925
  }
926
 
 
1112
  class Game {
1113
  constructor() {
1114
  this.scene = new THREE.Scene();
1115
+ this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 50000);
1116
  this.renderer = new THREE.WebGLRenderer({ antialias: true });
1117
  this.renderer.setSize(window.innerWidth, window.innerHeight);
1118
  this.renderer.shadowMap.enabled = true;
 
1633
 
1634
  const gameOverDiv = document.createElement('div');
1635
  gameOverDiv.className = 'start-screen';
1636
+ gameOverDiv.style.display = 'flex'; // ๊ฒŒ์ž„ ์˜ค๋ฒ„ ํ™”๋ฉด์„ ๋ฐ”๋กœ ํ‘œ์‹œ
1637
  gameOverDiv.innerHTML = `
1638
  <h1 style="color: ${victory ? '#0f0' : '#f00'}; font-size: 48px;">
1639
  ${victory ? 'MISSION ACCOMPLISHED!' : 'SHOT DOWN!'}