snake: don't repeatedly add inputs to buffer when held; mobile: slide controls
Hunter
Friday, August 1st, 2025 at 4:12 PM
493 }
494 }
495
496 + // Track key state to prevent hold repeats
497 + let keysPressed = {};
498 +
499 document.addEventListener('keydown', (event) => {
500 if (event.code === 'Space') {
501 if (!gameRunning) {
506
507 if (!gameRunning) return;
508
509 + // Only process if key wasn't already pressed
510 + if (keysPressed[event.code]) return;
511 + keysPressed[event.code] = true;
512 +
513 switch(event.code) {
514 case 'ArrowUp':
515 setDirection({x: 0, y: -1});
526 }
527 });
528
- // Mobile controls
529 + document.addEventListener('keyup', (event) => {
530 + keysPressed[event.code] = false;
531 + });
532 +
533 + // Mobile controls - Track which button was last triggered to prevent hold repeats
534 + let lastTriggeredButton = null;
535 +
536 + function handleTouchMove(e) {
537 + e.preventDefault();
538 + const touch = e.touches[0];
539 + const element = document.elementFromPoint(touch.clientX, touch.clientY);
540 + const button = element?.closest('.control-btn');
541 +
542 + if (button && button !== lastTriggeredButton) {
543 + lastTriggeredButton = button;
544 +
545 + if (gameRunning) {
546 + switch(button.id) {
547 + case 'upBtn':
548 + setDirection({x: 0, y: -1});
549 + break;
550 + case 'downBtn':
551 + setDirection({x: 0, y: 1});
552 + break;
553 + case 'leftBtn':
554 + setDirection({x: -1, y: 0});
555 + break;
556 + case 'rightBtn':
557 + setDirection({x: 1, y: 0});
558 + break;
559 + }
560 + } else if (button.id === 'centerBtn') {
561 + startGame();
562 + }
563 + }
564 + }
565 +
566 + function handleTouchEnd(e) {
567 + e.preventDefault();
568 + lastTriggeredButton = null;
569 + }
570 +
571 + // Add touch event listeners for sliding behavior
572 document.getElementById('upBtn').addEventListener('touchstart', (e) => {
573 e.preventDefault();
574 + lastTriggeredButton = e.target;
575 if (gameRunning) setDirection({x: 0, y: -1});
576 });
577 document.getElementById('downBtn').addEventListener('touchstart', (e) => {
578 e.preventDefault();
579 + lastTriggeredButton = e.target;
580 if (gameRunning) setDirection({x: 0, y: 1});
581 });
582 document.getElementById('leftBtn').addEventListener('touchstart', (e) => {
583 e.preventDefault();
584 + lastTriggeredButton = e.target;
585 if (gameRunning) setDirection({x: -1, y: 0});
586 });
587 document.getElementById('rightBtn').addEventListener('touchstart', (e) => {
588 e.preventDefault();
589 + lastTriggeredButton = e.target;
590 if (gameRunning) setDirection({x: 1, y: 0});
591 });
592 document.getElementById('centerBtn').addEventListener('touchstart', (e) => {
593 e.preventDefault();
- if (!gameRunning) {
- startGame();
- }
594 + lastTriggeredButton = e.target;
595 + if (!gameRunning) startGame();
596 });
597
598 + // Add global touch move and end listeners for sliding
599 + document.addEventListener('touchmove', handleTouchMove);
600 + document.addEventListener('touchend', handleTouchEnd);
601 +
602 // Handle window resize and orientation changes
603 window.addEventListener('resize', () => {
604 updateBoardSize();