Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Nexus Protocol - Sci-Fi RPG</title> | |
<style> | |
/* Inlined Tailwind CSS */ | |
:root { | |
--primary: #0a192f; | |
--secondary: #172a45; | |
--accent: #64ffda; | |
--dark: #020c1b; | |
--light: #ccd6f6; | |
--highlight: #1e90ff; | |
} | |
* { | |
box-sizing: border-box; | |
margin: 0; | |
padding: 0; | |
} | |
body { | |
font-family: 'Roboto', sans-serif; | |
background-color: var(--dark); | |
color: var(--light); | |
height: 100vh; | |
width: 100vw; | |
overflow: hidden; | |
} | |
.absolute { | |
position: absolute; | |
} | |
.relative { | |
position: relative; | |
} | |
.fixed { | |
position: fixed; | |
} | |
.inset-0 { | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
} | |
.top-0 { | |
top: 0; | |
} | |
.right-0 { | |
right: 0; | |
} | |
.bottom-0 { | |
bottom: 0; | |
} | |
.left-0 { | |
left: 0; | |
} | |
.flex { | |
display: flex; | |
} | |
.hidden { | |
display: none; | |
} | |
.items-center { | |
align-items: center; | |
} | |
.justify-center { | |
justify-content: center; | |
} | |
.justify-between { | |
justify-content: space-between; | |
} | |
.flex-col { | |
flex-direction: column; | |
} | |
.flex-1 { | |
flex: 1 1 0%; | |
} | |
.w-full { | |
width: 100%; | |
} | |
.h-full { | |
height: 100%; | |
} | |
.w-16 { | |
width: 4rem; | |
} | |
.h-16 { | |
height: 4rem; | |
} | |
.w-10 { | |
width: 2.5rem; | |
} | |
.h-10 { | |
height: 2.5rem; | |
} | |
.w-12 { | |
width: 3rem; | |
} | |
.h-12 { | |
height: 3rem; | |
} | |
.rounded-full { | |
border-radius: 9999px; | |
} | |
.rounded-lg { | |
border-radius: 0.5rem; | |
} | |
.rounded-md { | |
border-radius: 0.375rem; | |
} | |
.overflow-hidden { | |
overflow: hidden; | |
} | |
.overflow-y-auto { | |
overflow-y: auto; | |
} | |
.bg-black { | |
background-color: #000; | |
} | |
.bg-gray-900 { | |
background-color: #111827; | |
} | |
.bg-blue-900 { | |
background-color: #1e3a8a; | |
} | |
.bg-opacity-40 { | |
opacity: 0.4; | |
} | |
.bg-opacity-80 { | |
opacity: 0.8; | |
} | |
.bg-opacity-90 { | |
opacity: 0.9; | |
} | |
.border-2 { | |
border-width: 2px; | |
} | |
.border-blue-500 { | |
border-color: #3b82f6; | |
} | |
.border-transparent { | |
border-color: transparent; | |
} | |
.text-center { | |
text-align: center; | |
} | |
.text-xs { | |
font-size: 0.75rem; | |
line-height: 1rem; | |
} | |
.text-sm { | |
font-size: 0.875rem; | |
line-height: 1.25rem; | |
} | |
.text-lg { | |
font-size: 1.125rem; | |
line-height: 1.75rem; | |
} | |
.text-xl { | |
font-size: 1.25rem; | |
line-height: 1.75rem; | |
} | |
.text-blue-400 { | |
color: #60a5fa; | |
} | |
.text-gray-300 { | |
color: #d1d5db; | |
} | |
.text-gray-400 { | |
color: #9ca3af; | |
} | |
.font-bold { | |
font-weight: 700; | |
} | |
.leading-relaxed { | |
line-height: 1.625; | |
} | |
.px-4 { | |
padding-left: 1rem; | |
padding-right: 1rem; | |
} | |
.py-2 { | |
padding-top: 0.5rem; | |
padding-bottom: 0.5rem; | |
} | |
.px-3 { | |
padding-left: 0.75rem; | |
padding-right: 0.75rem; | |
} | |
.py-1 { | |
padding-top: 0.25rem; | |
padding-bottom: 0.25rem; | |
} | |
.mb-1 { | |
margin-bottom: 0.25rem; | |
} | |
.mb-2 { | |
margin-bottom: 0.5rem; | |
} | |
.mb-4 { | |
margin-bottom: 1rem; | |
} | |
.mt-1 { | |
margin-top: 0.25rem; | |
} | |
.mt-2 { | |
margin-top: 0.5rem; | |
} | |
.mt-4 { | |
margin-top: 1rem; | |
} | |
.mr-2 { | |
margin-right: 0.5rem; | |
} | |
.mr-3 { | |
margin-right: 0.75rem; | |
} | |
.space-x-1 > * + * { | |
margin-left: 0.25rem; | |
} | |
.space-x-2 > * + * { | |
margin-left: 0.5rem; | |
} | |
.space-x-3 > * + * { | |
margin-left: 0.75rem; | |
} | |
.space-x-4 > * + * { | |
margin-left: 1rem; | |
} | |
.space-y-1 > * + * { | |
margin-top: 0.25rem; | |
} | |
.space-y-2 > * + * { | |
margin-top: 0.5rem; | |
} | |
.grid { | |
display: grid; | |
} | |
.grid-cols-1 { | |
grid-template-columns: repeat(1, minmax(0, 1fr)); | |
} | |
.grid-cols-2 { | |
grid-template-columns: repeat(2, minmax(0, 1fr)); | |
} | |
.grid-cols-4 { | |
grid-template-columns: repeat(4, minmax(0, 1fr)); | |
} | |
.gap-2 { | |
gap: 0.5rem; | |
} | |
.gap-3 { | |
gap: 0.75rem; | |
} | |
.cursor-pointer { | |
cursor: pointer; | |
} | |
.pointer-events-none { | |
pointer-events: none; | |
} | |
.object-cover { | |
object-fit: cover; | |
} | |
.z-20 { | |
z-index: 20; | |
} | |
.z-30 { | |
z-index: 30; | |
} | |
.z-50 { | |
z-index: 50; | |
} | |
.transform { | |
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y)); | |
} | |
.-translate-x-1\/2 { | |
--tw-translate-x: -50%; | |
} | |
.transition { | |
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter; | |
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |
transition-duration: 150ms; | |
} | |
.transition-all { | |
transition-property: all; | |
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); | |
transition-duration: 150ms; | |
} | |
.duration-300 { | |
transition-duration: 300ms; | |
} | |
.ease-in { | |
transition-timing-function: cubic-bezier(0.4, 0, 1, 1); | |
} | |
.ease-out { | |
transition-timing-function: cubic-bezier(0, 0, 0.2, 1); | |
} | |
.group:hover .group-hover\:opacity-100 { | |
opacity: 1; | |
} | |
.opacity-0 { | |
opacity: 0; | |
} | |
.opacity-50 { | |
opacity: 0.5; | |
} | |
.opacity-70 { | |
opacity: 0.7; | |
} | |
.opacity-100 { | |
opacity: 1; | |
} | |
.panel-hidden { | |
opacity: 0; | |
pointer-events: none;6 | |
} | |
.panel-visible { | |
opacity: 1; | |
pointer-events: auto; | |
} | |
/* Custom Fonts */ | |
@font-face { | |
font-family: 'Orbitron'; | |
font-style: normal; | |
font-weight: 400; | |
src: url(Orbitron400.woff2) format('woff2'); | |
} | |
@font-face { | |
font-family: 'Roboto'; | |
font-style: normal; | |
font-weight: 400; | |
src: url(Roboto400.woff2) format('woff2'); | |
} | |
.tech-font { | |
font-family: 'Orbitron', sans-serif; | |
} | |
/* Custom Components */ | |
.health-bar { | |
height: 6px; | |
background: linear-gradient(to right, #ff5555, #ff0000); | |
border-radius: 3px; | |
transition: width 0.3s ease; | |
} | |
.energy-bar { | |
height: 6px; | |
background: linear-gradient(to right, #64ffda, #1e90ff); | |
border-radius: 3px; | |
transition: width 0.3s ease; | |
} | |
.action-btn { | |
background: rgba(10, 25, 47, 0.8); | |
border: 1px solid var(--accent); | |
transition: all 0.2s ease; | |
color: var(--accent); | |
} | |
.action-btn:hover { | |
background: rgba(23, 42, 69, 0.8); | |
transform: translateY(-1px); | |
box-shadow: 0 2px 8px rgba(100, 255, 218, 0.3); | |
} | |
.character-card { | |
transition: all 0.3s ease; | |
border: 1px solid transparent; | |
} | |
.character-card:hover { | |
border-color: var(--accent); | |
transform: translateY(-5px); | |
} | |
.character-card.active { | |
border-color: var(--highlight); | |
box-shadow: 0 0 15px rgba(30, 144, 255, 0.5); | |
} | |
.node { | |
width: 12px; | |
height: 12px; | |
background-color: var(--accent); | |
border-radius: 50%; | |
position: absolute; | |
cursor: pointer; | |
transition: all 0.3s ease; | |
} | |
.node:hover { | |
transform: scale(1.5); | |
box-shadow: 0 0 10px var(--accent); | |
} | |
.node.visited { | |
background-color: var(--highlight); | |
} | |
.node.current { | |
transform: scale(1.8); | |
box-shadow: 0 0 15px var(--highlight); | |
} | |
.node.available { | |
animation: pulse 2s infinite; | |
} | |
@keyframes pulse { | |
0% { box-shadow: 0 0 0 0 rgba(100, 255, 218, 0.7); } | |
70% { box-shadow: 0 0 0 8px rgba(100, 255, 218, 0); } | |
100% { box-shadow: 0 0 0 0 rgba(100, 255, 218, 0); } | |
} | |
.fade-in { | |
animation: fadeIn 0.5s ease-in; | |
} | |
@keyframes fadeIn { | |
from { opacity: 0; } | |
to { opacity: 1; } | |
} | |
.damage-text { | |
position: absolute; | |
color: #ff5555; | |
font-weight: bold; | |
animation: floatUp 1s forwards; | |
pointer-events: none; | |
text-shadow: 1px 1px 2px black; | |
font-family: 'Orbitron', sans-serif; | |
} | |
@keyframes floatUp { | |
0% { transform: translateY(0); opacity: 1; } | |
100% { transform: translateY(-50px); opacity: 0; } | |
} | |
.ui-panel { | |
transition: all 0.4s cubic-bezier(0.22, 1, 0.36, 1); | |
} | |
.bottom-panel { | |
transform: translateY(100%); | |
} | |
.right-panel { | |
transform: translateX(100%); | |
} | |
.left-panel { | |
transform: translateX(-100%); | |
} | |
.panel-visible { | |
transform: translate(0); | |
} | |
.panel-hidden { | |
opacity: 0; | |
pointer-events: none; | |
} | |
.first-person-overlay { | |
position: absolute; | |
inset: 0; | |
pointer-events: none; | |
background: radial-gradient(circle at center, transparent 70%, rgba(2, 12, 27, 0.7) 100%); | |
z-index: 5; | |
} | |
.weapon-effect { | |
animation: weaponFire 0.3s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; | |
} | |
@keyframes weaponFire { | |
0% { opacity: 0; transform: scale(0.5); } | |
50% { opacity: 1; transform: scale(1.2); } | |
100% { opacity: 0; transform: scale(0.8); } | |
} | |
.dialog-box { | |
background: rgba(10, 25, 47, 0.9); | |
border: 1px solid var(--accent); | |
box-shadow: 0 0 20px rgba(100, 255, 218, 0.3); | |
} | |
.dialog-option:hover { | |
background: rgba(23, 42, 69, 0.7); | |
border-left: 3px solid var(--accent); | |
} | |
.character-avatar { | |
transition: all 0.3s ease; | |
border: 2px solid transparent; | |
} | |
.character-avatar:hover { | |
border-color: var(--accent); | |
transform: scale(1.05); | |
} | |
.character-avatar.active { | |
border-color: var(--highlight); | |
box-shadow: 0 0 15px rgba(30, 144, 255, 0.5); | |
} | |
.map-transition { | |
animation: mapFade 1s ease-in-out; | |
} | |
@keyframes mapFade { | |
0% { opacity: 0; transform: scale(0.9); } | |
100% { opacity: 1; transform: scale(1); } | |
} | |
.scene-transition { | |
animation: sceneFade 0.8s ease-in-out; | |
} | |
@keyframes sceneFade { | |
0% { opacity: 0; } | |
100% { opacity: 1; } | |
} | |
.notification { | |
animation: notificationPop 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55) both; | |
} | |
@keyframes notificationPop { | |
0% { transform: scale(0); opacity: 0; } | |
100% { transform: scale(1); opacity: 1; } | |
} | |
.fade-out { | |
animation: fadeOut 0.3s ease-out forwards; | |
} | |
@keyframes fadeOut { | |
to { opacity: 0; } | |
} | |
.hud-element { | |
background: rgba(10, 25, 47, 0.5); | |
border: 1px solid rgba(100, 255, 218, 0.3); | |
backdrop-filter: blur(5px); | |
} | |
.scene-container { | |
background-size: cover; | |
background-position: center; | |
transition: background-image 0.5s ease; | |
} | |
/* Font Awesome Icons */ | |
.fa, | |
.fas { | |
font-family: 'Font Awesome 6 Free'; | |
font-weight: 900; | |
} | |
.fa-map:before { | |
content: "\f279"; | |
} | |
.fa-cog:before { | |
content: "\f013"; | |
} | |
.fa-book:before { | |
content: "\f02d"; | |
} | |
.fa-shield-alt:before { | |
content: "\f3ed"; | |
} | |
.fa-bolt:before { | |
content: "\f0e7"; | |
} | |
.fa-microchip:before { | |
content: "\f2db"; | |
} | |
.fa-cogs:before { | |
content: "\f085"; | |
} | |
.fa-hourglass-end:before { | |
content: "\f253"; | |
} | |
.fa-flag:before { | |
content: "\f024"; | |
} | |
.fa-user-astronaut:before { | |
content: "\f4fb"; | |
} | |
.fa-comment:before { | |
content: "\f075"; | |
} | |
.fa-satellite-dish:before { | |
content: "\f7c0"; | |
} | |
.fa-times:before { | |
content: "\f00d"; | |
} | |
.fa-heartbeat:before { | |
content: "\f21e"; | |
} | |
.fa-atom:before { | |
content: "\f5d2"; | |
} | |
.fa-map-marked-alt:before { | |
content: "\f5a0"; | |
} | |
.fa-history:before { | |
content: "\f1da"; | |
} | |
.fa-lock:before { | |
content: "\f023"; | |
} | |
.fa-battery-half:before { | |
content: "\f242"; | |
} | |
</style> | |
</head> | |
<body class="relative h-full"> | |
<!-- Main Game View --> | |
<div id="gameView" class="absolute inset-0 overflow-hidden"> | |
<!-- Current Scene Background --> | |
<div id="sceneContainer" class="scene-container absolute inset-0 bg-gray-900 flex items-end justify-center scene-transition" style="background-image: url('https://i.imgur.com/Dw6qY7a.png')"> | |
<!-- Scene content will be dynamically loaded here --> | |
<!-- Characters in Scene (max 15) --> | |
<div id="sceneCharacters" class="absolute inset-0 pointer-events-none"> | |
<!-- Characters will be dynamically positioned here --> | |
</div> | |
<!-- First-Person Overlay Effect --> | |
<div class="first-person-overlay"></div> | |
<!-- Weapon Effects --> | |
<div id="weaponEffects" class="absolute inset-0 pointer-events-none"></div> | |
<!-- Damage Numbers --> | |
<div id="damageContainer" class="absolute inset-0 pointer-events-none"></div> | |
</div> | |
<!-- Player Status Bar (Minimal - expands on hover) --> | |
<div id="playerStatus" class="absolute bottom-0 left-0 right-0 h-16 bg-black bg-opacity-40 flex justify-center items-center transition-all duration-300 hover:h-24"> | |
<div class="flex items-center space-x-6 px-4"> | |
<!-- Avatar --> | |
<div class="character-avatar w-12 h-12 rounded-full bg-gray-800 border-2 border-blue-500 overflow-hidden"> | |
<img src="https://i.imgur.com/JQ9qy0E.png" alt="Player" class="w-full h-full object-cover"> | |
</div> | |
<!-- Health --> | |
<div class="w-32"> | |
<div class="flex justify-between text-xs mb-1"> | |
<span>INTEGRITY</span> | |
<span>85%</span> | |
</div> | |
<div class="health-bar" style="width: 85%"></div> | |
</div> | |
<!-- Energy --> | |
<div class="w-32"> | |
<div class="flex justify-between text-xs mb-1"> | |
<span>POWER</span> | |
<span>64%</span> | |
</div> | |
<div class="energy-bar" style="width: 64%"></div> | |
</div> | |
<!-- Quick Stats --> | |
<div class="hidden md:flex space-x-4 text-xs"> | |
<div class="text-center"> | |
<div class="tech-font text-blue-400">Lv.12</div> | |
<div>NEXUS</div> | |
</div> | |
<div class="text-center"> | |
<div class="tech-font text-green-400">24</div> | |
<div>ATK</div> | |
</div> | |
<div class="text-center"> | |
<div class="tech-font text-purple-400">18</div> | |
<div>DEF</div> | |
</div> | |
</div> | |
<!-- Expanded Info (shown on hover) --> | |
<div class="hidden md:flex items-center space-x-4 opacity-0 transition-opacity duration-300 group-hover:opacity-100"> | |
<div class="text-xs"> | |
<div class="flex items-center space-x-1"> | |
<i class="fas fa-shield-alt text-blue-400"></i> | |
<span>Shield: 85/100</span> | |
</div> | |
<div class="flex items-center space-x-1"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span>Energy: 32/50</span> | |
</div> | |
</div> | |
<div class="text-xs"> | |
<div class="flex items-center space-x-1"> | |
<i class="fas fa-microchip text-green-400"></i> | |
<span>RAM: 4/6</span> | |
</div> | |
<div class="flex items-center space-x-1"> | |
<i class="fas fa-cogs text-red-400"></i> | |
<span>Heat: 42°</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Player Team (Callable Cards) --> | |
<div id="teamPanel" class="absolute bottom-20 left-0 right-0 flex justify-center space-x-2 px-4"> | |
<!-- Team member cards (5 total) --> | |
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer active"> | |
<div class="h-12 bg-blue-900 flex items-center justify-center"> | |
<img src="https://i.imgur.com/3QZ2Q0X.png" alt="Teammate" class="w-full h-full object-cover"> | |
</div> | |
<div class="p-1"> | |
<div class="health-bar w-full mb-1" style="width: 80%"></div> | |
<p class="text-xs truncate text-center">Elandra</p> | |
</div> | |
</div> | |
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer"> | |
<div class="h-12 bg-purple-900 flex items-center justify-center"> | |
<img src="https://i.imgur.com/5t5wY9j.png" alt="Teammate" class="w-full h-full object-cover"> | |
</div> | |
<div class="p-1"> | |
<div class="health-bar w-full mb-1" style="width: 45%"></div> | |
<p class="text-xs truncate text-center">Thorgar</p> | |
</div> | |
</div> | |
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer"> | |
<div class="h-12 bg-green-900 flex items-center justify-center"> | |
<img src="https://i.imgur.com/7VvX7Qq.png" alt="Teammate" class="w-full h-full object-cover"> | |
</div> | |
<div class="p-1"> | |
<div class="energy-bar w-full mb-1" style="width: 30%"></div> | |
<p class="text-xs truncate text-center">Merlin</p> | |
</div> | |
</div> | |
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer"> | |
<div class="h-12 bg-red-900 flex items-center justify-center"> | |
<img src="https://i.imgur.com/9t5wY9j.png" alt="Teammate" class="w-full h-full object-cover"> | |
</div> | |
<div class="p-1"> | |
<div class="health-bar w-full mb-1" style="width: 90%"></div> | |
<p class="text-xs truncate text-center">Lydia</p> | |
</div> | |
</div> | |
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer"> | |
<div class="h-12 bg-yellow-900 flex items-center justify-center"> | |
<img src="https://i.imgur.com/JQ9qy0E.png" alt="Teammate" class="w-full h-full object-cover"> | |
</div> | |
<div class="p-1"> | |
<div class="health-bar w-full mb-1" style="width: 60%"></div> | |
<p class="text-xs truncate text-center">Rook</p> | |
</div> | |
</div> | |
</div> | |
<!-- Quick Access Menu (Top Right) --> | |
<div id="quickMenu" class="absolute top-4 right-4 flex space-x-2"> | |
<button class="hud-element w-10 h-10 rounded-full flex items-center justify-center text-blue-400 hover:text-blue-300"> | |
<i class="fas fa-map"></i> | |
</button> | |
<button class="hud-element w-10 h-10 rounded-full flex items-center justify-center text-green-400 hover:text-green-300"> | |
<i class="fas fa-cog"></i> | |
</button> | |
<button class="hud-element w-10 h-10 rounded-full flex items-center justify-center text-purple-400 hover:text-purple-300"> | |
<i class="fas fa-book"></i> | |
</button> | |
</div> | |
<!-- Round Indicator (Top Left) --> | |
<div id="roundIndicator" class="absolute top-4 left-4 hud-element px-3 py-1 rounded-full"> | |
<span class="tech-font text-blue-400">ROUND <span id="roundNumber">1</span></span> | |
</div> | |
<!-- Action Points (Top Center) --> | |
<div id="actionPointsDisplay" class="absolute top-4 left-1/2 transform -translate-x-1/2 hud-element px-4 py-1 rounded-full flex items-center space-x-2"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span class="tech-font">AP: <span id="apCount">4</span>/6</span> | |
</div> | |
</div> | |
<!-- World Map Panel (Hidden by default) --> | |
<div id="mapPanel" class="absolute inset-0 bg-black bg-opacity-90 z-20 flex items-center justify-center panel-hidden"> | |
<div class="relative w-full h-full max-w-4xl max-h-4xl"> | |
<button id="closeMap" class="absolute top-4 right-4 text-2xl text-blue-400 hover:text-blue-300 z-30"> | |
<i class="fas fa-times"></i> | |
</button> | |
<!-- Map Background --> | |
<div class="absolute inset-0 bg-gray-900 rounded-lg overflow-hidden"> | |
<!-- This would be your map background image --> | |
<div class="absolute inset-0 opacity-20" style="background-image: url('https://i.imgur.com/Dw6qY7a.png'); background-size: cover;"></div> | |
<!-- Node Connections --> | |
<svg id="mapConnections" class="absolute inset-0 w-full h-full" xmlns="http://www.w3.org/2000/svg"> | |
<!-- Connections between nodes will be drawn here --> | |
<line x1="20%" y1="30%" x2="35%" y2="45%" stroke="#64ffda" stroke-width="2" stroke-dasharray="5,3" /> | |
<line x1="35%" y1="45%" x2="50%" y2="40%" stroke="#64ffda" stroke-width="2" /> | |
<line x1="50%" y1="40%" x2="65%" y2="55%" stroke="#64ffda" stroke-width="2" /> | |
<line x1="65%" y1="55%" x2="80%" y2="50%" stroke="#64ffda" stroke-width="2" /> | |
</svg> | |
<!-- Map Nodes --> | |
<div class="node visited" style="top: 30%; left: 20%;" data-scene="start"></div> | |
<div class="node visited" style="top: 45%; left: 35%;" data-scene="hub1"></div> | |
<div class="node current" style="top: 40%; left: 50%;" data-scene="current"></div> | |
<div class="node available" style="top: 55%; left: 65%;" data-scene="lab"></div> | |
<div class="node" style="top: 50%; left: 80%;" data-scene="boss"></div> | |
</div> | |
<!-- Map Info Panel --> | |
<div class="absolute bottom-4 left-4 hud-element p-4 max-w-xs"> | |
<h3 class="tech-font text-xl text-blue-400 mb-2">SECTOR 7-GRID</h3> | |
<p class="text-sm">Current Location: Research Outpost</p> | |
<p class="text-sm mt-2">Available Paths:</p> | |
<ul class="text-xs space-y-1 mt-1"> | |
<li class="flex items-center"> | |
<div class="w-2 h-2 rounded-full bg-blue-500 mr-2"></div> | |
<span>Main Laboratory (1.2km)</span> | |
</li> | |
<li class="flex items-center opacity-50"> | |
<div class="w-2 h-2 rounded-full bg-gray-500 mr-2"></div> | |
<span>Command Center (Locked)</span> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
<!-- Dialog Panel (Hidden by default) --> | |
<div id="dialogPanel" class="absolute bottom-0 left-0 right-0 h-1/3 bg-black bg-opacity-80 z-20 panel-hidden"> | |
<div class="h-full flex flex-col"> | |
<!-- Speaker Info --> | |
<div class="flex items-center p-4 border-b border-blue-900"> | |
<div class="w-12 h-12 rounded-full bg-gray-800 overflow-hidden mr-3"> | |
<img src="https://i.imgur.com/3QZ2Q0X.png" alt="Speaker" class="w-full h-full object-cover"> | |
</div> | |
<div> | |
<h3 class="tech-font text-blue-400">Commander Elandra</h3> | |
<p class="text-xs text-gray-400">Nexus Protocol Officer</p> | |
</div> | |
</div> | |
<!-- Dialog Text --> | |
<div class="flex-1 p-4 overflow-y-auto"> | |
<p class="text-lg leading-relaxed"> | |
"The quantum destabilization in Sector 7 is worse than we thought. Our scans show the anomaly is spreading at an exponential rate. We need to act now before it breaches the containment field." | |
</p> | |
</div> | |
<!-- Dialog Options --> | |
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 p-4 border-t border-blue-900"> | |
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent"> | |
<p class="text-sm">"What's the plan? How can we stop it?"</p> | |
</div> | |
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent"> | |
<p class="text-sm">"Is this related to the missing research team?"</p> | |
</div> | |
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent"> | |
<p class="text-sm">"What are the risks if we fail?"</p> | |
</div> | |
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent"> | |
<p class="text-sm">"I need more resources to handle this."</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Action Panel (Hidden by default) --> | |
<div id="actionPanel" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-80 z-20 panel-hidden"> | |
<div class="p-4"> | |
<h3 class="tech-font text-xl text-blue-400 mb-4 text-center">COMBAT ACTIONS</h3> | |
<div class="grid grid-cols-2 md:grid-cols-4 gap-3"> | |
<!-- Attack Actions --> | |
<div class="action-btn p-3 rounded-lg cursor-pointer group"> | |
<div class="flex items-center space-x-2"> | |
<div class="w-10 h-10 rounded-full bg-red-900 flex items-center justify-center"> | |
<i class="fas fa-bolt text-red-300"></i> | |
</div> | |
<div> | |
<p class="tech-font text-blue-400">Plasma Shot</p> | |
<div class="flex items-center space-x-1 text-xs"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span>1 AP</span> | |
<i class="fas fa-battery-half text-green-400"></i> | |
<span>5E</span> | |
</div> | |
</div> | |
</div> | |
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition"> | |
Fire a concentrated plasma bolt (12-18 damage) | |
</p> | |
</div> | |
<!-- Tech Actions --> | |
<div class="action-btn p-3 rounded-lg cursor-pointer group"> | |
<div class="flex items-center space-x-2"> | |
<div class="w-10 h-10 rounded-full bg-blue-900 flex items-center justify-center"> | |
<i class="fas fa-shield-alt text-blue-300"></i> | |
</div> | |
<div> | |
<p class="tech-font text-blue-400">Deflector</p> | |
<div class="flex items-center space-x-1 text-xs"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span>1 AP</span> | |
<i class="fas fa-battery-half text-green-400"></i> | |
<span>8E</span> | |
</div> | |
</div> | |
</div> | |
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition"> | |
Raise deflector shield (+15 DEF for 1 round) | |
</p> | |
</div> | |
<!-- Special Actions --> | |
<div class="action-btn p-3 rounded-lg cursor-pointer group"> | |
<div class="flex items-center space-x-2"> | |
<div class="w-10 h-10 rounded-full bg-purple-900 flex items-center justify-center"> | |
<i class="fas fa-atom text-purple-300"></i> | |
</div> | |
<div> | |
<p class="tech-font text-blue-400">Overload</p> | |
<div class="flex items-center space-x-1 text-xs"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span>2 AP</span> | |
<i class="fas fa-battery-half text-green-400"></i> | |
<span>15E</span> | |
</div> | |
</div> | |
</div> | |
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition"> | |
Overcharge systems (Next attack +50% damage) | |
</p> | |
</div> | |
<!-- Utility Actions --> | |
<div class="action-btn p-3 rounded-lg cursor-pointer group"> | |
<div class="flex items-center space-x-2"> | |
<div class="w-10 h-10 rounded-full bg-green-900 flex items-center justify-center"> | |
<i class="fas fa-heartbeat text-green-300"></i> | |
</div> | |
<div> | |
<p class="tech-font text-blue-400">Repair</p> | |
<div class="flex items-center space-x-1 text-xs"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span>2 AP</span> | |
<i class="fas fa-battery-half text-green-400"></i> | |
<span>12E</span> | |
</div> | |
</div> | |
</div> | |
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition"> | |
Emergency repair (Restore 15-25 INT) | |
</p> | |
</div> | |
</div> | |
<div class="mt-4 flex justify-between items-center"> | |
<button id="endTurnBtn" class="action-btn px-4 py-2 rounded flex items-center space-x-2"> | |
<i class="fas fa-hourglass-end"></i> | |
<span>END TURN</span> | |
</button> | |
<div class="flex items-center space-x-4"> | |
<div class="flex items-center space-x-2 text-sm"> | |
<i class="fas fa-bolt text-yellow-400"></i> | |
<span>AP: <span class="tech-font">4</span>/6</span> | |
</div> | |
<div class="flex items-center space-x-2 text-sm"> | |
<i class="fas fa-battery-half text-green-400"></i> | |
<span>Energy: <span class="tech-font">32</span>/50</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Notification System --> | |
<div id="notificationContainer" class="fixed top-4 right-4 space-y-2 z-50"></div> | |
<script> | |
// Game state | |
let currentRound = 1; | |
let actionPoints = 4; | |
let currentScene = 'research_outpost'; | |
let mapVisible = false; | |
let dialogVisible = false; | |
let actionPanelVisible = false; | |
// Initialize UI | |
document.addEventListener('DOMContentLoaded', () => { | |
// Setup event listeners | |
document.getElementById('closeMap').addEventListener('click', toggleMap); | |
document.querySelectorAll('.node').forEach(node => { | |
node.addEventListener('click', navigateToNode); | |
}); | |
// Setup quick menu buttons | |
document.querySelectorAll('#quickMenu button').forEach((btn, index) => { | |
btn.addEventListener('click', () => { | |
if (index === 0) toggleMap(); | |
if (index === 1) showNotification('Settings panel would open here', 'fas fa-cog'); | |
if (index === 2) showNotification('Codex would open here', 'fas fa-book'); | |
}); | |
}); | |
// Setup team panel interactions | |
document.querySelectorAll('.character-card').forEach(card => { | |
card.addEventListener('click', selectTeamMember); | |
}); | |
// Setup action panel | |
document.getElementById('endTurnBtn').addEventListener('click', endTurn); | |
// Load initial scene | |
loadScene(currentScene); | |
// Show welcome notification | |
setTimeout(() => { | |
showNotification('Nexus Protocol initialized', 'fas fa-satellite-dish', 'text-blue-400'); | |
}, 500); | |
}); | |
// Scene management | |
function loadScene(sceneId) { | |
const sceneContainer = document.getElementById('sceneContainer'); | |
const sceneCharacters = document.getElementById('sceneCharacters'); | |
// Clear existing characters | |
sceneCharacters.innerHTML = ''; | |
// Add characters to scene (max 15) | |
const characters = [ | |
{ id: 'elandra', x: '70%', y: '60%', image: 'https://i.imgur.com/3QZ2Q0X.png' }, | |
{ id: 'scientist', x: '30%', y: '50%', image: 'https://i.imgur.com/5t5wY9j.png' }, | |
{ id: 'drone', x: '50%', y: '40%', image: 'https://i.imgur.com/7VvX7Qq.png' } | |
]; | |
characters.slice(0, 15).forEach(char => { | |
const charElement = document.createElement('div'); | |
charElement.className = 'absolute w-16 h-16 rounded-full overflow-hidden border-2 border-blue-500 cursor-pointer'; | |
charElement.style.left = char.x; | |
charElement.style.top = char.y; | |
charElement.innerHTML = `<img src="${char.image}" alt="${char.id}" class="w-full h-full object-cover">`; | |
charElement.addEventListener('click', () => interactWithCharacter(char.id)); | |
sceneCharacters.appendChild(charElement); | |
}); | |
sceneContainer.classList.add('scene-transition'); | |
setTimeout(() => { | |
sceneContainer.classList.remove('scene-transition'); | |
}, 800); | |
} | |
function interactWithCharacter(charId) { | |
if (charId === 'elandra') { | |
showDialog( | |
'Commander Elandra', | |
'Nexus Protocol Officer', | |
'https://i.imgur.com/3QZ2Q0X.png', | |
'"The quantum destabilization in Sector 7 is worse than we thought. Our scans show the anomaly is spreading at an exponential rate. We need to act now before it breaches the containment field."' | |
); | |
} else { | |
showNotification(`Interacting with ${charId}`, 'fas fa-comment'); | |
} | |
} | |
// Navigation | |
function toggleMap() { | |
const mapPanel = document.getElementById('mapPanel'); | |
mapVisible = !mapVisible; | |
if (mapVisible) { | |
mapPanel.classList.remove('panel-hidden'); | |
mapPanel.classList.add('panel-visible', 'map-transition'); | |
} else { | |
mapPanel.classList.remove('panel-visible'); | |
mapPanel.classList.add('panel-hidden'); | |
} | |
} | |
function navigateToNode(e) { | |
const node = e.currentTarget; | |
const sceneId = node.getAttribute('data-scene'); | |
if (node.classList.contains('available') || node.classList.contains('current')) { | |
showNotification(`Navigating to ${sceneId}...`, 'fas fa-map-marked-alt'); | |
setTimeout(() => { | |
toggleMap(); | |
loadScene(sceneId); | |
}, 1000); | |
} else if (node.classList.contains('visited')) { | |
showNotification('Returning to previous location...', 'fas fa-history'); | |
setTimeout(() => { | |
toggleMap(); | |
loadScene(sceneId); | |
}, 1000); | |
} else { | |
showNotification('Location not yet available', 'fas fa-lock', 'text-red-400'); | |
} | |
} | |
// Dialog system | |
function showDialog(speaker, title, image, text) { | |
const dialogPanel = document.getElementById('dialogPanel'); | |
const speakerImg = dialogPanel.querySelector('img'); | |
const speakerName = dialogPanel.querySelector('h3'); | |
const speakerTitle = dialogPanel.querySelector('p.text-xs'); | |
const dialogText = dialogPanel.querySelector('p.text-lg'); | |
speakerImg.src = image; | |
speakerName.textContent = speaker; | |
speakerTitle.textContent = title; | |
dialogText.textContent = text; | |
dialogPanel.classList.remove('panel-hidden'); | |
dialogPanel.classList.add('panel-visible'); | |
dialogVisible = true; | |
} | |
function closeDialog() { | |
const dialogPanel = document.getElementById('dialogPanel'); | |
dialogPanel.classList.remove('panel-visible'); | |
dialogPanel.classList.add('panel-hidden'); | |
dialogVisible = false; | |
} | |
// Combat system | |
function toggleActionPanel() { | |
const actionPanel = document.getElementById('actionPanel'); | |
actionPanelVisible = !actionPanelVisible; | |
if (actionPanelVisible) { | |
actionPanel.classList.remove('panel-hidden'); | |
actionPanel.classList.add('panel-visible'); | |
} else { | |
actionPanel.classList.remove('panel-visible'); | |
actionPanel.classList.add('panel-hidden'); | |
} | |
} | |
function endTurn() { | |
currentRound++; | |
document.getElementById('roundNumber').textContent = currentRound; | |
actionPoints = 6; | |
document.getElementById('apCount').textContent = actionPoints; | |
showNotification(`Round ${currentRound} started`, 'fas fa-flag', 'text-blue-400'); | |
toggleActionPanel(); | |
} | |
// Team management | |
function selectTeamMember(e) { | |
const card = e.currentTarget; | |
// Deselect all | |
document.querySelectorAll('.character-card').forEach(c => { | |
c.classList.remove('active'); | |
}); | |
// Select clicked | |
card.classList.add('active'); | |
showNotification(`${card.querySelector('p').textContent} selected`, 'fas fa-user-astronaut'); | |
} | |
// Notification system | |
function showNotification(message, icon, textColor = 'text-blue-400') { | |
const container = document.getElementById('notificationContainer'); | |
const notification = document.createElement('div'); | |
notification.className = `notification hud-element px-4 py-2 rounded-lg flex items-center space-x-2 ${textColor}`; | |
notification.innerHTML = ` | |
<i class="${icon}"></i> | |
<span>${message}</span> | |
`; | |
container.appendChild(notification); | |
// Remove after delay | |
setTimeout(() => { | |
notification.classList.add('fade-out'); | |
setTimeout(() => { | |
notification.remove(); | |
}, 300); | |
}, 3000); | |
} | |
// Keyboard shortcuts | |
document.addEventListener('keydown', (e) => { | |
// Toggle map with M key | |
if (e.key === 'm' || e.key === 'M') { | |
e.preventDefault(); | |
toggleMap(); | |
} | |
// Toggle action panel with Space key | |
if (e.key === ' ') { | |
e.preventDefault(); | |
toggleActionPanel(); | |
} | |
// Close dialogs with Escape | |
if (e.key === 'Escape') { | |
if (dialogVisible) closeDialog(); | |
if (actionPanelVisible) toggleActionPanel(); | |
if (mapVisible) toggleMap(); | |
} | |
}); | |
</script> | |
</body> | |
</html> |