Spaces:
Running
Running
Update game.js
Browse files
game.js
CHANGED
@@ -1010,301 +1010,333 @@ class Fighter {
|
|
1010 |
}
|
1011 |
}
|
1012 |
|
1013 |
-
// AIM-9 ๋ฏธ์ฌ์ผ ํด๋์ค
|
1014 |
class AIM9Missile {
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
|
1145 |
-
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1308 |
}
|
1309 |
|
1310 |
// ์ ์ ํฌ๊ธฐ ํด๋์ค - ์์ ํ ์ฌ์ค๊ณ
|
|
|
1010 |
}
|
1011 |
}
|
1012 |
|
1013 |
+
javascript// AIM-9 ๋ฏธ์ฌ์ผ ํด๋์ค
|
1014 |
class AIM9Missile {
|
1015 |
+
constructor(scene, position, target, rotation) {
|
1016 |
+
this.scene = scene;
|
1017 |
+
this.position = position.clone();
|
1018 |
+
this.target = target;
|
1019 |
+
this.rotation = rotation.clone();
|
1020 |
+
this.speed = 1028.8; // 2000kt๋ฅผ m/s๋ก ๋ณํ
|
1021 |
+
this.mesh = null;
|
1022 |
+
this.isLoaded = false;
|
1023 |
+
this.lifeTime = 30; // 30์ด๋ก ์ฆ๊ฐ (๋ ์ค๋ ์ถ์ )
|
1024 |
+
this.turnRate = 6.0; // ํ์ ์จ 2๋ฐฐ ์ฆ๊ฐ (๋ ๋น ๋ฅธ ์ถ์ )
|
1025 |
+
this.startPosition = position.clone();
|
1026 |
+
|
1027 |
+
// ์ถ๋ ฅ ์ฐ๊ธฐ ํํฐํด
|
1028 |
+
this.smokeTrail = [];
|
1029 |
+
this.smokeEmitTime = 0;
|
1030 |
+
|
1031 |
+
// ๋ฏธ์ฌ์ผ ๋ฐ์ฌ ๋ฐฉํฅ ์ค์
|
1032 |
+
const quaternion = new THREE.Quaternion();
|
1033 |
+
const pitchQuat = new THREE.Quaternion();
|
1034 |
+
const yawQuat = new THREE.Quaternion();
|
1035 |
+
const rollQuat = new THREE.Quaternion();
|
1036 |
+
|
1037 |
+
pitchQuat.setFromAxisAngle(new THREE.Vector3(1, 0, 0), this.rotation.x);
|
1038 |
+
yawQuat.setFromAxisAngle(new THREE.Vector3(0, 1, 0), this.rotation.y);
|
1039 |
+
rollQuat.setFromAxisAngle(new THREE.Vector3(0, 0, 1), this.rotation.z);
|
1040 |
+
|
1041 |
+
quaternion.multiply(rollQuat);
|
1042 |
+
quaternion.multiply(pitchQuat);
|
1043 |
+
quaternion.multiply(yawQuat);
|
1044 |
+
|
1045 |
+
const initialDirection = new THREE.Vector3(0, 0, 1);
|
1046 |
+
initialDirection.applyQuaternion(quaternion);
|
1047 |
+
this.velocity = initialDirection.multiplyScalar(this.speed);
|
1048 |
+
|
1049 |
+
// ๋ฏธ์ฌ์ผ ์๋ฆฌ
|
1050 |
+
this.swingAudio = null;
|
1051 |
+
this.swingAudioPlayed = false; // ํ ๋ฒ๋ง ์ฌ์ํ๊ธฐ ์ํ ํ๋๊ทธ
|
1052 |
+
this.initializeAudio();
|
1053 |
+
|
1054 |
+
this.createMissile();
|
1055 |
+
}
|
1056 |
+
|
1057 |
+
initializeAudio() {
|
1058 |
+
// missileswing.ogg๋ update ๋ฉ์๋์์ ํ ๋ฒ๋ง ์ฌ์
|
1059 |
+
// ์ฌ๊ธฐ์๋ ์ด๊ธฐํํ์ง ์์
|
1060 |
+
}
|
1061 |
+
|
1062 |
+
createMissile() {
|
1063 |
+
// ์ฆ์ ํด๋ฐฑ ๋ชจ๋ธ ์์ฑ (๋น๋๊ธฐ ๋ก๋ฉ ๋์ )
|
1064 |
+
this.createFallbackMissile();
|
1065 |
+
|
1066 |
+
this.mesh.position.copy(this.position);
|
1067 |
+
this.scene.add(this.mesh);
|
1068 |
+
|
1069 |
+
// ๋์ค์ GLB ๋ชจ๋ธ ๋ก๋ ์๋ (์ ํ์ฌํญ)
|
1070 |
+
const loader = new GLTFLoader();
|
1071 |
+
loader.load('models/aim-9.glb',
|
1072 |
+
(result) => {
|
1073 |
+
// ๋ชจ๋ธ ๋ก๋ ์ฑ๊ณต ์ ๊ต์ฒด
|
1074 |
+
if (this.mesh && this.mesh.parent) {
|
1075 |
+
this.scene.remove(this.mesh);
|
1076 |
+
this.mesh = result.scene;
|
1077 |
+
this.mesh.scale.set(0.75, 0.75, 0.75);
|
1078 |
+
this.mesh.position.copy(this.position);
|
1079 |
+
this.scene.add(this.mesh);
|
1080 |
+
console.log('AIM-9 model loaded and replaced');
|
1081 |
+
}
|
1082 |
+
},
|
1083 |
+
undefined,
|
1084 |
+
(error) => {
|
1085 |
+
console.log('AIM-9 model not found, keeping fallback');
|
1086 |
+
}
|
1087 |
+
);
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
createFallbackMissile() {
|
1091 |
+
// ํด๋ฐฑ ๋ฏธ์ฌ์ผ ๋ชจ๋ธ
|
1092 |
+
const group = new THREE.Group();
|
1093 |
+
|
1094 |
+
// ๋ฏธ์ฌ์ผ ๋ณธ์ฒด
|
1095 |
+
const bodyGeometry = new THREE.CylinderGeometry(0.3, 0.4, 4, 8);
|
1096 |
+
const bodyMaterial = new THREE.MeshLambertMaterial({ color: 0x808080 });
|
1097 |
+
const body = new THREE.Mesh(bodyGeometry, bodyMaterial);
|
1098 |
+
body.rotation.x = Math.PI / 2;
|
1099 |
+
group.add(body);
|
1100 |
+
|
1101 |
+
// ํ๋
|
1102 |
+
const noseGeometry = new THREE.ConeGeometry(0.3, 1, 8);
|
1103 |
+
const noseMaterial = new THREE.MeshLambertMaterial({ color: 0x404040 });
|
1104 |
+
const nose = new THREE.Mesh(noseGeometry, noseMaterial);
|
1105 |
+
nose.position.z = 2.5;
|
1106 |
+
nose.rotation.x = -Math.PI / 2;
|
1107 |
+
group.add(nose);
|
1108 |
+
|
1109 |
+
// ๋ ๊ฐ
|
1110 |
+
const finGeometry = new THREE.BoxGeometry(2, 0.1, 0.5);
|
1111 |
+
const finMaterial = new THREE.MeshLambertMaterial({ color: 0x606060 });
|
1112 |
+
|
1113 |
+
for (let i = 0; i < 4; i++) {
|
1114 |
+
const fin = new THREE.Mesh(finGeometry, finMaterial);
|
1115 |
+
fin.position.z = -1.5;
|
1116 |
+
fin.rotation.z = (Math.PI / 2) * i;
|
1117 |
+
group.add(fin);
|
1118 |
+
}
|
1119 |
+
|
1120 |
+
// ๋ถ๊ฝ ํจ๊ณผ
|
1121 |
+
const flameGeometry = new THREE.ConeGeometry(0.4, 1.5, 8);
|
1122 |
+
const flameMaterial = new THREE.MeshBasicMaterial({
|
1123 |
+
color: 0xff4400,
|
1124 |
+
transparent: true,
|
1125 |
+
opacity: 0.8
|
1126 |
+
});
|
1127 |
+
const flame = new THREE.Mesh(flameGeometry, flameMaterial);
|
1128 |
+
flame.position.z = -2.5;
|
1129 |
+
flame.rotation.x = Math.PI / 2;
|
1130 |
+
group.add(flame);
|
1131 |
+
|
1132 |
+
this.mesh = group;
|
1133 |
+
this.mesh.scale.set(2.25, 2.25, 2.25); // 50% ๋ ํฌ๊ฒ (1.5 -> 2.25)
|
1134 |
+
this.isLoaded = true;
|
1135 |
+
}
|
1136 |
+
|
1137 |
+
update(deltaTime, playerPosition) {
|
1138 |
+
if (!this.mesh || !this.target || !this.target.position) {
|
1139 |
+
this.destroy();
|
1140 |
+
return 'expired';
|
1141 |
+
}
|
1142 |
+
|
1143 |
+
this.lifeTime -= deltaTime;
|
1144 |
+
if (this.lifeTime <= 0) {
|
1145 |
+
this.destroy();
|
1146 |
+
return 'expired';
|
1147 |
+
}
|
1148 |
+
|
1149 |
+
// missileswing.ogg๋ฅผ ํ ๋ฒ๋ง ์ฌ์
|
1150 |
+
if (!this.swingAudioPlayed && this.lifeTime < 29.5) { // ๋ฐ์ฌ 0.5์ด ํ ์ฌ๏ฟฝ๏ฟฝ
|
1151 |
+
try {
|
1152 |
+
this.swingAudio = new Audio('sounds/missileswing.ogg');
|
1153 |
+
this.swingAudio.volume = 0.5;
|
1154 |
+
this.swingAudio.play().catch(e => {});
|
1155 |
+
this.swingAudioPlayed = true;
|
1156 |
+
} catch (e) {
|
1157 |
+
console.log('Missile swing audio failed:', e);
|
1158 |
+
}
|
1159 |
+
}
|
1160 |
+
|
1161 |
+
// ํ๊ฒ ์ถ์ - ํฅ์๋ ํธ๋ฐ ์๊ณ ๋ฆฌ์ฆ
|
1162 |
+
const toTarget = this.target.position.clone().sub(this.position);
|
1163 |
+
const distance = toTarget.length();
|
1164 |
+
|
1165 |
+
// ๋ช
์ค ์ฒดํฌ - ๋ฒ์ ์ฆ๊ฐ
|
1166 |
+
if (distance < 50) { // 30์์ 50์ผ๋ก ์ฆ๊ฐ
|
1167 |
+
// ๋ช
์ค!
|
1168 |
+
this.onHit();
|
1169 |
+
return 'hit';
|
1170 |
+
}
|
1171 |
+
|
1172 |
+
// ์์ธก ์ฌ๊ฒฉ: ํ๊ฒ์ ๋ฏธ๋ ์์น ์์ธก
|
1173 |
+
if (this.target.velocity) {
|
1174 |
+
const timeToImpact = distance / this.speed;
|
1175 |
+
const predictedPosition = this.target.position.clone().add(
|
1176 |
+
this.target.velocity.clone().multiplyScalar(timeToImpact * 0.5)
|
1177 |
+
);
|
1178 |
+
toTarget.copy(predictedPosition.sub(this.position));
|
1179 |
+
}
|
1180 |
+
|
1181 |
+
toTarget.normalize();
|
1182 |
+
const currentDirection = this.velocity.clone().normalize();
|
1183 |
+
|
1184 |
+
// ๋น๋ก ํญ๋ฒ ์ ๋ (Proportional Navigation)
|
1185 |
+
const closing_velocity = this.velocity.length();
|
1186 |
+
const line_of_sight_rate = currentDirection.clone().cross(toTarget);
|
1187 |
+
const navigation_constant = 4.0; // N = 4 (์ผ๋ฐ์ ์ธ ๋ฏธ์ฌ์ผ ์์)
|
1188 |
+
|
1189 |
+
// ๊ฐ์๋ ๋ช
๋ น ๊ณ์ฐ
|
1190 |
+
const commanded_acceleration = line_of_sight_rate.multiplyScalar(
|
1191 |
+
navigation_constant * closing_velocity
|
1192 |
+
);
|
1193 |
+
|
1194 |
+
// ๋ถ๋๋ฌ์ด ๋ฐฉํฅ ์ ํ with ๋น๋ก ํญ๋ฒ
|
1195 |
+
const newDirection = currentDirection.clone();
|
1196 |
+
const maxTurnRate = this.turnRate * deltaTime;
|
1197 |
+
|
1198 |
+
// ๊ฐ์๋๋ฅผ ๋ฐฉํฅ ๋ณํ๋ก ๋ณํ
|
1199 |
+
const deltaDirection = commanded_acceleration.multiplyScalar(deltaTime / this.speed);
|
1200 |
+
newDirection.add(deltaDirection);
|
1201 |
+
|
1202 |
+
// ์ง์ ์ถ์ ๋ ํผํฉ (๊ทผ๊ฑฐ๋ฆฌ์์ ๋ ์ ํํ ์ถ์ )
|
1203 |
+
if (distance < 500) {
|
1204 |
+
const directWeight = 1.0 - (distance / 500);
|
1205 |
+
newDirection.lerp(toTarget, directWeight * maxTurnRate);
|
1206 |
+
}
|
1207 |
+
|
1208 |
+
newDirection.normalize();
|
1209 |
+
|
1210 |
+
// ์๋ ์
๋ฐ์ดํธ - ๊ฐ์ ์ถ๊ฐ
|
1211 |
+
if (this.lifeTime > 25) {
|
1212 |
+
// ์ด๊ธฐ 5์ด๊ฐ ๊ฐ์
|
1213 |
+
this.speed = Math.min(this.speed + deltaTime * 200, 1543.2); // ์ต๋ 3000kt
|
1214 |
+
}
|
1215 |
+
|
1216 |
+
this.velocity = newDirection.multiplyScalar(this.speed);
|
1217 |
+
|
1218 |
+
// ์์น ์
๋ฐ์ดํธ
|
1219 |
+
this.position.add(this.velocity.clone().multiplyScalar(deltaTime));
|
1220 |
+
this.mesh.position.copy(this.position);
|
1221 |
+
|
1222 |
+
// ๋ฏธ์ฌ์ผ ํ์
|
1223 |
+
const lookAtTarget = this.position.clone().add(this.velocity);
|
1224 |
+
this.mesh.lookAt(lookAtTarget);
|
1225 |
+
|
1226 |
+
// ์ถ๋ ฅ ์ฐ๊ธฐ ์์ฑ
|
1227 |
+
this.smokeEmitTime += deltaTime;
|
1228 |
+
if (this.smokeEmitTime >= 0.02) { // 0.02์ด๋ง๋ค ์ฐ๊ธฐ ์์ฑ
|
1229 |
+
this.smokeEmitTime = 0;
|
1230 |
+
this.createSmokeParticle();
|
1231 |
+
}
|
1232 |
+
|
1233 |
+
// ์ฐ๊ธฐ ํํฐํด ์
๋ฐ์ดํธ
|
1234 |
+
for (let i = this.smokeTrail.length - 1; i >= 0; i--) {
|
1235 |
+
const smoke = this.smokeTrail[i];
|
1236 |
+
smoke.life -= deltaTime;
|
1237 |
+
|
1238 |
+
if (smoke.life <= 0) {
|
1239 |
+
this.scene.remove(smoke.mesh);
|
1240 |
+
this.smokeTrail.splice(i, 1);
|
1241 |
+
} else {
|
1242 |
+
// ์ฐ๊ธฐ ํ์ฐ ๋ฐ ํ์ด๋
|
1243 |
+
smoke.mesh.scale.multiplyScalar(1.02);
|
1244 |
+
smoke.mesh.material.opacity = smoke.life / 3.0;
|
1245 |
+
|
1246 |
+
// ์ฝ๊ฐ์ ์์น ํจ๊ณผ
|
1247 |
+
smoke.mesh.position.y += deltaTime * 2;
|
1248 |
+
}
|
1249 |
+
}
|
1250 |
+
|
1251 |
+
// ์ง๋ฉด ์ถฉ๋
|
1252 |
+
if (this.position.y <= 0) {
|
1253 |
+
this.destroy();
|
1254 |
+
return 'expired';
|
1255 |
+
}
|
1256 |
+
|
1257 |
+
return 'flying';
|
1258 |
+
}
|
1259 |
+
|
1260 |
+
createSmokeParticle() {
|
1261 |
+
// ๋ฏธ์ฌ์ผ ๋ค์ชฝ ์์น ๊ณ์ฐ
|
1262 |
+
const backward = this.velocity.clone().normalize().multiplyScalar(-3);
|
1263 |
+
const smokePos = this.position.clone().add(backward);
|
1264 |
+
|
1265 |
+
// ํ์ ์ฐ๊ธฐ ํํฐํด ์์ฑ
|
1266 |
+
const smokeGeometry = new THREE.SphereGeometry(
|
1267 |
+
1 + Math.random() * 2.5, // ํฌ๊ธฐ ๋ณํ
|
1268 |
+
6,
|
1269 |
+
6
|
1270 |
+
);
|
1271 |
+
const smokeMaterial = new THREE.MeshBasicMaterial({
|
1272 |
+
color: 0xffffff, // ํ์์
|
1273 |
+
transparent: true,
|
1274 |
+
opacity: 0.8
|
1275 |
+
});
|
1276 |
+
|
1277 |
+
const smoke = new THREE.Mesh(smokeGeometry, smokeMaterial);
|
1278 |
+
smoke.position.copy(smokePos);
|
1279 |
+
|
1280 |
+
// ์ฝ๊ฐ์ ๋๋ค ์คํ์
|
1281 |
+
smoke.position.x += (Math.random() - 0.5) * 1;
|
1282 |
+
smoke.position.y += (Math.random() - 0.5) * 1;
|
1283 |
+
smoke.position.z += (Math.random() - 0.5) * 1;
|
1284 |
+
|
1285 |
+
this.scene.add(smoke);
|
1286 |
+
|
1287 |
+
this.smokeTrail.push({
|
1288 |
+
mesh: smoke,
|
1289 |
+
life: 3.0 // 3์ด ๋์ ์ง์
|
1290 |
+
});
|
1291 |
+
|
1292 |
+
// ์ฐ๊ธฐ ํํฐํด ์ ํ (์ฑ๋ฅ์ ์ํด)
|
1293 |
+
if (this.smokeTrail.length > 150) {
|
1294 |
+
const oldSmoke = this.smokeTrail.shift();
|
1295 |
+
this.scene.remove(oldSmoke.mesh);
|
1296 |
+
}
|
1297 |
+
}
|
1298 |
+
|
1299 |
+
onHit() {
|
1300 |
+
// ๋ช
์ค ํจ๊ณผ
|
1301 |
+
if (window.gameInstance) {
|
1302 |
+
window.gameInstance.createExplosionEffect(this.position);
|
1303 |
+
}
|
1304 |
+
|
1305 |
+
// ๋ช
์ค์
|
1306 |
+
try {
|
1307 |
+
const hitSound = new Audio('sounds/missilehit.ogg');
|
1308 |
+
hitSound.volume = 0.8;
|
1309 |
+
hitSound.play().catch(e => {});
|
1310 |
+
} catch (e) {
|
1311 |
+
console.log('Missile hit sound failed:', e);
|
1312 |
+
}
|
1313 |
+
|
1314 |
+
// ํ๊ฒ์๊ฒ ํผํด
|
1315 |
+
if (this.target.takeDamage) {
|
1316 |
+
this.target.takeDamage(GAME_CONSTANTS.AIM9_DAMAGE);
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
this.destroy();
|
1320 |
+
}
|
1321 |
+
|
1322 |
+
destroy() {
|
1323 |
+
if (this.mesh) {
|
1324 |
+
this.scene.remove(this.mesh);
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
// ์ฐ๊ธฐ ํํฐํด ์ ๋ฆฌ
|
1328 |
+
this.smokeTrail.forEach(smoke => {
|
1329 |
+
if (smoke.mesh) {
|
1330 |
+
this.scene.remove(smoke.mesh);
|
1331 |
+
}
|
1332 |
+
});
|
1333 |
+
this.smokeTrail = [];
|
1334 |
+
|
1335 |
+
if (this.swingAudio) {
|
1336 |
+
this.swingAudio.pause();
|
1337 |
+
this.swingAudio = null;
|
1338 |
+
}
|
1339 |
+
}
|
1340 |
}
|
1341 |
|
1342 |
// ์ ์ ํฌ๊ธฐ ํด๋์ค - ์์ ํ ์ฌ์ค๊ณ
|