From 1e7b21a935eaff63cca3c00097243bb59ca30cbb Mon Sep 17 00:00:00 2001 From: verboomp Date: Mon, 20 Apr 2026 16:09:18 +0200 Subject: [PATCH] added sys digger --- sys_digger/constants.js | 2 +- sys_digger/game.js | 15 +++++- sys_digger/index.html | 110 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 122 insertions(+), 5 deletions(-) diff --git a/sys_digger/constants.js b/sys_digger/constants.js index 9fd27af..0028a65 100644 --- a/sys_digger/constants.js +++ b/sys_digger/constants.js @@ -1,5 +1,5 @@ // ─── Game rules ────────────────────────────────────────────────────────────── -const MAX_DOCKS = 8; // failed docks before game over +const MAX_DOCKS = 6; // failed docks before game over const NUM_ANCHORS = 6; // anchor points around the central molecule const ANCHOR_RADIUS = 120; // px distance from center to anchor points const CLICK_RADIUS = 38; // px hit radius for clicking an anchor diff --git a/sys_digger/game.js b/sys_digger/game.js index 3c2e7d3..f3c6487 100644 --- a/sys_digger/game.js +++ b/sys_digger/game.js @@ -79,6 +79,7 @@ function topScore() { let score = 0; let docks = 0; let gameOver = false; +let gameStarted = false; let incomingAtoms = []; let anchorPoints = []; let particles = []; @@ -177,19 +178,26 @@ function submitScore() { function restartGame() { score = docks = 0; gameOver = false; + gameStarted = false; incomingAtoms = []; particles = []; clickEffects = []; lastSpawn = 0; spawnInterval = SPAWN_INTERVAL_START; document.getElementById('score').textContent = 'Score: 0'; - document.getElementById('docks-count').textContent = '0 / 8 docks'; + document.getElementById('docks-count').textContent = `0 / ${MAX_DOCKS} docks`; document.getElementById('name-form').style.display = 'flex'; document.getElementById('overlay').classList.remove('active'); + document.getElementById('intro').classList.remove('hidden'); initAnchors(); updateCystinstein(); } +function startGame() { + gameStarted = true; + document.getElementById('intro').classList.add('hidden'); +} + function updateHudBest(best) { document.getElementById('highscore').textContent = best !== null ? `Best: ${best}` : 'Best: —'; } @@ -203,7 +211,7 @@ document.getElementById('player-name').addEventListener('keydown', e => { function gameLoop(ts) { drawBackground(); - if (!gameOver && ts - lastSpawn > spawnInterval) { + if (gameStarted && !gameOver && ts - lastSpawn > spawnInterval) { spawnAtom(); lastSpawn = ts; spawnInterval = Math.max(SPAWN_INTERVAL_MIN, spawnInterval - SPAWN_DIFFICULTY_STEP); @@ -221,6 +229,9 @@ function gameLoop(ts) { } // ─── Boot ──────────────────────────────────────────────────────────────────── +// Fill dynamic value in intro text +document.getElementById('intro').innerHTML = + document.getElementById('intro').innerHTML.replace('${MAX_DOCKS}', MAX_DOCKS); updateHudBest(topScore()); initAnchors(); updateCystinstein(); diff --git a/sys_digger/index.html b/sys_digger/index.html index 2c35f09..604e77e 100644 --- a/sys_digger/index.html +++ b/sys_digger/index.html @@ -15,7 +15,7 @@ font-family: 'Courier New', monospace; overflow: hidden; } - canvas { display: block; cursor: url("data:image/svg+xml,") 16 16, crosshair; } + canvas { display: block; cursor: url("data:image/svg+xml,") 16 16, auto; } #score { position: absolute; @@ -60,6 +60,83 @@ margin-top: 6px; } + /* ── Intro screen ── */ + #intro { + display: flex; + position: absolute; + top: 0; left: 0; + width: 100%; height: 100%; + background: rgba(0, 0, 0, 0.92); + justify-content: center; + align-items: center; + flex-direction: column; + color: white; + text-align: center; + padding: 40px 20px; + z-index: 10; + } + #intro.hidden { display: none; } + + #intro h1 { + font-size: 64px; + letter-spacing: 8px; + color: #00ff88; + text-shadow: 0 0 30px #00ff88, 0 0 60px #00ff8855; + margin-bottom: 6px; + animation: flicker 2s infinite alternate; + } + #intro .subtitle { + font-size: 15px; + letter-spacing: 4px; + color: #00ccff; + text-shadow: 0 0 10px #00ccff; + margin-bottom: 40px; + text-transform: uppercase; + } + #intro .instructions { + max-width: 480px; + margin-bottom: 40px; + display: flex; + flex-direction: column; + gap: 14px; + } + #intro .instruction-row { + display: flex; + align-items: center; + gap: 16px; + background: rgba(255,255,255,0.04); + border: 1px solid rgba(255,255,255,0.08); + border-radius: 8px; + padding: 12px 18px; + text-align: left; + } + #intro .instruction-icon { + font-size: 26px; + flex-shrink: 0; + width: 36px; + text-align: center; + } + #intro .instruction-text { + font-size: 13px; + color: #aaa; + line-height: 1.5; + } + #intro .instruction-text strong { color: #fff; } + #start-btn { + padding: 16px 52px; + font-size: 20px; + font-family: 'Courier New', monospace; + font-weight: bold; + background: #00ff88; + color: #000; + border: none; + border-radius: 8px; + cursor: pointer; + letter-spacing: 2px; + transition: background 0.2s, transform 0.1s; + } + #start-btn:hover { background: #00cc66; transform: scale(1.04); } + /* ── Game-over overlay ── */ #overlay { display: none; @@ -197,12 +274,41 @@
CYSTINSTEIN
-
0 / 8 docks
+
0 / 6 docks
Score: 0
Best: —
+
+

SYS DIGGER

+
Protect the atom
+ +
+
+
+
+ A molecule sits at the center of the screen with anchor points around it. +
+
+
+
💊
+
+ Click the glowing red anchor when an atom approaches to block the connection. +
+
+
+
🧫
+
+ Each missed dock grows the Cystinstein in the top-left. + Allow ${MAX_DOCKS} docks and it's fully formed — game over. +
+
+
+ + +
+

CYSTINSTEIN FORMED!