From 79127dc8316d07301699a8218b4f26c76f70d45b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 05:25:22 +0000 Subject: [PATCH 1/3] fix: mobile on-screen buttons, reduce spacing, add pause button Agent-Logs-Url: https://github.com/armin-l/Snake/sessions/d6ee5583-15f2-43a2-a8f9-eb8784b246b0 Co-authored-by: armin-l <107995326+armin-l@users.noreply.github.com> --- index.html | 1 + snake.css | 5 +++++ snake.js | 22 +++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/index.html b/index.html index 280736a..1e4c9c4 100644 --- a/index.html +++ b/index.html @@ -91,6 +91,7 @@

Perks

+ diff --git a/snake.css b/snake.css index 1093816..e306422 100644 --- a/snake.css +++ b/snake.css @@ -145,6 +145,7 @@ canvas { display: block; border-radius: 4px; } #btn-left { grid-column: 1; grid-row: 2; } #btn-down { grid-column: 2; grid-row: 2; } #btn-right { grid-column: 3; grid-row: 2; } +#btn-pause { grid-column: 3; grid-row: 1; font-size: 1rem; } #hint { margin-top: 14px; font-size: 0.8rem; color: #555; } @@ -798,4 +799,8 @@ canvas { display: block; border-radius: 4px; } /* Reset canvas-wrapper order */ #canvas-wrapper { order: unset; } + + /* Bring controls closer to the canvas */ + #effects-bar { margin-top: 4px; } + #controls { margin-top: 6px; } } diff --git a/snake.js b/snake.js index 375f1ec..07487b5 100644 --- a/snake.js +++ b/snake.js @@ -83,6 +83,7 @@ const DOM = { btnDown: getElement('btn-down'), btnLeft: getElement('btn-left'), btnRight: getElement('btn-right'), + btnPause: getElement('btn-pause'), nameEntryOverlay: getElement('name-entry-overlay'), neRank: getElement('ne-rank'), nc0: getElement('nc0'), @@ -834,6 +835,7 @@ function startGame() { init(); draw(); DOM.overlay.style.display = 'none'; + DOM.btnPause.textContent = '\u23F8'; running = true; lastTime = performance.now(); accumulated = 0; @@ -847,6 +849,12 @@ function enqueueDir(directionName) { if (dirQueue.length < 3) dirQueue.push(DIR[directionName]); } +function togglePause() { + if (!running) return; + paused = !paused; + DOM.btnPause.textContent = paused ? '\u23F5' : '\u23F8'; +} + function tryDir(directionName) { if (!running) return; enqueueDir(directionName); @@ -925,7 +933,7 @@ function onKeyDown(event) { return; } if (event.key === 'p' || event.key === 'P') { - paused = !paused; + togglePause(); return; } @@ -937,6 +945,7 @@ function onKeyDown(event) { } function onTouchStart(event) { + if (event.target.closest('.ctrl-btn')) return; touchStartX = event.touches[0].clientX; touchStartY = event.touches[0].clientY; const levelupOpen = DOM.levelupOverlay.style.display !== 'none'; @@ -946,6 +955,7 @@ function onTouchStart(event) { function onTouchEnd(event) { if (DOM.infoDrawer.classList.contains('open')) return; if (DOM.levelupOverlay.style.display !== 'none') return; + if (event.target.closest('.ctrl-btn')) return; const dx = event.changedTouches[0].clientX - touchStartX; const dy = event.changedTouches[0].clientY - touchStartY; if (Math.abs(dx) < 10 && Math.abs(dy) < 10) return; @@ -982,6 +992,16 @@ function wireEvents() { DOM.btnDown.addEventListener('click', () => tryDir('DOWN')); DOM.btnLeft.addEventListener('click', () => tryDir('LEFT')); DOM.btnRight.addEventListener('click', () => tryDir('RIGHT')); + [ + [DOM.btnUp, () => tryDir('UP')], + [DOM.btnDown, () => tryDir('DOWN')], + [DOM.btnLeft, () => tryDir('LEFT')], + [DOM.btnRight, () => tryDir('RIGHT')], + [DOM.btnPause, () => togglePause()], + ].forEach(([btn, handler]) => { + btn.addEventListener('touchstart', (e) => { e.preventDefault(); handler(); }, { passive: false }); + }); + DOM.btnPause.addEventListener('click', togglePause); DOM.startBtn.addEventListener('click', startGame); DOM.devPerkBtn.addEventListener('click', () => { From 87c9c12bde422a8522b0c117f935e6dc1a7991f2 Mon Sep 17 00:00:00 2001 From: armin-l <107995326+armin-l@users.noreply.github.com> Date: Mon, 27 Apr 2026 20:43:34 +0200 Subject: [PATCH 2/3] Update index.html Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 1e4c9c4..ae3938c 100644 --- a/index.html +++ b/index.html @@ -91,7 +91,7 @@

Perks

- + From 645bc58f3cebb0f7b3c51a40ec9ff2b50eefed2b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Apr 2026 18:45:31 +0000 Subject: [PATCH 3/3] refactor: deduplicate ctrl-btn event wiring, guard closest() with instanceof check Agent-Logs-Url: https://github.com/armin-l/Snake/sessions/04827a4b-9a8e-40f5-a406-ecacee22e6bc Co-authored-by: armin-l <107995326+armin-l@users.noreply.github.com> --- snake.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/snake.js b/snake.js index 07487b5..4e35350 100644 --- a/snake.js +++ b/snake.js @@ -944,8 +944,12 @@ function onKeyDown(event) { enqueueDir(directionName); } +function isCtrlBtn(target) { + return target instanceof Element && !!target.closest('.ctrl-btn'); +} + function onTouchStart(event) { - if (event.target.closest('.ctrl-btn')) return; + if (isCtrlBtn(event.target)) return; touchStartX = event.touches[0].clientX; touchStartY = event.touches[0].clientY; const levelupOpen = DOM.levelupOverlay.style.display !== 'none'; @@ -955,7 +959,7 @@ function onTouchStart(event) { function onTouchEnd(event) { if (DOM.infoDrawer.classList.contains('open')) return; if (DOM.levelupOverlay.style.display !== 'none') return; - if (event.target.closest('.ctrl-btn')) return; + if (isCtrlBtn(event.target)) return; const dx = event.changedTouches[0].clientX - touchStartX; const dy = event.changedTouches[0].clientY - touchStartY; if (Math.abs(dx) < 10 && Math.abs(dy) < 10) return; @@ -988,20 +992,16 @@ function wireEvents() { } }); - DOM.btnUp.addEventListener('click', () => tryDir('UP')); - DOM.btnDown.addEventListener('click', () => tryDir('DOWN')); - DOM.btnLeft.addEventListener('click', () => tryDir('LEFT')); - DOM.btnRight.addEventListener('click', () => tryDir('RIGHT')); [ - [DOM.btnUp, () => tryDir('UP')], - [DOM.btnDown, () => tryDir('DOWN')], - [DOM.btnLeft, () => tryDir('LEFT')], + [DOM.btnUp, () => tryDir('UP')], + [DOM.btnDown, () => tryDir('DOWN')], + [DOM.btnLeft, () => tryDir('LEFT')], [DOM.btnRight, () => tryDir('RIGHT')], [DOM.btnPause, () => togglePause()], ].forEach(([btn, handler]) => { + btn.addEventListener('click', handler); btn.addEventListener('touchstart', (e) => { e.preventDefault(); handler(); }, { passive: false }); }); - DOM.btnPause.addEventListener('click', togglePause); DOM.startBtn.addEventListener('click', startGame); DOM.devPerkBtn.addEventListener('click', () => {