Spaces:
Running
Running
Add 1 files
Browse files- index.html +273 -98
index.html
CHANGED
@@ -56,6 +56,44 @@
|
|
56 |
position: relative;
|
57 |
height: 400px;
|
58 |
overflow: hidden;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
}
|
60 |
|
61 |
.rocket-3d {
|
@@ -65,6 +103,7 @@
|
|
65 |
bottom: 0;
|
66 |
left: 50%;
|
67 |
transform: translateX(-50%);
|
|
|
68 |
}
|
69 |
|
70 |
.flame {
|
@@ -150,7 +189,7 @@
|
|
150 |
100% { opacity: 1; }
|
151 |
}
|
152 |
|
153 |
-
/*
|
154 |
.launch-smoke {
|
155 |
position: absolute;
|
156 |
bottom: 0;
|
@@ -162,6 +201,7 @@
|
|
162 |
border-radius: 50%;
|
163 |
filter: blur(10px);
|
164 |
opacity: 0;
|
|
|
165 |
}
|
166 |
|
167 |
.launching .launch-smoke {
|
@@ -274,6 +314,7 @@
|
|
274 |
justify-content: center;
|
275 |
opacity: 0;
|
276 |
transform: scale(0);
|
|
|
277 |
}
|
278 |
|
279 |
.success-animate {
|
@@ -285,6 +326,50 @@
|
|
285 |
50% { transform: scale(1.2); opacity: 1; }
|
286 |
100% { transform: scale(1); opacity: 1; }
|
287 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
288 |
</style>
|
289 |
</head>
|
290 |
<body>
|
@@ -303,7 +388,7 @@
|
|
303 |
<div class="flex items-center space-x-4">
|
304 |
<div class="hidden md:flex items-center space-x-2">
|
305 |
<i class="fas fa-coins text-yellow-400"></i>
|
306 |
-
<span class="font-bold" id="funds">$
|
307 |
</div>
|
308 |
<div class="hidden md:flex items-center space-x-2">
|
309 |
<i class="fas fa-star text-blue-400"></i>
|
@@ -325,8 +410,11 @@
|
|
325 |
<div class="bg-gray-900 rounded-xl p-6 shadow-xl border border-gray-800">
|
326 |
<h2 class="orbitron text-xl text-blue-400 mb-4">ROCKET DESIGN</h2>
|
327 |
<div class="rocket-display flex justify-center items-end" id="rocket-display">
|
|
|
|
|
|
|
|
|
328 |
<div class="rocket-3d" id="rocket-model">
|
329 |
-
<!-- Rocket parts will be added here by JavaScript -->
|
330 |
<div class="flame" id="rocket-flame"></div>
|
331 |
<div class="launch-smoke"></div>
|
332 |
</div>
|
@@ -477,47 +565,75 @@
|
|
477 |
}
|
478 |
}
|
479 |
|
480 |
-
// Rocket parts data
|
481 |
const rocketParts = {
|
482 |
firstStages: [
|
483 |
-
{ id: 'falcon9', name: 'Falcon 9', cost: 5000000, mass: 25000, thrust: 7607, height: 10,
|
484 |
-
|
485 |
-
{ id: '
|
486 |
-
|
|
|
|
|
|
|
|
|
487 |
],
|
488 |
secondStages: [
|
489 |
-
{ id: 'falcon9-upper', name: 'Falcon 9 Upper', cost: 2000000, mass: 5000, thrust: 934, height: 6,
|
490 |
-
|
491 |
-
{ id: '
|
492 |
-
|
|
|
|
|
|
|
|
|
493 |
],
|
494 |
fairings: [
|
495 |
-
{ id: 'standard', name: 'Standard Fairing', cost: 1000000, mass: 2000, height: 5,
|
496 |
-
|
497 |
-
{ id: '
|
498 |
-
|
|
|
|
|
|
|
|
|
499 |
],
|
500 |
engines: [
|
501 |
-
{ id: 'merlin', name: 'Merlin', cost: 1000000, thrust: 845, isp: 282,
|
502 |
-
|
503 |
-
{ id: '
|
504 |
-
|
|
|
|
|
|
|
|
|
505 |
]
|
506 |
};
|
507 |
|
508 |
-
// Planets data
|
509 |
const destinations = [
|
510 |
-
{ id: 'leo', name: 'Low Earth Orbit', distance: 200, difficulty: 1,
|
511 |
-
|
512 |
-
|
513 |
-
{ id: '
|
514 |
-
|
515 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
516 |
];
|
517 |
|
518 |
// Game state
|
519 |
let gameState = {
|
520 |
-
funds:
|
521 |
reputation: 100,
|
522 |
currentRocket: {
|
523 |
firstStage: null,
|
@@ -582,7 +698,7 @@
|
|
582 |
partElement.dataset.partType = partType;
|
583 |
|
584 |
partElement.innerHTML = `
|
585 |
-
<div class="w-16 h-16
|
586 |
${part.image ? `<img src="${part.image}" alt="${part.name}" class="w-full h-full object-contain">` : '<i class="fas fa-rocket text-xl"></i>'}
|
587 |
</div>
|
588 |
<h3 class="font-bold text-center">${part.name}</h3>
|
@@ -669,22 +785,34 @@
|
|
669 |
// Add parts to the rocket model
|
670 |
if (gameState.currentRocket.firstStage) {
|
671 |
const firstStage = document.createElement('div');
|
672 |
-
firstStage.className = `first-stage
|
673 |
firstStage.style.height = `${gameState.currentRocket.firstStage.height * 10}px`;
|
|
|
|
|
|
|
|
|
674 |
rocketModel.appendChild(firstStage);
|
675 |
}
|
676 |
|
677 |
if (gameState.currentRocket.secondStage) {
|
678 |
const secondStage = document.createElement('div');
|
679 |
-
secondStage.className = `second-stage
|
680 |
secondStage.style.height = `${gameState.currentRocket.secondStage.height * 10}px`;
|
|
|
|
|
|
|
|
|
681 |
rocketModel.appendChild(secondStage);
|
682 |
}
|
683 |
|
684 |
if (gameState.currentRocket.fairing && gameState.currentRocket.fairing.id !== 'none') {
|
685 |
const fairing = document.createElement('div');
|
686 |
-
fairing.className = `fairing
|
687 |
fairing.style.height = `${gameState.currentRocket.fairing.height * 10}px`;
|
|
|
|
|
|
|
|
|
688 |
rocketModel.appendChild(fairing);
|
689 |
}
|
690 |
}
|
@@ -754,6 +882,10 @@
|
|
754 |
|
755 |
const rocketModel = document.getElementById('rocket-model');
|
756 |
const rocketDisplay = document.getElementById('rocket-display');
|
|
|
|
|
|
|
|
|
757 |
const countdownElement = document.getElementById('countdown');
|
758 |
const stageSeparation = document.getElementById('stage-separation');
|
759 |
const successMarker = document.getElementById('success-marker');
|
@@ -761,6 +893,14 @@
|
|
761 |
const launchButton = document.getElementById('launch-button');
|
762 |
const missionName = document.getElementById('mission-name').value || `Mission ${Math.floor(Math.random() * 1000)}`;
|
763 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
764 |
// Disable launch button during launch
|
765 |
launchButton.disabled = true;
|
766 |
launchButton.classList.remove('bg-green-600', 'hover:bg-green-700');
|
@@ -774,6 +914,7 @@
|
|
774 |
// Reset rocket position
|
775 |
rocketModel.style.bottom = '0';
|
776 |
rocketModel.style.transform = 'translateX(-50%)';
|
|
|
777 |
|
778 |
// Play launch sound
|
779 |
playSound('launch');
|
@@ -832,93 +973,117 @@
|
|
832 |
rocketModel.classList.add('rocket-ascent');
|
833 |
rocketModel.classList.remove('launch-shake');
|
834 |
|
835 |
-
//
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
//
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
|
|
|
|
|
|
|
|
847 |
setTimeout(() => {
|
848 |
-
|
849 |
-
|
|
|
|
|
|
|
850 |
|
851 |
setTimeout(() => {
|
852 |
-
|
|
|
853 |
|
854 |
setTimeout(() => {
|
855 |
-
updateConsole(
|
856 |
|
857 |
-
// Show
|
858 |
-
|
859 |
-
|
860 |
|
861 |
-
//
|
862 |
-
|
863 |
-
|
|
|
|
|
|
|
|
|
864 |
|
865 |
setTimeout(() => {
|
866 |
-
updateConsole(`>
|
867 |
-
|
868 |
-
|
|
|
|
|
869 |
|
870 |
-
//
|
871 |
-
gameState.
|
872 |
-
gameState.
|
873 |
|
874 |
-
|
875 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
876 |
}, 2000);
|
877 |
}, 2000);
|
878 |
-
},
|
879 |
-
},
|
880 |
-
}
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
const failureReason = getRandomFailureReason();
|
885 |
-
|
886 |
-
setTimeout(() => {
|
887 |
-
// Show explosion
|
888 |
-
explosion.style.left = rocketModel.style.left;
|
889 |
-
explosion.style.top = rocketModel.style.top;
|
890 |
-
explosion.classList.add('explode');
|
891 |
-
playSound('explosion');
|
892 |
-
|
893 |
-
// Hide rocket
|
894 |
-
rocketModel.style.opacity = '0';
|
895 |
-
|
896 |
-
updateConsole(`> WARNING: ${failureReason}`);
|
897 |
-
updateConsole("> Attempting to mitigate...");
|
898 |
|
899 |
setTimeout(() => {
|
900 |
-
|
901 |
-
|
|
|
|
|
|
|
902 |
|
903 |
-
//
|
904 |
-
|
905 |
-
|
|
|
|
|
906 |
|
907 |
setTimeout(() => {
|
908 |
-
updateConsole(
|
909 |
-
updateConsole(
|
910 |
-
updateConsole("> Preparing for next attempt");
|
911 |
|
912 |
-
//
|
913 |
-
|
914 |
-
|
915 |
|
916 |
-
|
917 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
918 |
}, 2000);
|
919 |
-
},
|
920 |
-
}
|
921 |
-
}
|
922 |
}, 1000);
|
923 |
}
|
924 |
}
|
@@ -1001,6 +1166,10 @@
|
|
1001 |
// Reset after launch
|
1002 |
function resetAfterLaunch() {
|
1003 |
const rocketModel = document.getElementById('rocket-model');
|
|
|
|
|
|
|
|
|
1004 |
const launchButton = document.getElementById('launch-button');
|
1005 |
const explosion = document.getElementById('explosion');
|
1006 |
const successMarker = document.getElementById('success-marker');
|
@@ -1014,6 +1183,12 @@
|
|
1014 |
stageSeparation.classList.remove('separate');
|
1015 |
countdownElement.classList.remove('countdown-animate');
|
1016 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1017 |
// Reset rocket position and visibility
|
1018 |
rocketModel.style.bottom = '0';
|
1019 |
rocketModel.style.transform = 'translateX(-50%)';
|
|
|
56 |
position: relative;
|
57 |
height: 400px;
|
58 |
overflow: hidden;
|
59 |
+
background: linear-gradient(to bottom, #000000 0%, #000428 100%);
|
60 |
+
}
|
61 |
+
|
62 |
+
.space-view {
|
63 |
+
position: absolute;
|
64 |
+
top: 0;
|
65 |
+
left: 0;
|
66 |
+
width: 100%;
|
67 |
+
height: 100%;
|
68 |
+
background: url('https://images.unsplash.com/photo-1506318137071-a8e06380a023?q=80&w=3000') no-repeat center center;
|
69 |
+
background-size: cover;
|
70 |
+
opacity: 0;
|
71 |
+
transition: opacity 1s ease;
|
72 |
+
}
|
73 |
+
|
74 |
+
.space-view.active {
|
75 |
+
opacity: 1;
|
76 |
+
}
|
77 |
+
|
78 |
+
.planet-arrival {
|
79 |
+
position: absolute;
|
80 |
+
top: 50%;
|
81 |
+
left: 50%;
|
82 |
+
transform: translate(-50%, -50%);
|
83 |
+
width: 200px;
|
84 |
+
height: 200px;
|
85 |
+
border-radius: 50%;
|
86 |
+
background-size: cover;
|
87 |
+
background-position: center;
|
88 |
+
box-shadow: 0 0 50px rgba(255, 255, 255, 0.5);
|
89 |
+
opacity: 0;
|
90 |
+
transition: all 1s ease;
|
91 |
+
z-index: 15;
|
92 |
+
}
|
93 |
+
|
94 |
+
.planet-arrival.active {
|
95 |
+
opacity: 1;
|
96 |
+
transform: translate(-50%, -50%) scale(1.5);
|
97 |
}
|
98 |
|
99 |
.rocket-3d {
|
|
|
103 |
bottom: 0;
|
104 |
left: 50%;
|
105 |
transform: translateX(-50%);
|
106 |
+
z-index: 10;
|
107 |
}
|
108 |
|
109 |
.flame {
|
|
|
189 |
100% { opacity: 1; }
|
190 |
}
|
191 |
|
192 |
+
/* Launch effects */
|
193 |
.launch-smoke {
|
194 |
position: absolute;
|
195 |
bottom: 0;
|
|
|
201 |
border-radius: 50%;
|
202 |
filter: blur(10px);
|
203 |
opacity: 0;
|
204 |
+
z-index: 5;
|
205 |
}
|
206 |
|
207 |
.launching .launch-smoke {
|
|
|
314 |
justify-content: center;
|
315 |
opacity: 0;
|
316 |
transform: scale(0);
|
317 |
+
z-index: 25;
|
318 |
}
|
319 |
|
320 |
.success-animate {
|
|
|
326 |
50% { transform: scale(1.2); opacity: 1; }
|
327 |
100% { transform: scale(1); opacity: 1; }
|
328 |
}
|
329 |
+
|
330 |
+
.rocket-component {
|
331 |
+
width: 100%;
|
332 |
+
height: 100%;
|
333 |
+
background-size: contain;
|
334 |
+
background-repeat: no-repeat;
|
335 |
+
background-position: center;
|
336 |
+
}
|
337 |
+
|
338 |
+
.rocket-in-space {
|
339 |
+
position: absolute;
|
340 |
+
width: 100px;
|
341 |
+
height: 200px;
|
342 |
+
background-size: contain;
|
343 |
+
background-repeat: no-repeat;
|
344 |
+
background-position: center;
|
345 |
+
opacity: 0;
|
346 |
+
transition: all 1s ease;
|
347 |
+
z-index: 15;
|
348 |
+
}
|
349 |
+
|
350 |
+
.rocket-in-space.active {
|
351 |
+
opacity: 1;
|
352 |
+
}
|
353 |
+
|
354 |
+
.arrival-message {
|
355 |
+
position: absolute;
|
356 |
+
top: 70%;
|
357 |
+
left: 50%;
|
358 |
+
transform: translate(-50%, -50%);
|
359 |
+
background: rgba(0, 0, 0, 0.7);
|
360 |
+
padding: 20px;
|
361 |
+
border-radius: 10px;
|
362 |
+
text-align: center;
|
363 |
+
opacity: 0;
|
364 |
+
transition: opacity 1s ease;
|
365 |
+
z-index: 30;
|
366 |
+
width: 80%;
|
367 |
+
max-width: 500px;
|
368 |
+
}
|
369 |
+
|
370 |
+
.arrival-message.active {
|
371 |
+
opacity: 1;
|
372 |
+
}
|
373 |
</style>
|
374 |
</head>
|
375 |
<body>
|
|
|
388 |
<div class="flex items-center space-x-4">
|
389 |
<div class="hidden md:flex items-center space-x-2">
|
390 |
<i class="fas fa-coins text-yellow-400"></i>
|
391 |
+
<span class="font-bold" id="funds">$100,000,000</span>
|
392 |
</div>
|
393 |
<div class="hidden md:flex items-center space-x-2">
|
394 |
<i class="fas fa-star text-blue-400"></i>
|
|
|
410 |
<div class="bg-gray-900 rounded-xl p-6 shadow-xl border border-gray-800">
|
411 |
<h2 class="orbitron text-xl text-blue-400 mb-4">ROCKET DESIGN</h2>
|
412 |
<div class="rocket-display flex justify-center items-end" id="rocket-display">
|
413 |
+
<div class="space-view" id="space-view"></div>
|
414 |
+
<div class="planet-arrival" id="planet-arrival"></div>
|
415 |
+
<div class="rocket-in-space" id="rocket-in-space"></div>
|
416 |
+
<div class="arrival-message" id="arrival-message"></div>
|
417 |
<div class="rocket-3d" id="rocket-model">
|
|
|
418 |
<div class="flame" id="rocket-flame"></div>
|
419 |
<div class="launch-smoke"></div>
|
420 |
</div>
|
|
|
565 |
}
|
566 |
}
|
567 |
|
568 |
+
// Rocket parts data with actual images
|
569 |
const rocketParts = {
|
570 |
firstStages: [
|
571 |
+
{ id: 'falcon9', name: 'Falcon 9', cost: 5000000, mass: 25000, thrust: 7607, height: 10,
|
572 |
+
color: 'bg-white', image: 'https://www.spacex.com/static/images/falcon9/falcon9-1.png' },
|
573 |
+
{ id: 'falcon-heavy', name: 'Falcon Heavy', cost: 9000000, mass: 40000, thrust: 22819, height: 12,
|
574 |
+
color: 'bg-gray-300', image: 'https://www.spacex.com/static/images/falcon-heavy/falcon-heavy-1.png' },
|
575 |
+
{ id: 'starship', name: 'Starship', cost: 15000000, mass: 120000, thrust: 75000, height: 18,
|
576 |
+
color: 'bg-gray-400', image: 'https://www.spacex.com/static/images/starship/starship-1.png' },
|
577 |
+
{ id: 'nova', name: 'Nova', cost: 20000000, mass: 150000, thrust: 100000, height: 20,
|
578 |
+
color: 'bg-blue-200', image: 'https://www.nasa.gov/wp-content/uploads/2023/06/sls_artistconcept_0.jpg?w=1536' }
|
579 |
],
|
580 |
secondStages: [
|
581 |
+
{ id: 'falcon9-upper', name: 'Falcon 9 Upper', cost: 2000000, mass: 5000, thrust: 934, height: 6,
|
582 |
+
color: 'bg-white', image: 'https://www.spacex.com/static/images/falcon9/falcon9-upper-stage.png' },
|
583 |
+
{ id: 'falcon-heavy-upper', name: 'Falcon Heavy Upper', cost: 3000000, mass: 8000, thrust: 934, height: 8,
|
584 |
+
color: 'bg-gray-300', image: 'https://www.spacex.com/static/images/falcon-heavy/falcon-heavy-upper-stage.png' },
|
585 |
+
{ id: 'starship-upper', name: 'Starship Upper', cost: 5000000, mass: 15000, thrust: 3000, height: 12,
|
586 |
+
color: 'bg-gray-400', image: 'https://www.spacex.com/static/images/starship/starship-upper-stage.png' },
|
587 |
+
{ id: 'nova-upper', name: 'Nova Upper', cost: 7000000, mass: 20000, thrust: 5000, height: 14,
|
588 |
+
color: 'bg-blue-200', image: 'https://www.nasa.gov/wp-content/uploads/2023/06/sls_upperstage_0.jpg?w=1536' }
|
589 |
],
|
590 |
fairings: [
|
591 |
+
{ id: 'standard', name: 'Standard Fairing', cost: 1000000, mass: 2000, height: 5,
|
592 |
+
color: 'bg-white', image: 'https://www.spacex.com/static/images/falcon9/fairing.png' },
|
593 |
+
{ id: 'extended', name: 'Extended Fairing', cost: 1500000, mass: 3000, height: 7,
|
594 |
+
color: 'bg-gray-300', image: 'https://www.spacex.com/static/images/falcon-heavy/extended-fairing.png' },
|
595 |
+
{ id: 'heavy', name: 'Heavy Fairing', cost: 2000000, mass: 4000, height: 8,
|
596 |
+
color: 'bg-gray-400', image: 'https://www.spacex.com/static/images/starship/heavy-fairing.png' },
|
597 |
+
{ id: 'none', name: 'No Fairing', cost: 0, mass: 0, height: 0,
|
598 |
+
color: 'transparent', image: '' }
|
599 |
],
|
600 |
engines: [
|
601 |
+
{ id: 'merlin', name: 'Merlin', cost: 1000000, thrust: 845, isp: 282,
|
602 |
+
color: 'bg-gray-500', image: 'https://www.spacex.com/static/images/falcon9/merlin-engine.png' },
|
603 |
+
{ id: 'raptor', name: 'Raptor', cost: 2000000, thrust: 2000, isp: 330,
|
604 |
+
color: 'bg-gray-600', image: 'https://www.spacex.com/static/images/starship/raptor-engine.png' },
|
605 |
+
{ id: 'be-4', name: 'BE-4', cost: 2500000, thrust: 2400, isp: 340,
|
606 |
+
color: 'bg-blue-600', image: 'https://www.blueorigin.com/assets/engines/be4/be4-engine.jpg' },
|
607 |
+
{ id: 'rs-25', name: 'RS-25', cost: 3000000, thrust: 1860, isp: 366,
|
608 |
+
color: 'bg-red-600', image: 'https://www.nasa.gov/wp-content/uploads/2023/06/rs25-engine.jpg?w=1536' }
|
609 |
]
|
610 |
};
|
611 |
|
612 |
+
// Planets data with actual images
|
613 |
const destinations = [
|
614 |
+
{ id: 'leo', name: 'Low Earth Orbit', distance: 200, difficulty: 1,
|
615 |
+
image: 'https://science.nasa.gov/wp-content/uploads/2023/09/iss067e092866_large.jpg?w=1536',
|
616 |
+
arrivalImage: 'https://science.nasa.gov/wp-content/uploads/2023/09/earth-from-space.jpg?w=1536' },
|
617 |
+
{ id: 'moon', name: 'The Moon', distance: 384400, difficulty: 2,
|
618 |
+
image: 'https://science.nasa.gov/wp-content/uploads/2023/09/webb-southern-ring-nebula-1.jpg?w=1536',
|
619 |
+
arrivalImage: 'https://science.nasa.gov/wp-content/uploads/2023/09/moon-surface.jpg?w=1536' },
|
620 |
+
{ id: 'mars', name: 'Mars', distance: 225000000, difficulty: 3,
|
621 |
+
image: 'https://science.nasa.gov/wp-content/uploads/2023/09/pia25980-16.jpg?w=1536',
|
622 |
+
arrivalImage: 'https://science.nasa.gov/wp-content/uploads/2023/09/mars-surface.jpg?w=1536' },
|
623 |
+
{ id: 'jupiter', name: 'Jupiter', distance: 778000000, difficulty: 4,
|
624 |
+
image: 'https://science.nasa.gov/wp-content/uploads/2023/09/jupiter-1.jpg?w=1536',
|
625 |
+
arrivalImage: 'https://science.nasa.gov/wp-content/uploads/2023/09/jupiter-closeup.jpg?w=1536' },
|
626 |
+
{ id: 'saturn', name: 'Saturn', distance: 1400000000, difficulty: 5,
|
627 |
+
image: 'https://science.nasa.gov/wp-content/uploads/2023/09/saturn-1.jpg?w=1536',
|
628 |
+
arrivalImage: 'https://science.nasa.gov/wp-content/uploads/2023/09/saturn-rings.jpg?w=1536' },
|
629 |
+
{ id: 'pluto', name: 'Pluto', distance: 5900000000, difficulty: 6,
|
630 |
+
image: 'https://science.nasa.gov/wp-content/uploads/2023/09/pluto-1.jpg?w=1536',
|
631 |
+
arrivalImage: 'https://science.nasa.gov/wp-content/uploads/2023/09/pluto-surface.jpg?w=1536' }
|
632 |
];
|
633 |
|
634 |
// Game state
|
635 |
let gameState = {
|
636 |
+
funds: 100000000, // $100,000,000 initial balance
|
637 |
reputation: 100,
|
638 |
currentRocket: {
|
639 |
firstStage: null,
|
|
|
698 |
partElement.dataset.partType = partType;
|
699 |
|
700 |
partElement.innerHTML = `
|
701 |
+
<div class="w-16 h-16 rounded-full mb-2 flex items-center justify-center">
|
702 |
${part.image ? `<img src="${part.image}" alt="${part.name}" class="w-full h-full object-contain">` : '<i class="fas fa-rocket text-xl"></i>'}
|
703 |
</div>
|
704 |
<h3 class="font-bold text-center">${part.name}</h3>
|
|
|
785 |
// Add parts to the rocket model
|
786 |
if (gameState.currentRocket.firstStage) {
|
787 |
const firstStage = document.createElement('div');
|
788 |
+
firstStage.className = `first-stage w-16 mx-auto`;
|
789 |
firstStage.style.height = `${gameState.currentRocket.firstStage.height * 10}px`;
|
790 |
+
firstStage.style.backgroundImage = `url(${gameState.currentRocket.firstStage.image})`;
|
791 |
+
firstStage.style.backgroundSize = 'contain';
|
792 |
+
firstStage.style.backgroundRepeat = 'no-repeat';
|
793 |
+
firstStage.style.backgroundPosition = 'center';
|
794 |
rocketModel.appendChild(firstStage);
|
795 |
}
|
796 |
|
797 |
if (gameState.currentRocket.secondStage) {
|
798 |
const secondStage = document.createElement('div');
|
799 |
+
secondStage.className = `second-stage w-12 mx-auto`;
|
800 |
secondStage.style.height = `${gameState.currentRocket.secondStage.height * 10}px`;
|
801 |
+
secondStage.style.backgroundImage = `url(${gameState.currentRocket.secondStage.image})`;
|
802 |
+
secondStage.style.backgroundSize = 'contain';
|
803 |
+
secondStage.style.backgroundRepeat = 'no-repeat';
|
804 |
+
secondStage.style.backgroundPosition = 'center';
|
805 |
rocketModel.appendChild(secondStage);
|
806 |
}
|
807 |
|
808 |
if (gameState.currentRocket.fairing && gameState.currentRocket.fairing.id !== 'none') {
|
809 |
const fairing = document.createElement('div');
|
810 |
+
fairing.className = `fairing w-16 mx-auto rounded-t-lg`;
|
811 |
fairing.style.height = `${gameState.currentRocket.fairing.height * 10}px`;
|
812 |
+
fairing.style.backgroundImage = `url(${gameState.currentRocket.fairing.image})`;
|
813 |
+
fairing.style.backgroundSize = 'contain';
|
814 |
+
fairing.style.backgroundRepeat = 'no-repeat';
|
815 |
+
fairing.style.backgroundPosition = 'center';
|
816 |
rocketModel.appendChild(fairing);
|
817 |
}
|
818 |
}
|
|
|
882 |
|
883 |
const rocketModel = document.getElementById('rocket-model');
|
884 |
const rocketDisplay = document.getElementById('rocket-display');
|
885 |
+
const spaceView = document.getElementById('space-view');
|
886 |
+
const planetArrival = document.getElementById('planet-arrival');
|
887 |
+
const rocketInSpace = document.getElementById('rocket-in-space');
|
888 |
+
const arrivalMessage = document.getElementById('arrival-message');
|
889 |
const countdownElement = document.getElementById('countdown');
|
890 |
const stageSeparation = document.getElementById('stage-separation');
|
891 |
const successMarker = document.getElementById('success-marker');
|
|
|
893 |
const launchButton = document.getElementById('launch-button');
|
894 |
const missionName = document.getElementById('mission-name').value || `Mission ${Math.floor(Math.random() * 1000)}`;
|
895 |
|
896 |
+
// Reset space view elements
|
897 |
+
spaceView.classList.remove('active');
|
898 |
+
planetArrival.classList.remove('active');
|
899 |
+
rocketInSpace.classList.remove('active');
|
900 |
+
arrivalMessage.classList.remove('active');
|
901 |
+
planetArrival.style.backgroundImage = '';
|
902 |
+
rocketInSpace.style.backgroundImage = '';
|
903 |
+
|
904 |
// Disable launch button during launch
|
905 |
launchButton.disabled = true;
|
906 |
launchButton.classList.remove('bg-green-600', 'hover:bg-green-700');
|
|
|
914 |
// Reset rocket position
|
915 |
rocketModel.style.bottom = '0';
|
916 |
rocketModel.style.transform = 'translateX(-50%)';
|
917 |
+
rocketModel.style.opacity = '1';
|
918 |
|
919 |
// Play launch sound
|
920 |
playSound('launch');
|
|
|
973 |
rocketModel.classList.add('rocket-ascent');
|
974 |
rocketModel.classList.remove('launch-shake');
|
975 |
|
976 |
+
// Show space view after rocket leaves the screen
|
977 |
+
setTimeout(() => {
|
978 |
+
spaceView.classList.add('active');
|
979 |
+
|
980 |
+
// Show rocket in space
|
981 |
+
rocketInSpace.style.backgroundImage = `url(${gameState.currentRocket.firstStage.image})`;
|
982 |
+
rocketInSpace.style.left = '50%';
|
983 |
+
rocketInSpace.style.top = '50%';
|
984 |
+
rocketInSpace.style.transform = 'translate(-50%, -50%)';
|
985 |
+
rocketInSpace.classList.add('active');
|
986 |
+
|
987 |
+
// Random mission outcome
|
988 |
+
const isSuccess = Math.random() < successChance;
|
989 |
+
|
990 |
+
if (isSuccess) {
|
991 |
+
// Successful mission
|
992 |
setTimeout(() => {
|
993 |
+
updateConsole("> First stage separation successful");
|
994 |
+
|
995 |
+
// Show stage separation effect
|
996 |
+
stageSeparation.classList.add('separate');
|
997 |
+
playSound('separation');
|
998 |
|
999 |
setTimeout(() => {
|
1000 |
+
stageSeparation.classList.remove('separate');
|
1001 |
+
updateConsole("> Second stage ignition");
|
1002 |
|
1003 |
setTimeout(() => {
|
1004 |
+
updateConsole("> Payload deployment confirmed");
|
1005 |
|
1006 |
+
// Show destination planet
|
1007 |
+
planetArrival.style.backgroundImage = `url(${gameState.currentDestination.arrivalImage})`;
|
1008 |
+
planetArrival.classList.add('active');
|
1009 |
|
1010 |
+
// Show arrival message
|
1011 |
+
arrivalMessage.innerHTML = `
|
1012 |
+
<h3 class="orbitron text-xl text-green-400 mb-2">MISSION SUCCESS</h3>
|
1013 |
+
<p>${missionName} has successfully reached ${gameState.currentDestination.name}!</p>
|
1014 |
+
<p class="mt-2 text-sm">Payload delivered: ${gameState.currentPayload.type}</p>
|
1015 |
+
`;
|
1016 |
+
arrivalMessage.classList.add('active');
|
1017 |
|
1018 |
setTimeout(() => {
|
1019 |
+
updateConsole(`> Mission to ${gameState.currentDestination.name} successful!`);
|
1020 |
+
|
1021 |
+
// Show success marker
|
1022 |
+
successMarker.classList.add('success-animate');
|
1023 |
+
playSound('success');
|
1024 |
|
1025 |
+
// Calculate rewards
|
1026 |
+
const reputationGain = gameState.currentDestination.difficulty * 10;
|
1027 |
+
const financialReward = gameState.currentDestination.difficulty * 500000;
|
1028 |
|
1029 |
+
setTimeout(() => {
|
1030 |
+
updateConsole(`> Reputation increased by ${reputationGain}`);
|
1031 |
+
updateConsole(`> Financial reward: $${financialReward.toLocaleString()}`);
|
1032 |
+
updateConsole("> Ready for next mission");
|
1033 |
+
|
1034 |
+
// Update game state
|
1035 |
+
gameState.reputation += reputationGain;
|
1036 |
+
gameState.funds += financialReward - missionCost;
|
1037 |
+
|
1038 |
+
// Reset for next launch
|
1039 |
+
resetAfterLaunch();
|
1040 |
+
}, 2000);
|
1041 |
}, 2000);
|
1042 |
}, 2000);
|
1043 |
+
}, 1000);
|
1044 |
+
}, 3000);
|
1045 |
+
} else {
|
1046 |
+
// Failed mission
|
1047 |
+
const failureTime = 2000 + Math.random() * 3000;
|
1048 |
+
const failureReason = getRandomFailureReason();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1049 |
|
1050 |
setTimeout(() => {
|
1051 |
+
// Show explosion
|
1052 |
+
explosion.style.left = rocketInSpace.style.left;
|
1053 |
+
explosion.style.top = rocketInSpace.style.top;
|
1054 |
+
explosion.classList.add('explode');
|
1055 |
+
playSound('explosion');
|
1056 |
|
1057 |
+
// Hide rocket
|
1058 |
+
rocketInSpace.style.opacity = '0';
|
1059 |
+
|
1060 |
+
updateConsole(`> WARNING: ${failureReason}`);
|
1061 |
+
updateConsole("> Attempting to mitigate...");
|
1062 |
|
1063 |
setTimeout(() => {
|
1064 |
+
updateConsole("> Mission failure confirmed");
|
1065 |
+
updateConsole("> Investigating root cause");
|
|
|
1066 |
|
1067 |
+
// Calculate penalties
|
1068 |
+
const reputationLoss = gameState.currentDestination.difficulty * 5;
|
1069 |
+
const financialLoss = missionCost * 0.5;
|
1070 |
|
1071 |
+
setTimeout(() => {
|
1072 |
+
updateConsole(`> Reputation decreased by ${reputationLoss}`);
|
1073 |
+
updateConsole(`> Financial loss: $${financialLoss.toLocaleString()}`);
|
1074 |
+
updateConsole("> Preparing for next attempt");
|
1075 |
+
|
1076 |
+
// Update game state
|
1077 |
+
gameState.reputation = Math.max(0, gameState.reputation - reputationLoss);
|
1078 |
+
gameState.funds -= financialLoss;
|
1079 |
+
|
1080 |
+
// Reset for next launch
|
1081 |
+
resetAfterLaunch();
|
1082 |
+
}, 2000);
|
1083 |
}, 2000);
|
1084 |
+
}, failureTime);
|
1085 |
+
}
|
1086 |
+
}, 3000);
|
1087 |
}, 1000);
|
1088 |
}
|
1089 |
}
|
|
|
1166 |
// Reset after launch
|
1167 |
function resetAfterLaunch() {
|
1168 |
const rocketModel = document.getElementById('rocket-model');
|
1169 |
+
const spaceView = document.getElementById('space-view');
|
1170 |
+
const planetArrival = document.getElementById('planet-arrival');
|
1171 |
+
const rocketInSpace = document.getElementById('rocket-in-space');
|
1172 |
+
const arrivalMessage = document.getElementById('arrival-message');
|
1173 |
const launchButton = document.getElementById('launch-button');
|
1174 |
const explosion = document.getElementById('explosion');
|
1175 |
const successMarker = document.getElementById('success-marker');
|
|
|
1183 |
stageSeparation.classList.remove('separate');
|
1184 |
countdownElement.classList.remove('countdown-animate');
|
1185 |
|
1186 |
+
// Reset space view elements
|
1187 |
+
spaceView.classList.remove('active');
|
1188 |
+
planetArrival.classList.remove('active');
|
1189 |
+
rocketInSpace.classList.remove('active');
|
1190 |
+
arrivalMessage.classList.remove('active');
|
1191 |
+
|
1192 |
// Reset rocket position and visibility
|
1193 |
rocketModel.style.bottom = '0';
|
1194 |
rocketModel.style.transform = 'translateX(-50%)';
|