Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: arena.mjs responsive mobile button layout + stuck key prevention

- Add responsive button repositioning on screen reframe (portrait/landscape)
- Extract button initialization into initMobileButtons() helper
- Reset keyboard state + clear movement when cursor lock toggles to prevent stuck keys
- Buttons now reposition like baktok.mjs on device rotation

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

+74 -30
+74 -30
system/public/aesthetic.computer/disks/arena.mjs
··· 613 613 614 614 // ๐Ÿ“ฑ Create mobile control buttons using ui.Button (always enabled for testing/development) 615 615 if (screen && ui?.Button) { 616 - const btnSize = 28; 617 - const btnSizeWide = 56; // wider action buttons 618 - const gap = 4; // gap between buttons (no border overlap) 619 - const padding = 6; 620 - const bottomMargin = 6; 621 - 622 - // Movement buttons (bottom-left): D-pad style, compact layout 623 - const moveX = padding; 624 - const moveY = screen.height - (btnSize * 3 + gap * 2 + bottomMargin); 625 - 626 - // Action buttons (bottom-right): wider layout 627 - const actionX = screen.width - btnSizeWide - padding; 628 - const actionY = screen.height - (btnSize * 2 + gap + bottomMargin); 629 - 630 - // D-pad layout: 631 - // โ†‘ 632 - // โ† โ— โ†’ 633 - // โ†“ 634 - mobileButtons = { 635 - up: { btn: new ui.Button(moveX + btnSize + gap, moveY, btnSize, btnSize), key: "forward", label: "โ†‘", isArrow: true }, 636 - down: { btn: new ui.Button(moveX + btnSize + gap, moveY + (btnSize + gap) * 2, btnSize, btnSize), key: "back", label: "โ†“", isArrow: true }, 637 - left: { btn: new ui.Button(moveX, moveY + btnSize + gap, btnSize, btnSize), key: "left", label: "โ†", isArrow: true }, 638 - right: { btn: new ui.Button(moveX + (btnSize + gap) * 2, moveY + btnSize + gap, btnSize, btnSize), key: "right", label: "โ†’", isArrow: true }, 639 - jump: { btn: new ui.Button(actionX, actionY, btnSizeWide, btnSize), key: "jump", label: "JUMP", color: [50, 200, 100] }, 640 - crouch: { btn: new ui.Button(actionX, actionY + btnSize + gap, btnSizeWide, btnSize), key: "crouch", label: "CROUCH", color: [220, 150, 40] }, 641 - }; 642 - 616 + initMobileButtons(screen, ui); 643 617 } 644 618 645 619 // --- Vertex-colored checkerboard ground with fog --- ··· 1558 1532 } 1559 1533 } 1560 1534 1561 - function act({ event: e, penLock, system }) { 1562 - if (e.is("pen:locked")) penLocked = true; 1563 - if (e.is("pen:unlocked")) penLocked = false; 1535 + function act({ event: e, penLock, system, screen, ui }) { 1536 + if (e.is("pen:locked")) { 1537 + penLocked = true; 1538 + // Reset keyboard state to prevent stuck keys when cursor lock changes 1539 + resetKeyboardState(system); 1540 + } 1541 + if (e.is("pen:unlocked")) { 1542 + penLocked = false; 1543 + // Reset keyboard state to prevent stuck keys when cursor lock changes 1544 + resetKeyboardState(system); 1545 + } 1546 + 1547 + // ๐Ÿ“ฑ Reposition mobile buttons on screen resize/reframe 1548 + if (e.is("reframed")) { 1549 + if (screen && ui?.Button) { 1550 + initMobileButtons(screen, ui); 1551 + } 1552 + } 1564 1553 1565 1554 // ๐ŸŽฎ Gamepad โ€” Standard Gamepad mapping (Xbox 360/One/Series, PS, etc.). 1566 1555 // Events arrive as `gamepad:<idx>:button:<n>:push|release` and ··· 1743 1732 // Don't re-lock on middle-click (1) or right-click (2) โ€” reserved for camera control. 1744 1733 if (!penLocked && e.button !== 1 && e.button !== 2) penLock(); 1745 1734 } 1735 + } 1736 + 1737 + // โŒจ๏ธ Helper: Reset all keyboard state to prevent stuck keys 1738 + function resetKeyboardState(system) { 1739 + keyboardState.w = false; 1740 + keyboardState.a = false; 1741 + keyboardState.s = false; 1742 + keyboardState.d = false; 1743 + keyboardState.arrowup = false; 1744 + keyboardState.arrowdown = false; 1745 + keyboardState.arrowleft = false; 1746 + keyboardState.arrowright = false; 1747 + keyboardState.space = false; 1748 + keyboardState.shift = false; 1749 + 1750 + // Also clear movement from doll to stop any in-progress movement 1751 + const doll = system?.fps?.doll; 1752 + if (doll) { 1753 + doll.setMovement("forward", false); 1754 + doll.setMovement("back", false); 1755 + doll.setMovement("left", false); 1756 + doll.setMovement("right", false); 1757 + doll.setMovement("jump", false); 1758 + doll.setMovement("crouch", false); 1759 + } 1760 + } 1761 + 1762 + // ๐Ÿ“ฑ Helper: Initialize or reposition mobile buttons responsively 1763 + function initMobileButtons(screen, ui) { 1764 + const btnSize = 28; 1765 + const btnSizeWide = 56; // wider action buttons 1766 + const gap = 4; // gap between buttons (no border overlap) 1767 + const padding = 6; 1768 + const bottomMargin = 6; 1769 + 1770 + // Movement buttons (bottom-left): D-pad style, compact layout 1771 + const moveX = padding; 1772 + const moveY = screen.height - (btnSize * 3 + gap * 2 + bottomMargin); 1773 + 1774 + // Action buttons (bottom-right): wider layout 1775 + const actionX = screen.width - btnSizeWide - padding; 1776 + const actionY = screen.height - (btnSize * 2 + gap + bottomMargin); 1777 + 1778 + // D-pad layout: 1779 + // โ†‘ 1780 + // โ† โ— โ†’ 1781 + // โ†“ 1782 + mobileButtons = { 1783 + up: { btn: new ui.Button(moveX + btnSize + gap, moveY, btnSize, btnSize), key: "forward", label: "โ†‘", isArrow: true }, 1784 + down: { btn: new ui.Button(moveX + btnSize + gap, moveY + (btnSize + gap) * 2, btnSize, btnSize), key: "back", label: "โ†“", isArrow: true }, 1785 + left: { btn: new ui.Button(moveX, moveY + btnSize + gap, btnSize, btnSize), key: "left", label: "โ†", isArrow: true }, 1786 + right: { btn: new ui.Button(moveX + (btnSize + gap) * 2, moveY + btnSize + gap, btnSize, btnSize), key: "right", label: "โ†’", isArrow: true }, 1787 + jump: { btn: new ui.Button(actionX, actionY, btnSizeWide, btnSize), key: "jump", label: "JUMP", color: [50, 200, 100] }, 1788 + crouch: { btn: new ui.Button(actionX, actionY + btnSize + gap, btnSizeWide, btnSize), key: "crouch", label: "CROUCH", color: [220, 150, 40] }, 1789 + }; 1746 1790 } 1747 1791 1748 1792 export const system = "fps";