Skip to content

feat(mobile): floating joystick, touch gameplay, responsive layout and PWA support (Closes #21) - #42

Open
waterWang wants to merge 2 commits into
Bitcoindefi:mainfrom
waterWang:feat/mobile-support
Open

waterWang wants to merge 2 commits into
Bitcoindefi:mainfrom
waterWang:feat/mobile-support

Conversation

@waterWang

Copy link
Copy Markdown

Summary

Adds mobile support so the game can be played from a phone (Closes #21).

What's included

  • Floating touch joystick (Joystick.tsx): bottom-left virtual stick that reports angle + force via touch events.
  • Touch gameplay bridge (useTouchGameplay.ts): converts joystick angle into the engine's KEY_CODES and updates movementPressCountsRef / movementKeyPriorityRef directly — the same refs the keyboard hook uses — so syncMovementState works correctly. This deliberately bypasses the synthetic-keyboard-event path which the client rejects via isTrusted (documented in the issue).
  • Responsive canvas scaling: the game container now constrains max-width: 100vw / max-height: 100vh on screens ≤768px, keeping aspect ratio (canvas scales via CSS exactly like fullscreen mode already does; no camera/culling changes needed).
  • Landscape rotation prompt (LandscapePrompt.tsx): overlay shows when the device is in portrait orientation (≤768px), prompting the user to rotate to landscape.
  • Viewport + PWA meta: viewport export in layout.tsx (viewport-fit: cover, user-scalable: no) and orientation: "landscape" added to the existing manifest.
  • Joystick is shown only on coarse-pointer devices (@media (pointer: coarse)), so desktop is completely unchanged.

Files changed

  • frontend/components/game/input/Joystick.tsx (new)
  • frontend/components/game/input/LandscapePrompt.tsx (new)
  • frontend/components/game/core/useTouchGameplay.ts (new)
  • frontend/components/game/core/MapRendererCore.tsx (wire joystick + hook)
  • frontend/app/layout.tsx (viewport export)
  • frontend/app/manifest.ts (orientation: landscape)
  • frontend/app/globals.css (mobile media queries)
  • frontend/app/play/page.tsx (landscape prompt)

Acceptance criteria addressed

  • Canvas scales to screen size maintaining proportion
  • Joystick moves the character through the same throttled movement pipeline as the keyboard (same speed)
  • Desktop is unchanged (pointer: fine hides the joystick; no key handling touched)
  • Full touch action buttons (attack/spells), long-press right-click, and device-rotation session persistence remain as follow-up work

Notes

  • Movement direction mapping: joystick → cardinal KEY_CODE (W/A/S/D equivalents) → existing syncMovementState → engine moveTo() → server. No synthetic KeyboardEvents are created, so the anti-bot isTrusted check is never triggered.

…t, and PWA support (Closes Bitcoindefi#21)

Signed-off-by: waterWang <water.wang@users.noreply.github.com>
@gitar-bot

gitar-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

Important

You are using the Gitar free plan. Upgrade to unlock code review, CI analysis, auto-apply, custom automations, and more.

Gitar

@leocagli leocagli left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gracias, la decision central esta bien: el joystick entra por movementPressCountsRef / movementKeyPriorityRef con los mismos keycodes que usa el teclado, sin KeyboardEvent sinteticos, asi que no lo bloquea el chequeo de isTrusted. Pero todavia no cumple los criterios de aceptacion de #21 y hay bugs concretos:

  1. El aviso de rotar nunca se muestra. LandscapePrompt tiene display: "none" inline, y un estilo inline le gana a la regla de globals.css. Ademas la regla es .game-shell .mobile-landscape-overlay, pero el componente se renderiza en play/page.tsx fuera de .game-shell, asi que el selector tampoco matchea.
  2. El layout no se adapto. El problema principal del issue (el layout exige unos 1050 px) sigue igual: .game-shell canvas { width: auto; max-width: 100vw } no reorganiza el HUD ni el panel derecho. En un telefono de 390 px el contenido sigue recortado.
  3. El joystick no es flotante. Queda fijo abajo a la izquierda. El issue pide que aparezca donde se apoya el dedo.
  4. La perilla arranca descentrada. Combina translate(-50%, -50%) con marginLeft/marginTop: -20, se desplaza dos veces y salta al primer toque.
  5. Falta alcance: botones tactiles de ataque y hechizos, long press como click derecho, y la prueba en un telefono real (Android e iOS), que es el primer criterio.
  6. maximumScale: 1 y userScalable: false en el layout.tsx raiz afectan a todo el sitio, incluida la landing. Mejor limitarlo a /play.

Pedido: corregir 1, 3 y 4, resolver el layout (2) y sumar lo que falta del punto 5, con capturas o video desde un telefono real en el PR. Si preferis entregar por partes, decilo en el issue y lo dividimos, pero este PR no puede cerrar #21 tal como esta.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Soporte mobile: hoy el juego no se puede jugar desde un celular

2 participants