diff --git a/apps/client/src/scenes/game/GameView.tsx b/apps/client/src/scenes/game/GameView.tsx index a1c5732..7aa33b6 100644 --- a/apps/client/src/scenes/game/GameView.tsx +++ b/apps/client/src/scenes/game/GameView.tsx @@ -3,7 +3,7 @@ * ゲーム画面の描画専用コンポーネント * タイマー表示,PixiJSの描画領域,入力UIの配置のみを担当する */ -import { Joystick } from "./input/joystick/Joystick"; +import { JoystickInputLayer } from "./input/joystick/JoystickInputLayer"; /** 表示と入力に必要なプロパティ */ type Props = { @@ -51,7 +51,7 @@ {/* UI 配置領域 */}
- +
); diff --git a/apps/client/src/scenes/game/input/joystick/Joystick.tsx b/apps/client/src/scenes/game/input/joystick/Joystick.tsx deleted file mode 100644 index 691c5cc..0000000 --- a/apps/client/src/scenes/game/input/joystick/Joystick.tsx +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Joystick - * 画面上のジョイスティックUIの入口 - * ポインターイベントを受け取り,useJoystick に処理を委譲し,描画は JoystickView に渡す - */ -import { JoystickView } from "./JoystickView"; -import { MAX_DIST, useJoystick } from "./useJoystick"; - -/** 入力半径の既定値を外部から参照できるように再公開 */ -export { MAX_DIST } from "./useJoystick"; - -/** Joystick コンポーネントの入力コールバック */ -type Props = { - onInput: (moveX: number, moveY: number) => void; -}; - -/** ポインター入力と描画を結びつけるジョイスティックUI */ -export const Joystick = ({ onInput }: Props) => { - const { isMoving, center, knobOffset, radius, handleStart, handleMove, handleEnd } = - useJoystick({ onInput }); - - return ( -
- {/* 見た目のみの描画(入力は扱わない) */} - -
- ); -}; \ No newline at end of file diff --git a/apps/client/src/scenes/game/input/joystick/JoystickCoordinator.tsx b/apps/client/src/scenes/game/input/joystick/JoystickCoordinator.tsx new file mode 100644 index 0000000..bf5f96f --- /dev/null +++ b/apps/client/src/scenes/game/input/joystick/JoystickCoordinator.tsx @@ -0,0 +1,35 @@ +/** + * JoystickCoordinator + * JoystickInputLayer からの入力を受け取り,処理と描画をまとめて仲介する + * 入力処理は useJoystick に委譲し,描画は JoystickView に委譲する + */ +import type React from "react"; +import { JoystickView } from "./JoystickView"; +import { useJoystick } from "./useJoystick"; + +/** JoystickCoordinator が提供する描画用データと入力ハンドラ */ +type RenderProps = { + view: React.ReactNode; + handleStart: (e: React.TouchEvent | React.MouseEvent) => void; + handleMove: (e: React.TouchEvent | React.MouseEvent) => void; + handleEnd: () => void; +}; + +/** 表示に必要な座標と状態 */ +type Props = { + onInput: (moveX: number, moveY: number) => void; + maxDist?: number; + children: (props: RenderProps) => React.ReactNode; +}; + +/** 受け取った入力から描画用の状態を生成し,描画を仲介する */ +export const JoystickCoordinator = ({ onInput, maxDist, children }: Props) => { + const { isMoving, center, knobOffset, radius, handleStart, handleMove, handleEnd } = + useJoystick({ onInput, maxDist }); + + const view = ( + + ); + + return <>{children({ view, handleStart, handleMove, handleEnd })}; +}; diff --git a/apps/client/src/scenes/game/input/joystick/JoystickInputLayer.tsx b/apps/client/src/scenes/game/input/joystick/JoystickInputLayer.tsx new file mode 100644 index 0000000..37bce33 --- /dev/null +++ b/apps/client/src/scenes/game/input/joystick/JoystickInputLayer.tsx @@ -0,0 +1,47 @@ +/** + * JoystickInputLayer + * 画面上のジョイスティック入力レイヤーの入口 + * 入力イベントの受け口として JoystickCoordinator に処理を委譲する + */ +import { JoystickCoordinator } from "./JoystickCoordinator"; + +/** 入力半径の既定値を外部から参照できるように再公開 */ +export { MAX_DIST } from "./joystick.constants"; + +/** JoystickInputLayer の入力コールバック */ +type Props = { + onInput: (moveX: number, moveY: number) => void; + maxDist?: number; +}; + +/** 入力の入口として配線を行う */ +export const JoystickInputLayer = ({ onInput, maxDist }: Props) => { + return ( + + {({ view, handleStart, handleMove, handleEnd }) => ( +
+ {/* 入力イベントを仲介へ渡し,出力は別レイヤーで処理する */} + {view} +
+ )} +
+ ); +}; \ No newline at end of file diff --git a/apps/client/src/scenes/game/input/joystick/JoystickView.tsx b/apps/client/src/scenes/game/input/joystick/JoystickView.tsx index 5ef2feb..ef316d9 100644 --- a/apps/client/src/scenes/game/input/joystick/JoystickView.tsx +++ b/apps/client/src/scenes/game/input/joystick/JoystickView.tsx @@ -3,7 +3,7 @@ * ジョイスティックの見た目だけを描画するコンポーネント * 入力処理は持たず,受け取った座標情報をもとにUIを描く */ -type Point = { x: number; y: number }; +import type { Point } from "./joystick.types"; /** 表示に必要な座標と状態 */ type Props = { diff --git a/apps/client/src/scenes/game/input/joystick/joystick.constants.ts b/apps/client/src/scenes/game/input/joystick/joystick.constants.ts new file mode 100644 index 0000000..88b2d7b --- /dev/null +++ b/apps/client/src/scenes/game/input/joystick/joystick.constants.ts @@ -0,0 +1,8 @@ +/** + * joystick.constants + * ジョイスティック入力に関する定数をまとめる + * 共有する半径の既定値などを定義する + */ + +/** UI側と共有する最大半径の既定値 */ +export const MAX_DIST = 60; diff --git a/apps/client/src/scenes/game/input/joystick/joystick.types.ts b/apps/client/src/scenes/game/input/joystick/joystick.types.ts new file mode 100644 index 0000000..9c7ce8d --- /dev/null +++ b/apps/client/src/scenes/game/input/joystick/joystick.types.ts @@ -0,0 +1,8 @@ +/** + * joystick.types + * ジョイスティック入力で使う型をまとめる + * 座標や入力の共通表現を定義する + */ + +/** 2D座標の簡易型 */ +export type Point = { x: number; y: number }; diff --git a/apps/client/src/scenes/game/input/joystick/useJoystick.ts b/apps/client/src/scenes/game/input/joystick/useJoystick.ts index c8b0236..fe503e6 100644 --- a/apps/client/src/scenes/game/input/joystick/useJoystick.ts +++ b/apps/client/src/scenes/game/input/joystick/useJoystick.ts @@ -5,9 +5,8 @@ */ import { useCallback, useState } from "react"; import type React from "react"; - -/** UI側と共有する最大半径の既定値 */ -export const MAX_DIST = 60; +import { MAX_DIST } from "./joystick.constants"; +import type { Point } from "./joystick.types"; /** フックに渡す入力コールバックと設定 */ type Props = { @@ -15,9 +14,6 @@ maxDist?: number; }; -/** 2D座標の簡易型 */ -type Point = { x: number; y: number }; - /** フックが返すUI向けの状態とハンドラ */ type UseJoystickReturn = { isMoving: boolean;