From 559a177fefe562a9479f1a66018fac9eca29a397 Mon Sep 17 00:00:00 2001 From: RolandoDrRobot Date: Mon, 23 Jun 2025 20:24:45 -0600 Subject: [PATCH] Fix buttons --- client/dev-dist/sw.js | 2 +- .../src/components/SkyJumpMiniGame/index.tsx | 67 +++++++++++++++++++ .../SkyJumpMiniGame/inputHandler.ts | 56 +++++++++++++++- .../src/components/SkyJumpMiniGame/main.css | 13 +++- 4 files changed, 135 insertions(+), 3 deletions(-) diff --git a/client/dev-dist/sw.js b/client/dev-dist/sw.js index 0a3b451b..f05150d1 100644 --- a/client/dev-dist/sw.js +++ b/client/dev-dist/sw.js @@ -82,7 +82,7 @@ define(['./workbox-20a2f87f'], (function (workbox) { 'use strict'; "revision": "3ca0b8505b4bec776b69afdba2768812" }, { "url": "index.html", - "revision": "0.tvrddraj1fg" + "revision": "0.5vrb7bvaaug" }], {}); workbox.cleanupOutdatedCaches(); workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), { diff --git a/client/src/components/SkyJumpMiniGame/index.tsx b/client/src/components/SkyJumpMiniGame/index.tsx index 817d82bb..9a9fb5e6 100644 --- a/client/src/components/SkyJumpMiniGame/index.tsx +++ b/client/src/components/SkyJumpMiniGame/index.tsx @@ -18,6 +18,7 @@ import { PLATFORM_IMG_PATH, RESET_GAME_DELAY, ENERGY_TOAST_DURATION, + PLAYER_HORIZONTAL_SPEED, } from './gameConfig'; import { GameEngine } from './gameEngine'; @@ -284,6 +285,33 @@ const CanvasSkyJumpGame = forwardRef gameEngineRef.current?.isGameOver() ?? true, })); + // Direct button handlers as backup + const handleLeftButtonPress = useCallback(() => { + console.log('Left button pressed directly!'); + if (gameEngineRef.current && !gameEngineRef.current.isGameOver()) { + gameEngineRef.current.setPlayerVelocityX(-PLAYER_HORIZONTAL_SPEED); + gameEngineRef.current.setPlayerFacingDirection(false); + gameEngineRef.current.setTouchControlsPressed(true, -1); + } + }, []); + + const handleRightButtonPress = useCallback(() => { + console.log('Right button pressed directly!'); + if (gameEngineRef.current && !gameEngineRef.current.isGameOver()) { + gameEngineRef.current.setPlayerVelocityX(PLAYER_HORIZONTAL_SPEED); + gameEngineRef.current.setPlayerFacingDirection(true); + gameEngineRef.current.setTouchControlsPressed(true, 1); + } + }, []); + + const handleButtonRelease = useCallback(() => { + console.log('Button released directly!'); + if (gameEngineRef.current && !gameEngineRef.current.isGameOver()) { + gameEngineRef.current.setPlayerVelocityX(0); + gameEngineRef.current.setTouchControlsPressed(false, 0); + } + }, []); + return (
{ + e.preventDefault(); + handleLeftButtonPress(); + }} + onTouchEnd={(e) => { + e.preventDefault(); + handleButtonRelease(); + }} + onMouseDown={(e) => { + e.preventDefault(); + handleLeftButtonPress(); + }} + onMouseUp={(e) => { + e.preventDefault(); + handleButtonRelease(); + }} + onContextMenu={(e) => e.preventDefault()} > ←
{ + e.preventDefault(); + handleRightButtonPress(); + }} + onTouchEnd={(e) => { + e.preventDefault(); + handleButtonRelease(); + }} + onMouseDown={(e) => { + e.preventDefault(); + handleRightButtonPress(); + }} + onMouseUp={(e) => { + e.preventDefault(); + handleButtonRelease(); + }} + onContextMenu={(e) => e.preventDefault()} > →
@@ -359,6 +425,7 @@ const CanvasSkyJumpGame = forwardRef )} diff --git a/client/src/components/SkyJumpMiniGame/inputHandler.ts b/client/src/components/SkyJumpMiniGame/inputHandler.ts index edaabfb1..908d3f1f 100644 --- a/client/src/components/SkyJumpMiniGame/inputHandler.ts +++ b/client/src/components/SkyJumpMiniGame/inputHandler.ts @@ -6,7 +6,9 @@ export class InputHandler { private isMobileDevice: boolean = false; private usingGyroscope: boolean = false; private gyroscopePermission: PermissionState | null = null; - private onToggleGyroscope?: (isUsing: boolean) => void; + private onToggleGyroscope?: (isUsing: boolean) => void; + private touchLeftButton?: HTMLElement | null; + private touchRightButton?: HTMLElement | null; constructor(gameEngine: GameEngine, onToggleGyroscope?: (isUsing: boolean) => void) { this.gameEngine = gameEngine; @@ -23,18 +25,31 @@ export class InputHandler { ): void { this.isMobileDevice = isMobile; this.usingGyroscope = initialUsingGyro && this.isMobileDevice; + this.touchLeftButton = touchLeftButton; + this.touchRightButton = touchRightButton; document.addEventListener('keydown', this.handleKeyDown); document.addEventListener('keyup', this.handleKeyUp); if (this.isMobileDevice) { if (touchLeftButton && touchRightButton) { + // Touch events touchLeftButton.addEventListener('touchstart', (e) => this.handleTouchStart(-1, e as TouchEvent), { passive: false }); touchLeftButton.addEventListener('touchend', (e) => this.handleTouchEnd(e as TouchEvent), { passive: false }); touchRightButton.addEventListener('touchstart', (e) => this.handleTouchStart(1, e as TouchEvent), { passive: false }); touchRightButton.addEventListener('touchend', (e) => this.handleTouchEnd(e as TouchEvent), { passive: false }); + + // Mouse events as fallback (for devices that translate touch to mouse) + touchLeftButton.addEventListener('mousedown', (e) => this.handleMouseDown(-1, e), { passive: false }); + touchLeftButton.addEventListener('mouseup', (e) => this.handleMouseUp(e), { passive: false }); + touchRightButton.addEventListener('mousedown', (e) => this.handleMouseDown(1, e), { passive: false }); + touchRightButton.addEventListener('mouseup', (e) => this.handleMouseUp(e), { passive: false }); + + // Prevent context menu and text selection touchLeftButton.addEventListener('contextmenu', e => e.preventDefault()); touchRightButton.addEventListener('contextmenu', e => e.preventDefault()); + touchLeftButton.addEventListener('selectstart', e => e.preventDefault()); + touchRightButton.addEventListener('selectstart', e => e.preventDefault()); } if (this.usingGyroscope) this.requestOrientationPermissionInternal(); @@ -89,6 +104,26 @@ export class InputHandler { this.gameEngine.setPlayerVelocityX(0); }; + private handleMouseDown = (direction: number, e: MouseEvent): void => { + e.preventDefault(); + if (this.gameEngine.isGameOver() || this.usingGyroscope) return; + this.gameEngine.setTouchControlsPressed(true, direction); + if (direction === 1) { + this.gameEngine.setPlayerVelocityX(PLAYER_HORIZONTAL_SPEED); + this.gameEngine.setPlayerFacingDirection(true); + } else if (direction === -1) { + this.gameEngine.setPlayerVelocityX(-PLAYER_HORIZONTAL_SPEED); + this.gameEngine.setPlayerFacingDirection(false); + } + }; + + private handleMouseUp = (e: MouseEvent): void => { + e.preventDefault(); + if (this.gameEngine.isGameOver() || this.usingGyroscope) return; + this.gameEngine.setTouchControlsPressed(false, 0); + this.gameEngine.setPlayerVelocityX(0); + }; + private requestOrientationPermissionInternal = async (): Promise => { try { if (typeof (DeviceOrientationEvent as any).requestPermission === 'function') { @@ -165,6 +200,25 @@ export class InputHandler { document.removeEventListener('keyup', this.handleKeyUp); if (this.isMobileDevice) { + // Remove touch and mouse event listeners + if (this.touchLeftButton) { + this.touchLeftButton.removeEventListener('touchstart', (e) => this.handleTouchStart(-1, e as TouchEvent)); + this.touchLeftButton.removeEventListener('touchend', (e) => this.handleTouchEnd(e as TouchEvent)); + this.touchLeftButton.removeEventListener('mousedown', (e) => this.handleMouseDown(-1, e)); + this.touchLeftButton.removeEventListener('mouseup', (e) => this.handleMouseUp(e)); + this.touchLeftButton.removeEventListener('contextmenu', e => e.preventDefault()); + this.touchLeftButton.removeEventListener('selectstart', e => e.preventDefault()); + } + + if (this.touchRightButton) { + this.touchRightButton.removeEventListener('touchstart', (e) => this.handleTouchStart(1, e as TouchEvent)); + this.touchRightButton.removeEventListener('touchend', (e) => this.handleTouchEnd(e as TouchEvent)); + this.touchRightButton.removeEventListener('mousedown', (e) => this.handleMouseDown(1, e)); + this.touchRightButton.removeEventListener('mouseup', (e) => this.handleMouseUp(e)); + this.touchRightButton.removeEventListener('contextmenu', e => e.preventDefault()); + this.touchRightButton.removeEventListener('selectstart', e => e.preventDefault()); + } + if (this.gameEngine.isGyroControlsEnabled()) { window.removeEventListener('deviceorientation', this.handleDeviceOrientation); window.removeEventListener('deviceorientation', this.calibrateGyroscope); diff --git a/client/src/components/SkyJumpMiniGame/main.css b/client/src/components/SkyJumpMiniGame/main.css index 116dc9a3..861df024 100644 --- a/client/src/components/SkyJumpMiniGame/main.css +++ b/client/src/components/SkyJumpMiniGame/main.css @@ -76,8 +76,10 @@ font-size: 24px; user-select: none; touch-action: manipulation; - z-index: 100; + z-index: 10010; pointer-events: auto; + cursor: pointer; + -webkit-tap-highlight-color: transparent; } .skyjump-left-button { @@ -94,6 +96,15 @@ font-size: 32px; } +.skyjump-control-button:active { + background-color: #D5D5C1; + transform: scale(0.95); +} + +.skyjump-control-button:hover { + background-color: #F0F0E0; +} + /* Return (exit) button */ .skyjump-return-button { background-color: #ECECDA;