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 @@
+
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', () => {