diff --git a/packages/app/src/components/app/play/index.jsx b/packages/app/src/components/app/play/index.jsx index acbea57..e0331f6 100644 --- a/packages/app/src/components/app/play/index.jsx +++ b/packages/app/src/components/app/play/index.jsx @@ -1,9 +1,63 @@ -import {React} from '@flecks/react'; +import {InputNormalizer} from '@avocado/input/client'; +import { + React, + useEffect, +} from '@flecks/react'; +import {useDispatch} from '@flecks/redux'; +import {useSocket} from '@flecks/socket'; +import {setSelfEntity} from '@humus/app/state'; + +import { + useSelfEntity, +} from '../../../hooks'; import Renderable from './renderable'; import Ui from './ui'; function Play() { + const dispatch = useDispatch(); + const selfEntity = useSelfEntity(); + const socket = useSocket(); + // Join. + useEffect(() => { + const join = async () => { + dispatch(setSelfEntity(await socket.send(['Join']))); + }; + join(); + socket.on('reconnect', join); + return () => { + socket.off('reconnect', join); + }; + }, [dispatch, socket]); + // Input. + useEffect(() => { + if (!selfEntity) { + return undefined; + } + const inputNormalizer = new InputNormalizer(); + inputNormalizer.listen(window.document.body); + selfEntity.listenForInput(inputNormalizer); + selfEntity.actionRegistry.setTransformerFor('UseItem', (type, value) => { + switch (type) { + case 'joystick': + return value === 0 ? -1 : selfEntity.activeSlotIndex; + case 'buttonPress': + case 'keyDown': + return selfEntity.activeSlotIndex; + default: + return -1; + } + }); + const inputHandle = setInterval(() => { + const actionStream = selfEntity.drainInput(); + if (actionStream.length > 0) { + socket.send(['Input', actionStream]); + } + }, 1000 / 60); + return () => { + clearInterval(inputHandle); + }; + }, [selfEntity, socket]); return ( <> diff --git a/packages/app/src/components/app/play/ui/index.jsx b/packages/app/src/components/app/play/ui/index.jsx index 9ac4376..165810a 100644 --- a/packages/app/src/components/app/play/ui/index.jsx +++ b/packages/app/src/components/app/play/ui/index.jsx @@ -1,6 +1,3 @@ -import './index.scss'; - -import {InputNormalizer} from '@avocado/input/client'; import {Vector} from '@avocado/math'; import {Room} from '@avocado/topdown'; import { @@ -10,11 +7,6 @@ import { useRef, useState, } from '@flecks/react'; -import {useDispatch} from '@flecks/redux'; -import {useSocket} from '@flecks/socket'; -import { - setSelfEntity, -} from '@humus/app/state'; import { useRoom, @@ -23,83 +15,47 @@ import { import Hotbar from './hotbar'; const PlayUi = () => { - const dispatch = useDispatch(); const flecks = useFlecks(); const ref = useRef(); const room = useRoom(); const selfEntity = useSelfEntity(); - const socket = useSocket(); - const [left, setLeft] = useState(0); - const [top, setTop] = useState(0); + const [position, setPosition] = useState([0, 0]); const [domScale, setDomScale] = useState([1, 1]); + // Handle camera changes. useEffect(() => { if (!room || !selfEntity) { return undefined; } + // Initial snap camera to position. selfEntity.camera.realPosition = selfEntity.camera.position; const onCameraRealOffsetChanged = () => { - const [left, top] = Vector.scale(selfEntity.camera.realOffset, -1); - const {resolution} = flecks.get('@humus/app'); - setDomScale(Vector.div(resolution, selfEntity.camera.viewSize)); - setLeft(left); - setTop(top); + setPosition(Vector.scale(selfEntity.camera.realOffset, -1)); + }; + const onCameraViewSizeChanged = () => { + setDomScale(Vector.div(flecks.get('@humus/app.resolution'), selfEntity.camera.viewSize)); }; onCameraRealOffsetChanged(); + onCameraViewSizeChanged(); selfEntity.camera.on('realOffsetChanged', onCameraRealOffsetChanged); + selfEntity.camera.on('viewSizeChanged', onCameraViewSizeChanged); return () => { - const {camera} = selfEntity || {}; + const {camera} = selfEntity; if (camera) { - camera.off('realOffsetChanged', onCameraRealOffsetChanged); + camera.off('realOffsetChanged', onCameraViewSizeChanged); + camera.off('viewSizeChanged', onCameraViewSizeChanged); } }; }, [flecks, room, selfEntity]); + // Focus. useEffect(() => { - const join = async () => { - dispatch(setSelfEntity(await socket.send(['Join']))); - }; - join(); - socket.on('reconnect', join); - return () => { - socket.off('reconnect', join); - }; - }, [dispatch, socket]); - useEffect(() => { - if (!ref.current || !selfEntity) { - return undefined; + if (ref.current) { + ref.current.focus(); } - const inputNormalizer = new InputNormalizer(); - inputNormalizer.listen(window.document.body); - selfEntity.listenForInput(inputNormalizer); - selfEntity.actionRegistry.setTransformerFor('UseItem', (type, value) => { - switch (type) { - case 'joystick': - return value === 0 ? -1 : selfEntity.activeSlotIndex; - case 'buttonPress': - case 'keyDown': - return selfEntity.activeSlotIndex; - default: - return -1; - } - }); - const inputHandle = setInterval(() => { - const actionStream = selfEntity.drainInput(); - if (actionStream.length > 0) { - socket.send(['Input', actionStream]); - } - }, 1000 / 60); - ref.current.focus(); - return () => { - clearInterval(inputHandle); - }; - }, [selfEntity, socket]); + }); return ( -
- + // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex +
+ {selfEntity && }
); diff --git a/packages/app/src/components/app/play/ui/index.scss b/packages/app/src/components/app/play/ui/index.scss deleted file mode 100644 index e69de29..0000000