diff --git a/index.html b/index.html index 434434f..dc39bba 100644 --- a/index.html +++ b/index.html @@ -1,11 +1,14 @@ - - + + - - - + + + VIRTUAL_NATSUMATSURI diff --git a/src/components/Yatai/TargetOverlay.module.css b/src/components/Yatai/TargetOverlay.module.css index c285a00..d22ce22 100644 --- a/src/components/Yatai/TargetOverlay.module.css +++ b/src/components/Yatai/TargetOverlay.module.css @@ -1,12 +1,13 @@ .target { - position: absolute; - z-index: 1; - width: 100px; - height: 100px; - transform: translate(calc(-50%+50px), calc(-50%+50px)); + position: absolute; + z-index: 1; + width: 100px; + height: 100px; + transform: translate(calc(-50%+50px), calc(-50%+50px)); + transition: all 0.1s linear; } .image { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } diff --git a/src/components/Yatai/TargetOverlay.tsx b/src/components/Yatai/TargetOverlay.tsx index f5ffe29..ea05a42 100644 --- a/src/components/Yatai/TargetOverlay.tsx +++ b/src/components/Yatai/TargetOverlay.tsx @@ -1,10 +1,7 @@ import { useEffect, useState } from "react"; import { useSocketReceiver } from "../../hooks/useSocketReceiver"; -import { - type ActionSchema, - MessageType, - type Target, -} from "../../type/shooting"; +import type { ActionSchema, PointerSchema, Target } from "../../type/shooting"; +import { MessageType } from "../../type/shooting"; import styles from "./TargetOverlay.module.css"; export const TargetOverlay = () => { @@ -12,29 +9,27 @@ export const TargetOverlay = () => { useEffect(() => { onMessage((data) => { - // ここも本来はPointerSchemaになる if (data.message_type === MessageType.Action) { shotTarget(data); } + if (data.message_type === MessageType.Pointer) { + aimTarget(data); + } }); }, [onMessage]); // TODO: これらは一人用,いつかマルチプレイヤー対応する const [aim, setAim] = useState(undefined); - // TODO: エイム照準の実装 - // const aimTarget = (data: PointerSchema) => { - // const x = window.innerWidth * data.target.x + window.innerWidth / 2; - // const y = window.innerHeight * data.target.y + window.innerHeight / 2; - // setAim({ x, y }); - // }; + const aimTarget = (data: PointerSchema) => { + const x = window.innerWidth / 2 + data.target.x * 1200; + const y = window.innerHeight / 2 + data.target.y * 1200; + setAim({ x, y }); + }; - // const [target, setTarget] = useState(undefined); const shotTarget = (data: ActionSchema) => { const x = window.innerWidth / 2 + data.target.x * 1200; const y = window.innerHeight / 2 + data.target.y * 1200; - // TODO: エイム実装ができたらここのsetAimは削除する setAim({ x, y }); - // setTarget({ x, y }); }; return ( diff --git a/src/pages/shooter/index.tsx b/src/pages/shooter/index.tsx index e858016..49cd32a 100644 --- a/src/pages/shooter/index.tsx +++ b/src/pages/shooter/index.tsx @@ -1,21 +1,21 @@ -import { type KeyboardEventHandler, useEffect, useState } from "react"; +import { + type KeyboardEventHandler, + useCallback, + useEffect, + useState, +} from "react"; import { DefaultButton } from "../../components/ui/Button"; import { Modal } from "../../components/ui/Modal"; import { ShooterButton } from "../../components/ui/ShooterButton"; -import { useOrientation } from "../../hooks/useOrientation"; -import { useSocketReceiver } from "../../hooks/useSocketReceiver"; +import type { Orientation } from "../../hooks/useOrientation"; import { useSocketSender } from "../../hooks/useSocketSender"; import { useUUIDStore } from "../../store"; import { message_type } from "../../type/schema"; -import { MessageType } from "../../type/shooting"; import style from "./index.module.css"; const Shooter = () => { const [isOpen, setIsOpen] = useState(true); - const [score, setScore] = useState(0); - const { orientationDiff } = useOrientation(); const { sendData } = useSocketSender(); - const { onMessage } = useSocketReceiver(); const initialImages = [ "/2D_material/cork.webp", @@ -25,31 +25,49 @@ const Shooter = () => { const [images, setImages] = useState(initialImages); const uuid = useUUIDStore((state) => state.uuid); + // const intervalId = useRef(null); + const [initialOrientation, setInitialOrientation] = useState({ + alpha: 0, + beta: 0, + gamma: 0, + }); + const send = useCallback( + (event: DeviceOrientationEvent, msg_type: message_type) => { + if (!event.alpha || !event.beta || !event.gamma) { + return; + } + console.log(event.alpha, event.beta, event.gamma); + sendData(msg_type, uuid, { + alpha: initialOrientation + ? (event.gamma - initialOrientation.gamma) * 2 + : event.gamma, + beta: initialOrientation + ? event.beta - initialOrientation.beta + : event.beta, + }); + }, + [sendData, uuid, initialOrientation], + ); useEffect(() => { - let intervalId: number | null = null; - - intervalId = window.setInterval(() => { - sendData(message_type.status, uuid, orientationDiff); + const intervalId = setInterval(() => { + window.addEventListener( + "deviceorientation", + (event) => send(event, message_type.status), + { once: true }, + ); }, 100); - return () => { - if (intervalId !== null) { - clearInterval(intervalId); - } + clearInterval(intervalId); }; - }, [uuid, orientationDiff, sendData]); + }, [send]); - useEffect(() => { - onMessage((data) => { - if (data.message_type === MessageType.Hit && data.id === uuid) { - setScore((prevScore) => prevScore + 1); - console.log(score); - } - }); - }, [onMessage, uuid, score]); - - const handleClick = () => { + const handleClick = async () => { + window.addEventListener( + "deviceorientation", + (event) => send(event, message_type.action), + { once: true }, + ); const audio = new Audio("/sound/cork_sound.mp3"); audio .play() @@ -57,7 +75,6 @@ const Shooter = () => { .catch((error) => { console.error("オーディオの音が出なかった", error); }); - sendData(message_type.action, uuid, orientationDiff); setImages((prevImages) => prevImages.slice(1)); }; @@ -66,11 +83,15 @@ const Shooter = () => { handleClick(); } }; + console.log("hige"); return (
setIsOpen(false)}> - +
@@ -81,16 +102,36 @@ const Shooter = () => { コルクの残量を表示しています ))}
+

{initialOrientation.alpha}

+

{initialOrientation.beta}

+

{initialOrientation.gamma}

); }; type ModalContentProps = { setIsOpen: (isOpen: boolean) => void; + setInitialOrientation: (orientation: Orientation) => void; }; -const ModalContent: React.FC = ({ setIsOpen }) => { - const { reset } = useOrientation(); +const ModalContent: React.FC = ({ + setIsOpen, + setInitialOrientation, +}) => { + const handleClick = () => { + window.addEventListener( + "deviceorientation", + (event) => { + setInitialOrientation({ + alpha: event.alpha || 0, + beta: event.beta || 0, + gamma: event.gamma || 0, + }); + }, + { once: true }, + ); + setIsOpen(false); + }; return (
= ({ setIsOpen }) => { variant="outlined" color="red" size="md" - onClick={() => { - reset(); - setIsOpen(false); - }} + onClick={handleClick} > 置いたよ!