From b1c8ee08ff44a5d12bdb3a2cc50c3afe54e070f5 Mon Sep 17 00:00:00 2001 From: Ku6epXBOCTuK Date: Thu, 25 Jun 2026 12:02:27 +0500 Subject: [PATCH] feat: update hud --- game.html | 2 +- js/game.js | 13 +---- js/main.js | 2 +- js/utils.js | 157 +++++++++++++++++++++++++++++++++------------------- style.css | 2 +- 5 files changed, 106 insertions(+), 70 deletions(-) diff --git a/game.html b/game.html index ff0c206..ea892d8 100644 --- a/game.html +++ b/game.html @@ -14,7 +14,7 @@
diff --git a/js/game.js b/js/game.js index 3744f88..8799ce0 100644 --- a/js/game.js +++ b/js/game.js @@ -113,7 +113,7 @@ function getEnemiesPerWave() { function takeDamage() { lives--; - document.getElementById("lives").textContent = lives; + document.getElementById("lives").textContent = "♡".repeat(CONFIG.game.startLives - lives) + "♥".repeat(lives); triggerShake(S.shakeDamage, S.shakeDamageDuration); document.getElementById("game-container").classList.add("glitch"); setTimeout( @@ -213,7 +213,7 @@ function startGame() { document.getElementById("score").textContent = score; document.getElementById("wave").textContent = wave; - document.getElementById("lives").textContent = lives; + document.getElementById("lives").textContent = "♡".repeat(CONFIG.game.startLives - lives) + "♥".repeat(lives); document.getElementById("start-screen").classList.add("hidden"); document.getElementById("gameover-screen").classList.add("hidden"); document.getElementById("ui-overlay").classList.remove("hidden"); @@ -317,15 +317,6 @@ function draw() { } ctx.save(); - ctx.fillStyle = CONFIG.colors.playerBase; - ctx.fillRect(0, H - S.inputAreaHeight, W, S.inputAreaHeight); - ctx.strokeStyle = CONFIG.colors.primary; - ctx.lineWidth = 1; - ctx.beginPath(); - ctx.moveTo(0, H - S.inputAreaHeight); - ctx.lineTo(W, H - S.inputAreaHeight); - ctx.stroke(); - ctx.fillStyle = CONFIG.colors.primary; ctx.shadowColor = CONFIG.colors.primary; ctx.shadowBlur = S.playerGlow; diff --git a/js/main.js b/js/main.js index 67bb02b..b5104c7 100644 --- a/js/main.js +++ b/js/main.js @@ -8,7 +8,7 @@ document.querySelector("#ui-overlay .ui-text:nth-child(2)").innerHTML = `${CONFIG.texts.waveLabel} 1`; document.querySelector("#ui-overlay .ui-text:nth-child(3)").innerHTML = - `${CONFIG.texts.livesLabel} 3`; + `${CONFIG.texts.livesLabel} ${"♥".repeat(CONFIG.game.startLives)}`; document.querySelector("#gameover-screen .screen-subtitle").innerHTML = `${CONFIG.texts.finalScoreLabel} 0`; diff --git a/js/utils.js b/js/utils.js index 04fd715..6d347b5 100644 --- a/js/utils.js +++ b/js/utils.js @@ -34,40 +34,85 @@ function recalc() { const R = CONFIG.visualRatio; const T = CONFIG.timing; - S.gridSize = Math.round(V.gridSize * W / 1000); - S.enemyPaddingX = Math.round(V.enemyPaddingX * W / 1000); - S.enemyAlienOffset = Math.round(V.enemyAlienOffset * W / 1000); - S.armorBarPad = Math.round(V.armorBarPad * W / 1000); - S.armorBarFont = Math.round(V.armorBarFont * W / 1000); - S.missTargetPadX = Math.round(V.missTargetPadX * W / 1000); - S.missTargetPadY = Math.round(V.missTargetPadY * H / 1000); - S.inputAreaHeight = Math.round(V.inputAreaHeight * H / 1000); - S.removeZone = Math.round(V.removeZone * H / 1000); + S.gridSize = Math.round((V.gridSize * W) / 1000); + S.enemyPaddingX = Math.round((V.enemyPaddingX * W) / 1000); + S.enemyAlienOffset = Math.round((V.enemyAlienOffset * W) / 1000); + S.armorBarPad = Math.round((V.armorBarPad * W) / 1000); + S.armorBarFont = Math.round((V.armorBarFont * W) / 1000); + S.missTargetPadX = Math.round((V.missTargetPadX * W) / 1000); + S.missTargetPadY = Math.round((V.missTargetPadY * H) / 1000); + S.inputAreaHeight = Math.round((V.inputAreaHeight * H) / 1000); + S.removeZone = Math.round((V.removeZone * H) / 1000); - for (const k of ["playerY","playerRadius","playerGlow","enemySimpleHeight","enemyHeavyHeight", - "enemySimpleFont","enemyHeavyFont","enemyArmorBarHeight","enemyArmorBarOffset", - "enemyArmorLabelOffset","enemyGlow","enemyFlashGlow","enemyLineWidth", - "projectileGlow","projectileHitRadius","projectileMissRadius","projectileFont", - "projectileCircleRadius","shakeHit","shakeMiss","shakeDamage","particleVel", - "particleSizeMin","particleSizeMax","particleGlow","trailSizeBase","trailSizeInc", - "trailGlow","shooterOffset"]) { - S[k] = Math.round(V[k] * H / 1000); + for (const k of [ + "playerY", + "playerRadius", + "playerGlow", + "enemySimpleHeight", + "enemyHeavyHeight", + "enemySimpleFont", + "enemyHeavyFont", + "enemyArmorBarHeight", + "enemyArmorBarOffset", + "enemyArmorLabelOffset", + "enemyGlow", + "enemyFlashGlow", + "enemyLineWidth", + "projectileGlow", + "projectileHitRadius", + "projectileMissRadius", + "projectileFont", + "projectileCircleRadius", + "shakeHit", + "shakeMiss", + "shakeDamage", + "particleVel", + "particleSizeMin", + "particleSizeMax", + "particleGlow", + "trailSizeBase", + "trailSizeInc", + "trailGlow", + "shooterOffset", + ]) { + S[k] = Math.round((V[k] * H) / 1000); } S.projectileSpeed = H / (CONFIG.speed.projectileCrossTime * 60); - S.gridSpeed = CONFIG.speed.gridSpeed * H / 1000; + S.gridSpeed = (CONFIG.speed.gridSpeed * H) / 1000; - for (const k of ["projectileTrailLength","particleHit","particleMiss", - "particleDestroySimple","particleDestroyHeavy","particleArmorBreak", - "flashDuration","shakeHitDuration","shakeMissDuration","shakeDamageDuration", - "trailMaxLength","trailDecay","trailAlpha"]) { + for (const k of [ + "projectileTrailLength", + "particleHit", + "particleMiss", + "particleDestroySimple", + "particleDestroyHeavy", + "particleArmorBreak", + "flashDuration", + "shakeHitDuration", + "shakeMissDuration", + "shakeDamageDuration", + "trailMaxLength", + "trailDecay", + "trailAlpha", + ]) { S[k] = C[k]; } - for (const k of ["missTargetYRange","projectileTrailLength","projectileTrailDecay", - "projectileTrailAlpha","projectileCircleAlpha","enemyPulseRate","enemyAlphaBase", - "enemyAlphaRange","enemyGlowPulse","particleDecayBase","particleDecayRange", - "particleDamping"]) { + for (const k of [ + "missTargetYRange", + "projectileTrailLength", + "projectileTrailDecay", + "projectileTrailAlpha", + "projectileCircleAlpha", + "enemyPulseRate", + "enemyAlphaBase", + "enemyAlphaRange", + "enemyGlowPulse", + "particleDecayBase", + "particleDecayRange", + "particleDamping", + ]) { S[k] = R[k]; } @@ -79,67 +124,67 @@ function recalc() { function applyOverlayScale(W, H) { const title = document.querySelector(".screen-title"); - if (title) title.style.fontSize = Math.round(40 * H / 1000) + "px"; + if (title) title.style.fontSize = Math.round((40 * H) / 1000) + "px"; const subs = document.querySelectorAll(".screen-subtitle"); - for (let el of subs) el.style.fontSize = Math.round(18 * H / 1000) + "px"; + for (let el of subs) el.style.fontSize = Math.round((18 * H) / 1000) + "px"; const overlay = document.getElementById("ui-overlay"); if (overlay) { - overlay.style.padding = Math.round(12 * H / 1000) + "px " + Math.round(16 * W / 1000) + "px"; - overlay.style.fontSize = Math.round(14 * H / 1000) + "px"; - } - const inputDisplay = document.getElementById("input-display"); - if (inputDisplay) { - inputDisplay.style.padding = Math.round(14 * H / 1000) + "px " + Math.round(16 * W / 1000) + "px"; + overlay.style.padding = Math.round((12 * H) / 1000) + "px " + Math.round((16 * W) / 1000) + "px"; + overlay.style.fontSize = Math.round((28 * H) / 1000) + "px"; } + // const inputDisplay = document.getElementById("input-display"); + // if (inputDisplay) { + // inputDisplay.style.padding = Math.round(14 * H / 1000) + "px " + Math.round(16 * W / 1000) + "px"; + // } const typed = document.getElementById("typed-text"); if (typed) { - typed.style.fontSize = Math.round(20 * H / 1000) + "px"; - typed.style.minHeight = Math.round(28 * H / 1000) + "px"; + typed.style.fontSize = Math.round((20 * H) / 1000) + "px"; + typed.style.minHeight = Math.round((28 * H) / 1000) + "px"; } const chatText = document.getElementById("chat-text"); if (chatText) { - chatText.style.fontSize = Math.round(16 * H / 1000) + "px"; - chatText.style.minHeight = Math.round(28 * H / 1000) + "px"; + chatText.style.fontSize = Math.round((16 * H) / 1000) + "px"; + chatText.style.minHeight = Math.round((28 * H) / 1000) + "px"; } const chForm = document.getElementById("channel-form"); if (chForm) { - chForm.querySelector(".screen-title").style.fontSize = Math.round(80 * H / 1000) + "px"; + chForm.querySelector(".screen-title").style.fontSize = Math.round((80 * H) / 1000) + "px"; const inp = chForm.querySelector("input"); if (inp) { - inp.style.fontSize = Math.round(22 * H / 1000) + "px"; - inp.style.padding = Math.round(12 * H / 1000) + "px " + Math.round(20 * W / 1000) + "px"; - inp.style.width = Math.round(300 * W / 1000) + "px"; + inp.style.fontSize = Math.round((22 * H) / 1000) + "px"; + inp.style.padding = Math.round((12 * H) / 1000) + "px " + Math.round((20 * W) / 1000) + "px"; + inp.style.width = Math.round((300 * W) / 1000) + "px"; } const btn = chForm.querySelector("button"); if (btn) { - btn.style.fontSize = Math.round(18 * H / 1000) + "px"; - btn.style.padding = Math.round(10 * H / 1000) + "px " + Math.round(40 * W / 1000) + "px"; - btn.style.minWidth = Math.round(260 * W / 1000) + "px"; + btn.style.fontSize = Math.round((18 * H) / 1000) + "px"; + btn.style.padding = Math.round((10 * H) / 1000) + "px " + Math.round((40 * W) / 1000) + "px"; + btn.style.minWidth = Math.round((260 * W) / 1000) + "px"; } const link = document.getElementById("game-link"); - if (link) link.style.fontSize = Math.round(16 * H / 1000) + "px"; + if (link) link.style.fontSize = Math.round((16 * H) / 1000) + "px"; const note = chForm.querySelector(".obs-note"); - if (note) note.style.fontSize = Math.round(16 * H / 1000) + "px"; + if (note) note.style.fontSize = Math.round((16 * H) / 1000) + "px"; } const goTitle = document.getElementById("gameover-title"); - if (goTitle) goTitle.style.fontSize = Math.round(64 * H / 1000) + "px"; + if (goTitle) goTitle.style.fontSize = Math.round((64 * H) / 1000) + "px"; const goSubs = document.querySelectorAll("#gameover-screen .screen-subtitle"); - for (let el of goSubs) el.style.fontSize = Math.round(28 * H / 1000) + "px"; + for (let el of goSubs) el.style.fontSize = Math.round((28 * H) / 1000) + "px"; const statsTitle = document.querySelectorAll(".stats-section-title"); - for (let el of statsTitle) el.style.fontSize = Math.round(28 * H / 1000) + "px"; + for (let el of statsTitle) el.style.fontSize = Math.round((28 * H) / 1000) + "px"; const statsTop1 = document.querySelectorAll(".stats-top1"); - for (let el of statsTop1) el.style.fontSize = Math.round(48 * H / 1000) + "px"; + for (let el of statsTop1) el.style.fontSize = Math.round((48 * H) / 1000) + "px"; const statsTop2 = document.querySelectorAll(".stats-top2"); - for (let el of statsTop2) el.style.fontSize = Math.round(36 * H / 1000) + "px"; + for (let el of statsTop2) el.style.fontSize = Math.round((36 * H) / 1000) + "px"; const statsTop3 = document.querySelectorAll(".stats-top3"); - for (let el of statsTop3) el.style.fontSize = Math.round(28 * H / 1000) + "px"; + for (let el of statsTop3) el.style.fontSize = Math.round((28 * H) / 1000) + "px"; const statsRow = document.querySelectorAll(".stats-row:not(.stats-top1):not(.stats-top2):not(.stats-top3)"); - for (let el of statsRow) el.style.fontSize = Math.round(24 * H / 1000) + "px"; + for (let el of statsRow) el.style.fontSize = Math.round((24 * H) / 1000) + "px"; const mazila = document.querySelectorAll(".stats-mazila"); - for (let el of mazila) el.style.fontSize = Math.round(28 * H / 1000) + "px"; + for (let el of mazila) el.style.fontSize = Math.round((28 * H) / 1000) + "px"; const crown = document.querySelectorAll(".stats-crown"); - for (let el of crown) el.style.fontSize = Math.round(56 * H / 1000) + "px"; + for (let el of crown) el.style.fontSize = Math.round((56 * H) / 1000) + "px"; } function drawGrid() { diff --git a/style.css b/style.css index bbece11..6b20fad 100644 --- a/style.css +++ b/style.css @@ -61,7 +61,7 @@ body { } .ui-text { color: #00ff41; - font-size: 14px; + font-size: 28px; text-shadow: 0 0 8px #00ff41; letter-spacing: 1px; }