Spaces:
Running
Running
Update game.js
Browse files
game.js
CHANGED
|
@@ -1134,128 +1134,112 @@ class AIM9Missile {
|
|
| 1134 |
this.isLoaded = true;
|
| 1135 |
}
|
| 1136 |
|
| 1137 |
-
update
|
| 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 |
-
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 |
// ๋ฏธ์ฌ์ผ ๋ค์ชฝ ์์น ๊ณ์ฐ
|
|
@@ -1431,52 +1415,53 @@ class EnemyFighter {
|
|
| 1431 |
this.isLoaded = true;
|
| 1432 |
}
|
| 1433 |
|
| 1434 |
-
update
|
| 1435 |
-
|
| 1436 |
-
|
| 1437 |
-
|
| 1438 |
-
|
| 1439 |
-
|
| 1440 |
-
|
| 1441 |
-
|
| 1442 |
-
|
| 1443 |
-
}
|
| 1444 |
-
|
| 1445 |
-
const distanceToPlayer = this.position.distanceTo(playerPosition);
|
| 1446 |
-
|
| 1447 |
-
// ์ํ ๊ฒฐ์
|
| 1448 |
-
if (this.temporaryEvadeMode) {
|
| 1449 |
-
this.aiState = 'evade';
|
| 1450 |
-
} else if (distanceToPlayer <= 3000) {
|
| 1451 |
-
this.aiState = 'combat';
|
| 1452 |
-
} else {
|
| 1453 |
-
this.aiState = 'patrol';
|
| 1454 |
-
}
|
| 1455 |
-
|
| 1456 |
-
// ์ถฉ๋ ํํผ ๊ณ์ฐ
|
| 1457 |
-
this.calculateAvoidance();
|
| 1458 |
-
this.checkCollisionPrediction(deltaTime);
|
| 1459 |
-
|
| 1460 |
-
// AI ํ๋ ์คํ
|
| 1461 |
-
switch (this.aiState) {
|
| 1462 |
-
case 'patrol':
|
| 1463 |
-
this.executePatrol(deltaTime);
|
| 1464 |
-
break;
|
| 1465 |
-
case 'combat':
|
| 1466 |
-
this.executeCombat(playerPosition, deltaTime);
|
| 1467 |
-
break;
|
| 1468 |
-
case 'evade':
|
| 1469 |
-
this.executeEmergencyEvade(deltaTime);
|
| 1470 |
-
break;
|
| 1471 |
}
|
| 1472 |
-
|
| 1473 |
-
// ๋ฌผ๋ฆฌ ์
๋ฐ์ดํธ
|
| 1474 |
-
this.updatePhysics(deltaTime);
|
| 1475 |
-
|
| 1476 |
-
// ํํ ์
๋ฐ์ดํธ
|
| 1477 |
-
this.updateBullets(deltaTime);
|
| 1478 |
}
|
| 1479 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1480 |
executePatrol(deltaTime) {
|
| 1481 |
// ๋ชฉํ ์ง์ ๊น์ง์ ๊ฑฐ๋ฆฌ ํ์ธ
|
| 1482 |
if (!this.targetPosition || this.position.distanceTo(this.targetPosition) < 500) {
|
|
|
|
| 1134 |
this.isLoaded = true;
|
| 1135 |
}
|
| 1136 |
|
| 1137 |
+
// AIM-9 ๋ฏธ์ฌ์ผ ํด๋์ค - update ๋ฉ์๋ ์์
|
| 1138 |
+
update(deltaTime, playerPosition) {
|
| 1139 |
+
if (!this.mesh || !this.target || !this.target.position) {
|
| 1140 |
+
this.destroy();
|
| 1141 |
+
return 'expired';
|
| 1142 |
+
}
|
| 1143 |
+
|
| 1144 |
+
this.lifeTime -= deltaTime;
|
| 1145 |
+
if (this.lifeTime <= 0) {
|
| 1146 |
+
this.destroy();
|
| 1147 |
+
return 'expired';
|
| 1148 |
+
}
|
| 1149 |
+
|
| 1150 |
+
// missileswing.ogg๋ฅผ ํ ๋ฒ๋ง ์ฌ์
|
| 1151 |
+
if (!this.swingAudioPlayed && this.lifeTime < 29.5) {
|
| 1152 |
+
try {
|
| 1153 |
+
this.swingAudio = new Audio('sounds/missileswing.ogg');
|
| 1154 |
+
this.swingAudio.volume = 0.5;
|
| 1155 |
+
this.swingAudio.play().catch(e => {});
|
| 1156 |
+
this.swingAudioPlayed = true;
|
| 1157 |
+
} catch (e) {
|
| 1158 |
+
console.log('Missile swing audio failed:', e);
|
| 1159 |
+
}
|
| 1160 |
+
}
|
| 1161 |
+
|
| 1162 |
+
// ํ๊ฒ ์ถ์ - ์๋ฒฝํ ์ถ์ ์๊ณ ๋ฆฌ์ฆ
|
| 1163 |
+
const toTarget = this.target.position.clone().sub(this.position);
|
| 1164 |
+
const distance = toTarget.length();
|
| 1165 |
+
|
| 1166 |
+
// ๋ช
์ค ์ฒดํฌ - ๋ฒ์ ์ฆ๊ฐ
|
| 1167 |
+
if (distance < 50) {
|
| 1168 |
+
// ๋ช
์ค!
|
| 1169 |
+
this.onHit();
|
| 1170 |
+
return 'hit';
|
| 1171 |
+
}
|
| 1172 |
+
|
| 1173 |
+
// ์๋ฒฝํ ์ถ์ - ํ๊ฒ์ ํ์ฌ ์์น๋ฅผ ์ ํํ ์ถ์
|
| 1174 |
+
toTarget.normalize();
|
| 1175 |
+
|
| 1176 |
+
// ์ฆ๊ฐ์ ์ธ ๋ฐฉํฅ ์ ํ - ํ์ ์จ ์ ํ ์์
|
| 1177 |
+
const newDirection = toTarget.clone();
|
| 1178 |
+
|
| 1179 |
+
// ์๋ ์ฆ๊ฐ - ๋ ๋น ๋ฅธ ์ถ์
|
| 1180 |
+
if (this.lifeTime > 25) {
|
| 1181 |
+
// ์ด๊ธฐ 5์ด๊ฐ ๊ฐ์
|
| 1182 |
+
this.speed = Math.min(this.speed + deltaTime * 300, 2057.6); // ์ต๋ 4000kt
|
| 1183 |
+
} else {
|
| 1184 |
+
// ์ดํ์๋ ๋์ ์๋ ์ ์ง
|
| 1185 |
+
this.speed = Math.min(this.speed + deltaTime * 100, 2057.6);
|
| 1186 |
+
}
|
| 1187 |
+
|
| 1188 |
+
// ํ๊ฒ๊ณผ์ ๊ฑฐ๋ฆฌ์ ๋ฐ๋ผ ์๋ ์ถ๊ฐ ์ฆ๊ฐ
|
| 1189 |
+
if (distance < 1000) {
|
| 1190 |
+
// ๊ทผ๊ฑฐ๋ฆฌ์์ ๋์ฑ ๋น ๋ฅด๊ฒ
|
| 1191 |
+
this.speed = Math.min(this.speed * 1.2, 2572); // ์ต๋ 5000kt
|
| 1192 |
+
}
|
| 1193 |
+
|
| 1194 |
+
this.velocity = newDirection.multiplyScalar(this.speed);
|
| 1195 |
+
|
| 1196 |
+
// ์์น ์
๋ฐ์ดํธ
|
| 1197 |
+
this.position.add(this.velocity.clone().multiplyScalar(deltaTime));
|
| 1198 |
+
this.mesh.position.copy(this.position);
|
| 1199 |
+
|
| 1200 |
+
// ๋ฏธ์ฌ์ผ ํ์ - ์ ํํ ํ๊ฒ์ ํฅํจ
|
| 1201 |
+
this.mesh.lookAt(this.target.position);
|
| 1202 |
+
|
| 1203 |
+
// ์ถ๋ ฅ ์ฐ๊ธฐ ์์ฑ
|
| 1204 |
+
this.smokeEmitTime += deltaTime;
|
| 1205 |
+
if (this.smokeEmitTime >= 0.02) {
|
| 1206 |
+
this.smokeEmitTime = 0;
|
| 1207 |
+
this.createSmokeParticle();
|
| 1208 |
+
}
|
| 1209 |
+
|
| 1210 |
+
// ์ฐ๊ธฐ ํํฐํด ์
๋ฐ์ดํธ
|
| 1211 |
+
for (let i = this.smokeTrail.length - 1; i >= 0; i--) {
|
| 1212 |
+
const smoke = this.smokeTrail[i];
|
| 1213 |
+
smoke.life -= deltaTime;
|
| 1214 |
+
|
| 1215 |
+
if (smoke.life <= 0) {
|
| 1216 |
+
this.scene.remove(smoke.mesh);
|
| 1217 |
+
this.smokeTrail.splice(i, 1);
|
| 1218 |
+
} else {
|
| 1219 |
+
// ์ฐ๊ธฐ ํ์ฐ ๋ฐ ํ์ด๋
|
| 1220 |
+
smoke.mesh.scale.multiplyScalar(1.02);
|
| 1221 |
+
smoke.mesh.material.opacity = smoke.life / 3.0;
|
| 1222 |
+
|
| 1223 |
+
// ์ฝ๊ฐ์ ์์น ํจ๊ณผ
|
| 1224 |
+
smoke.mesh.position.y += deltaTime * 2;
|
| 1225 |
+
}
|
| 1226 |
+
}
|
| 1227 |
+
|
| 1228 |
+
// ์ง๋ฉด ์ถฉ๋
|
| 1229 |
+
if (this.position.y <= 0) {
|
| 1230 |
+
this.destroy();
|
| 1231 |
+
return 'expired';
|
| 1232 |
+
}
|
| 1233 |
+
|
| 1234 |
+
// ํ๊ฒ์ด ์ง๋ฉด์ ์์ผ๋ฉด ๋ฏธ์ฌ์ผ๋ ๋ฐ๋ผ๊ฐ
|
| 1235 |
+
if (this.target.position.y <= 50 && distance < 200) {
|
| 1236 |
+
// ํ๊ฒ์ด ์ง๋ฉด ๊ทผ์ฒ์ ์๊ณ ๊ฑฐ๋ฆฌ๊ฐ ๊ฐ๊น์ฐ๋ฉด ์ฆ์ ๋ช
์ค
|
| 1237 |
+
this.onHit();
|
| 1238 |
+
return 'hit';
|
| 1239 |
+
}
|
| 1240 |
+
|
| 1241 |
+
return 'flying';
|
| 1242 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1243 |
|
| 1244 |
createSmokeParticle() {
|
| 1245 |
// ๋ฏธ์ฌ์ผ ๋ค์ชฝ ์์น ๊ณ์ฐ
|
|
|
|
| 1415 |
this.isLoaded = true;
|
| 1416 |
}
|
| 1417 |
|
| 1418 |
+
// EnemyFighter ํด๋์ค์ update ๋ฉ์๋์์ ๋ฏธ์ฌ์ผ ํํผ ๋ก์ง ์ ๊ฑฐ
|
| 1419 |
+
update(playerPosition, deltaTime) {
|
| 1420 |
+
if (!this.mesh || !this.isLoaded) return;
|
| 1421 |
+
|
| 1422 |
+
// ํํผ ํ์ด๋จธ ์
๋ฐ์ดํธ (๋ฏธ์ฌ์ผ ํํผ ์ ์ธ)
|
| 1423 |
+
if (this.temporaryEvadeMode && this.evadeTimer > 0) {
|
| 1424 |
+
this.evadeTimer -= deltaTime;
|
| 1425 |
+
if (this.evadeTimer <= 0) {
|
| 1426 |
+
this.temporaryEvadeMode = false;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1427 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1428 |
}
|
| 1429 |
|
| 1430 |
+
const distanceToPlayer = this.position.distanceTo(playerPosition);
|
| 1431 |
+
|
| 1432 |
+
// ์ํ ๊ฒฐ์ (๋ฏธ์ฌ์ผ ํ์ง ์ ๊ฑฐ)
|
| 1433 |
+
if (this.temporaryEvadeMode) {
|
| 1434 |
+
this.aiState = 'evade';
|
| 1435 |
+
} else if (distanceToPlayer <= 3000) {
|
| 1436 |
+
this.aiState = 'combat';
|
| 1437 |
+
} else {
|
| 1438 |
+
this.aiState = 'patrol';
|
| 1439 |
+
}
|
| 1440 |
+
|
| 1441 |
+
// ์ถฉ๋ ํํผ ๊ณ์ฐ (๋ค๋ฅธ ์ ๊ธฐ์์ ์ถฉ๋๋ง)
|
| 1442 |
+
this.calculateAvoidance();
|
| 1443 |
+
this.checkCollisionPrediction(deltaTime);
|
| 1444 |
+
|
| 1445 |
+
// AI ํ๋ ์คํ
|
| 1446 |
+
switch (this.aiState) {
|
| 1447 |
+
case 'patrol':
|
| 1448 |
+
this.executePatrol(deltaTime);
|
| 1449 |
+
break;
|
| 1450 |
+
case 'combat':
|
| 1451 |
+
this.executeCombat(playerPosition, deltaTime);
|
| 1452 |
+
break;
|
| 1453 |
+
case 'evade':
|
| 1454 |
+
this.executeEmergencyEvade(deltaTime);
|
| 1455 |
+
break;
|
| 1456 |
+
}
|
| 1457 |
+
|
| 1458 |
+
// ๋ฌผ๋ฆฌ ์
๋ฐ์ดํธ
|
| 1459 |
+
this.updatePhysics(deltaTime);
|
| 1460 |
+
|
| 1461 |
+
// ํํ ์
๋ฐ์ดํธ
|
| 1462 |
+
this.updateBullets(deltaTime);
|
| 1463 |
+
}
|
| 1464 |
+
|
| 1465 |
executePatrol(deltaTime) {
|
| 1466 |
// ๋ชฉํ ์ง์ ๊น์ง์ ๊ฑฐ๋ฆฌ ํ์ธ
|
| 1467 |
if (!this.targetPosition || this.position.distanceTo(this.targetPosition) < 500) {
|