316 lines
16 KiB
HTML
316 lines
16 KiB
HTML
<!doctype html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>Star Wars - Wild Space</title>
|
||
<link rel="stylesheet" href="./style.css" />
|
||
</head>
|
||
<body>
|
||
<!-- Auth Modal ──────────────────────────────────────────────────────────── -->
|
||
<div class="authOverlay" id="authOverlay">
|
||
<div class="authModal">
|
||
<div class="authTabs">
|
||
<button type="button" class="authTab authTab--active" id="tabLogin">Se connecter</button>
|
||
<button type="button" class="authTab" id="tabRegister">S'enregistrer</button>
|
||
</div>
|
||
|
||
<!-- Login form -->
|
||
<form class="authForm" id="loginForm">
|
||
<div class="authField">
|
||
<label>Nom d'utilisateur</label>
|
||
<input type="text" id="loginUsername" autocomplete="username" required />
|
||
</div>
|
||
<div class="authField">
|
||
<label>Mot de passe</label>
|
||
<input type="password" id="loginPassword" autocomplete="current-password" required />
|
||
</div>
|
||
<div class="authError hidden" id="loginError"></div>
|
||
<button type="submit" class="authSubmit">Se connecter</button>
|
||
</form>
|
||
|
||
<!-- Register form -->
|
||
<form class="authForm hidden" id="registerForm">
|
||
<div class="authField">
|
||
<label>Nom d'utilisateur</label>
|
||
<input type="text" id="regUsername" autocomplete="username" required />
|
||
</div>
|
||
<div class="authField">
|
||
<label>Mot de passe <span class="authHint">(6 caractères min.)</span></label>
|
||
<input type="password" id="regPassword" autocomplete="new-password" required />
|
||
</div>
|
||
<div class="authField">
|
||
<label>Équipe</label>
|
||
<div class="authTeamChoice">
|
||
<label class="authTeamOption">
|
||
<input type="radio" name="regTeam" value="blue" required />
|
||
<span class="authTeamBadge authTeamBadge--blue">
|
||
<img src="./graphism/logo_resistance.svg" class="authTeamLogo" alt="" />
|
||
Résistance
|
||
</span>
|
||
<span class="authTeamCount authTeamCount--blue" id="regCountBlue">… joueurs</span>
|
||
</label>
|
||
<label class="authTeamOption">
|
||
<input type="radio" name="regTeam" value="red" />
|
||
<span class="authTeamBadge authTeamBadge--red">
|
||
Premier ordre
|
||
<img src="./graphism/logo_first_order.svg" class="authTeamLogo" alt="" />
|
||
</span>
|
||
<span class="authTeamCount authTeamCount--red" id="regCountRed">… joueurs</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<p class="authNotice">⚠ En cas d'oubli du mot de passe, aucune récupération n'est possible.</p>
|
||
<div class="authError hidden" id="registerError"></div>
|
||
<button type="submit" class="authSubmit">Créer le compte</button>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Main app layout: left info column + right galaxy square ─────────────── -->
|
||
<div class="app">
|
||
|
||
<!-- ── Left information column ────────────────────────────────────────── -->
|
||
<aside class="infoColumn" id="infoColumn">
|
||
|
||
<!-- Mobile close button -->
|
||
<button type="button" id="closeMenuBtn" class="closeMenuBtn" aria-label="Close menu">✕</button>
|
||
|
||
<div class="infoSection infoSection--title">
|
||
<div class="h1">Star Wars - Wild Space</div>
|
||
<div class="sub">Explorez les Régions Inconnues pour faire triompher votre camp !</div>
|
||
</div>
|
||
|
||
<!-- Team score display -->
|
||
<div class="scoreBoard" id="scoreBoard">
|
||
<div class="teamLogoWrap">
|
||
<img src="./graphism/logo_resistance.svg" alt="Resistance" class="team-logo" />
|
||
<span class="teamPlayerCount teamPlayerCount--blue" id="activeCountBlue">0 joueur</span>
|
||
</div>
|
||
<div class="scoreBoardContent">
|
||
<div class="scoreBoardRow">
|
||
<div class="scoreTeam scoreTeam--blue">
|
||
<span class="scoreTeamName">Résistance</span>
|
||
<div class="scoreStats">
|
||
<div class="scoreStat">
|
||
<span class="scoreStatVal scoreValue" id="scoreBlue">0</span>
|
||
<span class="scoreStatLabel">Tuiles</span>
|
||
</div>
|
||
<div class="scoreStat">
|
||
<span class="scoreStatVal scoreVP" id="vpBlue">0</span>
|
||
<span class="scoreStatLabel">Points</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<span class="scoreSep">—</span>
|
||
<div class="scoreTeam scoreTeam--red">
|
||
<span class="scoreTeamName">Premier Ordre</span>
|
||
<div class="scoreStats">
|
||
<div class="scoreStat">
|
||
<span class="scoreStatVal scoreVP" id="vpRed">0</span>
|
||
<span class="scoreStatLabel">Points</span>
|
||
</div>
|
||
<div class="scoreStat">
|
||
<span class="scoreStatVal scoreValue" id="scoreRed">0</span>
|
||
<span class="scoreStatLabel">Tuiles</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- Income summary + cumulative economic score (inside scoreBoard) -->
|
||
<div class="scoreBoardEcon">
|
||
<div class="econSummaryRow">
|
||
<span class="econSummaryTeam econSummaryTeam--blue econSummaryTeam--center">
|
||
<span class="econSummaryVal" id="incomeBlue">+0.000/s</span>
|
||
</span>
|
||
<span class="econSummarySep">—</span>
|
||
<span class="econSummaryTeam econSummaryTeam--red econSummaryTeam--center">
|
||
<span class="econSummaryVal" id="incomeRed">+0.000/s</span>
|
||
</span>
|
||
</div>
|
||
<div class="econSummaryRow econSummaryRow--score">
|
||
<span class="econSummaryTeam econSummaryTeam--blue econSummaryTeam--center">
|
||
<span class="econScoreVal" id="econScoreBlue">0.000</span>
|
||
<span class="econDelta" id="econDeltaBlue"></span>
|
||
</span>
|
||
<span class="econSummarySep">—</span>
|
||
<span class="econSummaryTeam econSummaryTeam--red econSummaryTeam--center">
|
||
<span class="econDelta" id="econDeltaRed"></span>
|
||
<span class="econScoreVal" id="econScoreRed">0.000</span>
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="teamLogoWrap">
|
||
<img src="./graphism/logo_first_order.svg" alt="First Order" class="team-logo" />
|
||
<span class="teamPlayerCount teamPlayerCount--red" id="activeCountRed">0 joueur</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Info rows -->
|
||
<div class="infoTable">
|
||
<div class="infoRow" id="userInfoRow">
|
||
<span class="infoKey">Joueur</span>
|
||
<span class="infoVal">
|
||
<span id="userDisplay">—</span>
|
||
<button type="button" id="logoutBtn" class="logoutBtn hidden">Déconnexion</button>
|
||
</span>
|
||
</div>
|
||
<div class="infoRow" id="countdownWrap" aria-live="polite">
|
||
<span class="infoKey countdownLabel">Prochain clic</span>
|
||
<span class="infoVal countdownVal">
|
||
<span id="countdown" class="countdown">0</span>
|
||
<span class="countdownUnit">s</span>
|
||
</span>
|
||
</div>
|
||
<div class="infoRow">
|
||
<span class="infoKey muted">Délai entre deux clics</span>
|
||
<code class="infoVal" id="cooldownConfig">—</code>
|
||
</div>
|
||
<div class="infoRow">
|
||
<span class="infoKey muted">Graine de la carte</span>
|
||
<code class="infoVal" id="worldSeedDisplay">—</code>
|
||
</div>
|
||
<div class="infoRow">
|
||
<span class="infoKey muted">Prochaine graine (UTC)</span>
|
||
<code class="infoVal" id="nextPeriodUtc">—</code>
|
||
</div>
|
||
<div class="infoRow">
|
||
<span class="infoKey muted">Prochaine graine dans</span>
|
||
<code class="infoVal" id="refreshCountdown">--:--:--</code>
|
||
</div>
|
||
<div class="infoRow">
|
||
<span class="infoKey muted">Graine actuelle depuis</span>
|
||
<code class="infoVal" id="dbCreatedAt">—</code>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Planet stats (collapsible) -->
|
||
<details class="panel panelCollapsible" id="planetStatsDetails" open>
|
||
<summary class="panelTitle panelTitleSummary">🪐 Statistiques Planétaires</summary>
|
||
<pre id="details" class="details details--hidden">Les stats sont vides sauf à cliquer sur une tuile exploitable.</pre>
|
||
</details>
|
||
|
||
<!-- Resources overview (collapsible) -->
|
||
<details class="panel panelCollapsible">
|
||
<summary class="panelTitle panelTitleSummary">💰 Ressources</summary>
|
||
<div id="resourceTableBody" class="econTableWrap">
|
||
<p class="econEmpty">Chargement…</p>
|
||
</div>
|
||
</details>
|
||
|
||
<!-- Element bonus (collapsible) -->
|
||
<details class="panel panelCollapsible">
|
||
<summary class="panelTitle panelTitleSummary">⚡ Bonus d'exploration</summary>
|
||
<div class="elemBonusTotals">
|
||
<span class="elemBonusTeam elemBonusTeam--blue">
|
||
<span class="elemBonusLabel">Résistance</span>
|
||
<span class="elemBonusVal" id="elemBonusBlue">0.00</span>
|
||
<span class="elemBonusUnit">%</span>
|
||
</span>
|
||
<span class="elemBonusSep">—</span>
|
||
<span class="elemBonusTeam elemBonusTeam--red">
|
||
<span class="elemBonusVal" id="elemBonusRed">0.00</span>
|
||
<span class="elemBonusUnit">%</span>
|
||
<span class="elemBonusLabel">Premier Ordre</span>
|
||
</span>
|
||
<span class="elemBonusEffective">
|
||
<span class="elemBonusDetailLabel">Recharge :</span>
|
||
<span class="elemBonusDetailVal" id="effectiveCooldown">—</span>
|
||
</span>
|
||
</div>
|
||
<div id="elementBonusTableBody" class="econTableWrap">
|
||
<p class="econEmpty">Chargement…</p>
|
||
</div>
|
||
</details>
|
||
|
||
<!-- Military power (collapsible) -->
|
||
<details class="panel panelCollapsible">
|
||
<summary class="panelTitle panelTitleSummary">⚔️ Puissance Militaire</summary>
|
||
<div class="milPowerTotals">
|
||
<span class="milPowerTeam milPowerTeam--blue">
|
||
<span class="milPowerLabel">Résistance</span>
|
||
<span class="milPowerVal" id="milPowerBlue">0.0</span>
|
||
</span>
|
||
<span class="milPowerSep">—</span>
|
||
<span class="milPowerTeam milPowerTeam--red">
|
||
<span class="milPowerVal" id="milPowerRed">0.0</span>
|
||
<span class="milPowerLabel">Premier Ordre</span>
|
||
</span>
|
||
</div>
|
||
<div id="militaryTableBody" class="econTableWrap">
|
||
<p class="econEmpty">Chargement…</p>
|
||
</div>
|
||
</details>
|
||
|
||
<!-- Game rules -->
|
||
<details class="panel panelCollapsible">
|
||
<summary class="panelTitle panelTitleSummary">📜 Règles du jeu</summary>
|
||
<div class="rulesContent">
|
||
<p><strong>Points de Victoire</strong><br/>
|
||
À la fin de chaque période (rotation de la carte), l'équipe ayant le <em>score économique</em> le plus élevé remporte <strong>1 Point de Victoire</strong>. Ces points sont cumulatifs d'une manche à l'autre.</p>
|
||
|
||
<p><strong>Tableau des scores</strong><br/>
|
||
Sous le tableau des scores, plusieurs indicateurs sont affichés :</p>
|
||
<ul>
|
||
<li><strong>Revenu/s</strong> — crédits générés chaque seconde grâce aux ressources naturelles des planètes découvertes.</li>
|
||
<li><strong>Score économique</strong> — total cumulé des crédits gagnés au fil du temps. Mis à jour toutes les 5 secondes.</li>
|
||
</ul>
|
||
|
||
<p><strong>💰 Ressources</strong><br/>
|
||
En explorant la galaxie, vous révélez des tuiles qui peuvent contenir des planètes. Chaque planète possède des ressources naturelles (minerais, bois, pétrole, etc.) dont la valeur contribue au revenu de votre équipe.</p>
|
||
|
||
<p><strong>⚡ Bonus d'exploration</strong><br/>
|
||
Les planètes produisent des éléments (matières premières, carburant, nourriture, science…) qui offrent un bonus cumulatif. Ce bonus réduit le temps de recharge entre deux clics, permettant d'explorer plus vite.</p>
|
||
|
||
<p><strong>⚔️ Puissance militaire</strong><br/>
|
||
La population des planètes conquises fournit des unités militaires. Lorsque vous accumulez suffisamment de troupes, vous pouvez lancer une attaque sur une tuile ennemie pour la capturer. Chaque attaque consomme une partie de vos forces.</p>
|
||
</div>
|
||
</details>
|
||
|
||
<!-- Credits -->
|
||
<details class="panel panelCollapsible">
|
||
<summary class="panelTitle panelTitleSummary">🏷️ Crédits</summary>
|
||
<div class="rulesContent">
|
||
<p><strong>Dépôt Git</strong><br/>
|
||
<a href="https://git.gbmm-holocron.eu/gauvain/star-wars-wild-space" target="_blank" rel="noopener">
|
||
git.gbmm-holocron.eu/gauvain/star-wars-wild-space
|
||
</a>
|
||
</p>
|
||
|
||
<p>Le projet "Star Wars: Wild Space" a été pensé et pitché en 2021 par Mya TELLIS et Harlon ASTELLAN (moi), pseudonymes hérités du forum de jeu de rôle littéraire "Star Wars - Online Roleplay" anciennement "Star Wars Old Revolution". Le projet n'ayant pas abouti faute de développeur disponible, il a été abandonné, mais pas en esprit. Faute de temps, de motivation et d'argent pour coder/le faire coder, j'ai décidé de mettre à profit l'agentique IA pour faire naître ce jeu sans prétention.</p>
|
||
|
||
<p>Des morceaux ne sont pas issus de l'IA, notamment la section de génération des planètes, réalisée à la main pour m'entraîner d'abord sur Python puis Javascript. Mais les morceaux ont été "révisés" par l'IA pour l'intégrer à une API, aussi on peut considérer que 100% du contenu ici est généré par Claude Sonnet 4.6, à 1% près. Aussi si vous êtes le genre à chouiner "gnagnagna l'IA le voooool des artiiiiistes" etc, sachez que sans l'IA il n'y aurait rien eu, l'outil existe, autant vous y faire, et pour ce projet personne n'a été remplacé, et personne ne vous force à y jouer. Allez révolutionner ailleurs.</p>
|
||
|
||
<p>Il n'y a pas (encore ?) de gestion de compte par courriel avec mot de passe oublié etc parce que l'implémentation est plus complexe. Pour l'instant, c'est suffisamment tranquille pour s'en passer. Au besoin refaites un compte.</p>
|
||
</div>
|
||
</details>
|
||
|
||
</aside>
|
||
|
||
<!-- ── Galaxy (square, 1000×1000, fixed ratio) ────────────────────────── -->
|
||
<main class="galaxyMain">
|
||
<!-- Mobile burger button -->
|
||
<button type="button" id="burgerBtn" class="burgerBtn" aria-label="Open menu">☰</button>
|
||
<canvas id="canvas" width="1000" height="1000"></canvas>
|
||
<div id="hint" class="hint">Cliquez sur une tuile. Les stats seront vides à moins de cliquer.</div>
|
||
|
||
<!-- Military attack confirmation modal -->
|
||
<div class="attackOverlay hidden" id="attackOverlay">
|
||
<div class="attackModal">
|
||
<div class="attackModal__icon">⚔️</div>
|
||
<div class="attackModal__title">Attaque Militaire</div>
|
||
<div class="attackModal__body" id="attackModalBody"></div>
|
||
<div class="attackModal__actions">
|
||
<button type="button" class="attackModal__btn attackModal__btn--cancel" id="attackModalNo">Annuler</button>
|
||
<button type="button" class="attackModal__btn attackModal__btn--confirm" id="attackModalYes">Attaquer !</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
</div>
|
||
|
||
<script type="module" src="./src/main.js"></script>
|
||
</body>
|
||
</html> |