snake: improve mobile support

Hunter
Wednesday, July 23rd, 2025 at 6:28 PM

pages/snake/index.html+99-9

pages/snake/index.html
  3  	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
  4  	<title>SNAKE</title>
  5  	<style>
  6 +		* {
  7 +			box-sizing: border-box;
  8 +			user-select: none;
  9 +		}
 10 +		
 11  		body {
 12  			background-color: white;
 13  			font-family: Arial, sans-serif;
 14  			text-align: center;
 15  			margin: 0;
 16  			padding: 20px;
 17 +			overflow-x: hidden;
 18  		}
 19  		
 20  		h1 {

 22  		}
 23  		
 24  		#gameBoard {
    -			display: inline-block;
 25 +			display: inline-flex;
 26 +			flex-direction: column;
 27  			border: 2px solid #333;
    -			background-color: white;
    -			font-size: 16px;
 28 +			background-color: lightgrey;
 29  			line-height: 1;
 30  			font-family: monospace;
    -			max-width: 100vw;
 31  			overflow: hidden;
 32  		}
 33  		
 34  		.row {
    -			display: block;
 35 +			display: flex;
 36 +			margin: 0;
 37 +			padding: 0;
 38 +			gap: 0;
 39 +		}
 40 +		
 41 +		.cell {
 42 +			display: flex;
 43 +			align-items: center;
 44 +			justify-content: center;
 45 +			flex-shrink: 0;
 46  			margin: 0;
 47  			padding: 0;
 48  		}

110  			color: #333;
111  		}
112  		
113 +		@media (max-width: 400px) {
114 +			body {
115 +				padding: 10px;
116 +			}
117 +			
118 +			h1 {
119 +				font-size: 24px;
120 +				margin: 10px 0;
121 +			}
122 +			
123 +			#score, #highScore {
124 +				font-size: 16px;
125 +			}
126 +		}
127 +		
128 +		@media (max-width: 360px) {
129 +			body {
130 +				padding: 5px;
131 +			}
132 +			
133 +			h1 {
134 +				font-size: 20px;
135 +			}
136 +			
137 +			#score, #highScore {
138 +				font-size: 14px;
139 +			}
140 +		}
141 +		
142  		@media (pointer: none), (pointer: coarse) {
143  			#mobileControls {
144  				display: block;

168  			<div class="control-btn" id="leftBtn">◀️</div>
169  			<div class="control-btn" id="rightBtn">▶️</div>
170  			<div class="control-btn" id="downBtn">🔽</div>
    -			<div class="control-btn" id="centerBtn">🆕</div>
171 +			<div class="control-btn" id="centerBtn">🟢</div>
172  		</div>
173  		<div id="mobileGameOver"></div>
    -		<div id="mobileStartHint">Press 🆕 to start!</div>
174 +		<div id="mobileStartHint">Press 🟢 to start!</div>
175  	</div>
176  
177  	<script>

232  			board[apple.y][apple.x] = APPLE;
233  		}
234  		
235 +		function calculateCellSize() {
236 +			const padding = window.innerWidth <= 360 ? 10 : (window.innerWidth <= 400 ? 20 : 40);
237 +			const borderWidth = 4; // 2px border on each side
238 +			const availableWidth = window.innerWidth - padding - borderWidth;
239 +			const maxPossibleSize = Math.floor(availableWidth / BOARD_SIZE);
240 +			
241 +			// Use smaller, tighter cell sizes
242 +			let cellSize;
243 +			if (window.innerWidth <= 360) {
244 +				cellSize = Math.min(maxPossibleSize, 12);
245 +			} else if (window.innerWidth <= 400) {
246 +				cellSize = Math.min(maxPossibleSize, 14);
247 +			} else {
248 +				cellSize = Math.min(maxPossibleSize, 16);
249 +			}
250 +			
251 +			return Math.max(cellSize, 8); // Minimum cell size
252 +		}
253 +		
254 +		function updateBoardSize() {
255 +			const cellSize = calculateCellSize();
256 +			const fontSize = Math.max(Math.floor(cellSize * 0.9), 8);
257 +			
258 +			const gameBoard = document.getElementById('gameBoard');
259 +			gameBoard.style.width = 'auto';
260 +			gameBoard.style.display = 'inline-flex';
261 +			gameBoard.style.flexDirection = 'column';
262 +			
263 +			const cells = document.querySelectorAll('.cell');
264 +			cells.forEach(cell => {
265 +				cell.style.width = cellSize + 'px';
266 +				cell.style.height = cellSize + 'px';
267 +				cell.style.fontSize = fontSize + 'px';
268 +			});
269 +		}
270 +		
271  		function renderBoard() {
272  			const gameBoard = document.getElementById('gameBoard');
273  			gameBoard.innerHTML = '';

276  				const row = document.createElement('div');
277  				row.className = 'row';
278  				for (let x = 0; x < BOARD_SIZE; x++) {
    -					row.innerHTML += board[y][x];
279 +					const cell = document.createElement('div');
280 +					cell.className = 'cell';
281 +					cell.textContent = board[y][x];
282 +					row.appendChild(cell);
283  				}
284  				gameBoard.appendChild(row);
285  			}
286 +			
287 +			updateBoardSize();
288  		}
289  		
290  		function moveSnake() {

475  			}
476  		});
477  		
478 +		// Handle window resize and orientation changes
479 +		window.addEventListener('resize', () => {
480 +			updateBoardSize();
481 +		});
482 +		
483  		// Initialize game
484  		loadHighScore();
485  		initBoard();

490  		document.getElementById('startHint').style.display = 'block';
491  		document.getElementById('mobileStartHint').style.display = 'block';
492  		document.getElementById('centerBtn').style.display = 'block';
    -		document.getElementById('centerBtn').textContent = '🆕';
493 +		document.getElementById('centerBtn').textContent = '🟢';
494  	</script>
495  </body>
496  </html>