Some checks are pending
CI/CD Cloud Deployment / test-and-build (push) Waiting to run
- Triple-A Werbeseite mit Gameplay-Videos, 3-Lane Radar und Einheiten-Showcase - LiveOps-Schaltzentrale mit CCU-Tracking, Download-Statistiken und Match-Balance - Reale Engine-Benchmarks (C# vs Godot, U2-U5.5 FPS, GPU-Skinning Entlastung) - Zero-Dependency Node.js Backend mit REST-APIs und Server-Sent Events (SSE) - Cloud-Ready mit Dockerfile, docker-compose.yml und GitHub Actions CI/CD
234 lines
11 KiB
JavaScript
234 lines
11 KiB
JavaScript
/**
|
|
* CHAMPIONS OF LUNERARIA - Tactical Radar 3-Lane Visualizer (Studio Grade)
|
|
* Holographic military MOBA radar with dynamic SVG pulse waves,
|
|
* contour elevation guides, and live tactical landmark inspector.
|
|
*/
|
|
|
|
const TACTICAL_REGIONS = {
|
|
mid: {
|
|
id: 'mid',
|
|
title: 'Mid-Lane (Zentralplattform)',
|
|
type: 'Direkte Offensive',
|
|
length: '61,16 Meter',
|
|
elevation: 'Plateau (Höhe 0 m)',
|
|
threat: 'Höchste Konfrontationsdichte',
|
|
preview: 'assets/img/hero-overview.png',
|
|
desc: 'Die kürzeste und blutigste Route. Führt geradlinig über die uralte Runensteinplattform direkt über die Symmetriekluft. Der Verlust der beiden Mid-Türme legt sofort die Flanken zur eigenen Basis frei.'
|
|
},
|
|
top: {
|
|
id: 'top',
|
|
title: 'Top-Lane (Hochlandkamm)',
|
|
type: 'Flankenkorridor',
|
|
length: '96,82 Meter',
|
|
elevation: 'Hochland (+8 m bis +14 m)',
|
|
threat: 'Flankenüberfälle & Grotte',
|
|
preview: 'assets/img/tuerme.png',
|
|
desc: 'Zieht im Nordwesten durch zerklüftetes Felsmassiv. Wegen des Höhenprofils und der direkten Anbindung an den Zugang zur Bossgrotte Mondschlund der ideale Pfad für Assassinen wie Sylvara.'
|
|
},
|
|
bot: {
|
|
id: 'bot',
|
|
title: 'Bottom-Lane (Deltabrücke)',
|
|
type: 'Weitfeld-Belagerung',
|
|
length: '96,82 Meter',
|
|
elevation: 'Tiefland / Flussdelta (-4 m)',
|
|
threat: 'Belagerungs- & Fernkampfzone',
|
|
preview: 'assets/img/aufmarsch.jpg',
|
|
desc: 'Führt durch die weite Flussniederung und über die massive Deltabrücke. Weitläufige Sichtachsen begünstigen Belagerungsmaschinen wie die Glasballiste und dichte Schützenformationen.'
|
|
},
|
|
grotto: {
|
|
id: 'grotto',
|
|
title: 'Bossgrotte „Mondschlund“',
|
|
type: 'Neutrales Primärziel',
|
|
length: 'Zentrales Terrassengebiet',
|
|
elevation: 'Grottensenke (+4 m)',
|
|
threat: 'Superboss Schlundkrone (6.800 HP)',
|
|
preview: 'assets/img/bosskampf.jpg',
|
|
desc: 'Auf der zentralen Symmetrieachse gelegen. Die Bezwingung der Schlundkrone schaltet eine mächtige Boss-Entsendung frei, die auf einer Wunsch-Lane als Belagerungskoloss gegen den feindlichen Ancient vorrückt.'
|
|
},
|
|
blue_ancient: {
|
|
id: 'blue_ancient',
|
|
title: 'Mondherz-Ancient (Team Blau)',
|
|
type: 'Festungskern West',
|
|
length: 'Hauptquartier',
|
|
elevation: 'Basisplateau (+6 m)',
|
|
threat: '10.000 HP · 16 Verteidiger',
|
|
preview: 'assets/img/ancient.png',
|
|
desc: 'Der pulsierende Saumkern des blauen Bündnisses, geschützt durch 2 Basistürme und drei Torriegel. Fällt dieser Kristall im Kampf, endet die Schlacht augenblicklich mit der Niederlage von Team Blau.'
|
|
},
|
|
red_ancient: {
|
|
id: 'red_ancient',
|
|
title: 'Mondherz-Ancient (Team Rot)',
|
|
type: 'Festungskern Ost',
|
|
length: 'Hauptquartier',
|
|
elevation: 'Basisplateau (+6 m)',
|
|
threat: '10.000 HP · 16 Verteidiger',
|
|
preview: 'assets/img/ancient-fall.jpg',
|
|
desc: 'Das exakt spiegelgleiche Gegenstück im Osten. Identische Verteidigungsradien, Schussfrequenzen der Türme und Aufmarschlinien garantieren 100 % faire Wettkampfbedingungen ohne Seitenvorteil.'
|
|
}
|
|
};
|
|
|
|
function renderStudioRadar(containerId) {
|
|
const container = document.getElementById(containerId);
|
|
if (!container) return;
|
|
|
|
const svgNS = 'http://www.w3.org/2000/svg';
|
|
const svg = document.createElementNS(svgNS, 'svg');
|
|
svg.setAttribute('viewBox', '0 0 880 540');
|
|
svg.setAttribute('class', 'radar-hud-svg');
|
|
svg.setAttribute('aria-label', 'Taktische Radaransicht des 3-Lane Schlachtfelds');
|
|
|
|
svg.innerHTML = `
|
|
<defs>
|
|
<!-- Background Radial Gradient -->
|
|
<radialGradient id="radarDarkGrad" cx="50%" cy="50%" r="70%">
|
|
<stop offset="0%" stop-color="#070c16" />
|
|
<stop offset="60%" stop-color="#04060b" />
|
|
<stop offset="100%" stop-color="#020306" />
|
|
</radialGradient>
|
|
|
|
<!-- Hologram Chasm Gradient -->
|
|
<linearGradient id="chasmHoloGrad" x1="0" y1="0" x2="0" y2="1">
|
|
<stop offset="0%" stop-color="rgba(168, 85, 247, 0.45)" />
|
|
<stop offset="50%" stop-color="rgba(56, 232, 216, 0.25)" />
|
|
<stop offset="100%" stop-color="rgba(168, 85, 247, 0.45)" />
|
|
</linearGradient>
|
|
|
|
<!-- Glow Filters -->
|
|
<filter id="radarCyanGlow" x="-30%" y="-30%" width="160%" height="160%">
|
|
<feGaussianBlur stdDeviation="5" result="blur" />
|
|
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
|
</filter>
|
|
<filter id="radarGoldGlow" x="-30%" y="-30%" width="160%" height="160%">
|
|
<feGaussianBlur stdDeviation="6" result="blur" />
|
|
<feComposite in="SourceGraphic" in2="blur" operator="over" />
|
|
</filter>
|
|
</defs>
|
|
|
|
<!-- Radar Background Grid -->
|
|
<rect width="880" height="540" fill="url(#radarDarkGrad)" rx="16" />
|
|
|
|
<!-- Elevation Contour Lines & Hex Accents -->
|
|
<g opacity="0.14" stroke="#38e8d8" stroke-width="0.75" fill="none">
|
|
<!-- Concentric Range Circles -->
|
|
<circle cx="440" cy="270" r="100" stroke-dasharray="2 4" />
|
|
<circle cx="440" cy="270" r="180" />
|
|
<circle cx="440" cy="270" r="260" stroke-dasharray="4 6" />
|
|
<circle cx="440" cy="270" r="340" />
|
|
|
|
<!-- Center Crosshairs -->
|
|
<line x1="60" y1="270" x2="820" y2="270" stroke-dasharray="6 4" />
|
|
<line x1="440" y1="40" x2="440" y2="500" stroke-dasharray="6 4" />
|
|
</g>
|
|
|
|
<!-- Central Mountain Chasm (Kluftlinie) -->
|
|
<path d="M 440 40 Q 415 190 450 270 T 430 500" fill="none" stroke="url(#chasmHoloGrad)" stroke-width="32" stroke-linecap="round" opacity="0.6" />
|
|
<path d="M 440 40 Q 415 190 450 270 T 430 500" fill="none" stroke="#22d3ee" stroke-width="2.5" stroke-dasharray="8 6" opacity="0.8" />
|
|
|
|
<!-- Lane Corridors -->
|
|
<!-- Top Lane (Hochland) -->
|
|
<path id="radarTopGlow" d="M 140 270 C 160 110, 340 85, 440 85 C 540 85, 720 110, 740 270"
|
|
fill="none" stroke="#38e8d8" stroke-width="10" stroke-linecap="round" opacity="0.25" />
|
|
<path d="M 140 270 C 160 110, 340 85, 440 85 C 540 85, 720 110, 740 270"
|
|
fill="none" stroke="#38e8d8" stroke-width="2.5" stroke-dasharray="8 6" opacity="0.9" />
|
|
|
|
<!-- Mid Lane (Zentrum) -->
|
|
<path id="radarMidGlow" d="M 140 270 L 740 270"
|
|
fill="none" stroke="#0ea5e9" stroke-width="14" stroke-linecap="round" opacity="0.25" />
|
|
<path d="M 140 270 L 740 270"
|
|
fill="none" stroke="#38bdf8" stroke-width="3" stroke-dasharray="10 6" opacity="0.95" />
|
|
|
|
<!-- Bottom Lane (Delta) -->
|
|
<path id="radarBotGlow" d="M 140 270 C 160 430, 340 455, 440 455 C 540 455, 720 430, 740 270"
|
|
fill="none" stroke="#818cf8" stroke-width="10" stroke-linecap="round" opacity="0.25" />
|
|
<path d="M 140 270 C 160 430, 340 455, 440 455 C 540 455, 720 430, 740 270"
|
|
fill="none" stroke="#818cf8" stroke-width="2.5" stroke-dasharray="8 6" opacity="0.9" />
|
|
|
|
<!-- Center Runestone Platform -->
|
|
<rect x="395" y="238" width="90" height="64" rx="8" fill="#0f172a" stroke="#38e8d8" stroke-width="1.8" filter="url(#radarCyanGlow)" opacity="0.85" />
|
|
<text x="440" y="275" font-family="'Cinzel', serif" font-size="11" font-weight="800" fill="#fff" text-anchor="middle" letter-spacing="1">MID-PLATEAU</text>
|
|
|
|
<!-- Boss Grotto "Mondschlund" -->
|
|
<g class="radar-interactive-target" data-target="grotto" cursor="pointer">
|
|
<circle cx="440" cy="150" r="34" fill="#1e142e" stroke="#f59e0b" stroke-width="3" filter="url(#radarGoldGlow)" />
|
|
<polygon points="440,132 454,160 426,160" fill="#f59e0b" />
|
|
<text x="440" y="200" font-family="'Cinzel', serif" font-size="11" font-weight="800" fill="#f59e0b" text-anchor="middle" letter-spacing="1">MONDSCHLUND</text>
|
|
</g>
|
|
|
|
<!-- Blue Ancient West -->
|
|
<g class="radar-interactive-target" data-target="blue_ancient" cursor="pointer">
|
|
<circle cx="140" cy="270" r="48" fill="#08203c" stroke="#0284c7" stroke-width="3.5" filter="url(#radarCyanGlow)" />
|
|
<polygon points="140,248 158,270 140,292 122,270" fill="#38e8d8" />
|
|
<text x="140" y="338" font-family="'Cinzel', serif" font-size="11" font-weight="800" fill="#38e8d8" text-anchor="middle" letter-spacing="1">BLAUER ANCIENT</text>
|
|
</g>
|
|
|
|
<!-- Red Ancient East -->
|
|
<g class="radar-interactive-target" data-target="red_ancient" cursor="pointer">
|
|
<circle cx="740" cy="270" r="48" fill="#360d1a" stroke="#e11d48" stroke-width="3.5" filter="url(#radarCyanGlow)" />
|
|
<polygon points="740,248 758,270 740,292 722,270" fill="#f43f5e" />
|
|
<text x="740" y="338" font-family="'Cinzel', serif" font-size="11" font-weight="800" fill="#f43f5e" text-anchor="middle" letter-spacing="1">ROTER ANCIENT</text>
|
|
</g>
|
|
|
|
<!-- Tower Indicators -->
|
|
<!-- Top Lane Towers -->
|
|
<circle cx="280" cy="122" r="9" fill="#0284c7" stroke="#fff" stroke-width="1.8" />
|
|
<circle cx="600" cy="122" r="9" fill="#e11d48" stroke="#fff" stroke-width="1.8" />
|
|
|
|
<!-- Mid Lane Towers -->
|
|
<circle cx="310" cy="270" r="9" fill="#0284c7" stroke="#fff" stroke-width="1.8" />
|
|
<circle cx="570" cy="270" r="9" fill="#e11d48" stroke="#fff" stroke-width="1.8" />
|
|
|
|
<!-- Bot Lane Towers -->
|
|
<circle cx="280" cy="418" r="9" fill="#0284c7" stroke="#fff" stroke-width="1.8" />
|
|
<circle cx="600" cy="418" r="9" fill="#e11d48" stroke="#fff" stroke-width="1.8" />
|
|
|
|
<!-- Invisible broad click paths -->
|
|
<path class="radar-interactive-target" data-target="top" d="M 160 250 C 180 120, 340 75, 440 75 C 540 75, 700 120, 720 250"
|
|
fill="none" stroke="transparent" stroke-width="44" cursor="pointer" />
|
|
<line class="radar-interactive-target" data-target="mid" x1="180" y1="270" x2="700" y2="270"
|
|
stroke="transparent" stroke-width="48" cursor="pointer" />
|
|
<path class="radar-interactive-target" data-target="bot" d="M 160 290 C 180 420, 340 465, 440 465 C 540 465, 700 420, 720 290"
|
|
fill="none" stroke="transparent" stroke-width="44" cursor="pointer" />
|
|
`;
|
|
|
|
container.appendChild(svg);
|
|
|
|
// Inspector logic
|
|
const titleEl = document.getElementById('dossierTitle');
|
|
const badgeEl = document.getElementById('dossierBadge');
|
|
const lengthEl = document.getElementById('dossierLength');
|
|
const elevationEl = document.getElementById('dossierElevation');
|
|
const descEl = document.getElementById('dossierDesc');
|
|
const previewEl = document.getElementById('dossierPreviewImg');
|
|
|
|
function updateDossier(key) {
|
|
const data = TACTICAL_REGIONS[key];
|
|
if (!data) return;
|
|
|
|
if (titleEl) titleEl.textContent = data.title;
|
|
if (badgeEl) badgeEl.textContent = data.type;
|
|
if (lengthEl) lengthEl.textContent = data.length;
|
|
if (elevationEl) elevationEl.textContent = data.elevation;
|
|
if (descEl) descEl.textContent = data.desc;
|
|
if (previewEl && data.preview) previewEl.src = data.preview;
|
|
|
|
document.querySelectorAll('.radar-zone-btn').forEach(btn => {
|
|
btn.classList.toggle('is-active', btn.dataset.target === key);
|
|
});
|
|
}
|
|
|
|
svg.querySelectorAll('.radar-interactive-target').forEach(node => {
|
|
node.addEventListener('click', () => {
|
|
updateDossier(node.dataset.target);
|
|
});
|
|
});
|
|
|
|
document.querySelectorAll('.radar-zone-btn').forEach(btn => {
|
|
btn.addEventListener('click', () => {
|
|
updateDossier(btn.dataset.target);
|
|
});
|
|
});
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
renderStudioRadar('radarScreenContainer');
|
|
});
|