Add zustand store and menu overlay

master
Ian Mancini 4 years ago
parent 1c758b4243
commit a2a7fee16c

@ -26,7 +26,8 @@
"react-three-fiber": "^5.2.1",
"three": "^0.122.0",
"typescript": "^4.0.5",
"web-vitals": "^0.2.4"
"web-vitals": "^0.2.4",
"zustand": "^3.1.4"
},
"scripts": {
"start": "cross-env PORT=4000 CI=true react-scripts start",

@ -0,0 +1,30 @@
import React, { useEffect, useRef } from 'react'
import { PointerLockControls } from '@react-three/drei'
import api from '../Store'
const Controls: React.FC = () => {
const ref = useRef<null | PointerLockControls>(null)
const setPointerLockControls = api.getState().setPointerLockControls
const setPointerLockStatus = api.getState().setPointerLockStatus
useEffect(() => {
if (ref.current) {
setPointerLockControls(ref.current)
const onLock = () => setPointerLockStatus(true)
const onUnlock = () => setPointerLockStatus(false)
ref.current.addEventListener?.('lock', onLock)
ref.current.addEventListener?.('unlock', onUnlock)
return () => {
ref.current?.removeEventListener?.('lock', onLock)
ref.current?.removeEventListener?.('unlock', onUnlock)
}
}
}, [ref, ref.current])
return <PointerLockControls ref={ref} />
}
export default Controls

@ -29,7 +29,6 @@ const usePlayerControls = () => {
})
useEffect(() => {
const handleKeyDown = (e: Event) => {
console.log(e.code)
setMovement((m) => ({ ...m, [moveFieldByKey(e.code)]: true }))
}
const handleKeyUp = (e: Event) =>

@ -1,12 +1,12 @@
import React, { Suspense } from 'react'
import { Physics } from '@react-three/cannon'
import { PointerLockControls } from '@react-three/drei'
import World from './models/World'
import WorldCollisions from './models/WorldCollisions'
import Player from './Player'
import Lighting from './Lighting'
import Effects from './Effects'
import Controls from './Controls'
const Scene: React.FC = () => {
return (
@ -30,7 +30,7 @@ const Scene: React.FC = () => {
<Effects />
</Suspense>
<PointerLockControls />
<Controls />
</>
)
}

@ -0,0 +1,18 @@
import create from 'zustand'
import { PointerLockControls } from '@react-three/drei'
type State = {
pointerLockControls: PointerLockControls | undefined
pointerLocked: boolean
setPointerLockStatus: (status: boolean) => void
setPointerLockControls: (controls: PointerLockControls) => void
}
const useStore = create<State>((set) => ({
pointerLockControls: undefined,
pointerLocked: false,
setPointerLockStatus: (status) => set(() => ({ pointerLocked: status })),
setPointerLockControls: (controls) => set(() => ({ pointerLockControls: controls })),
}))
export default useStore

@ -0,0 +1,60 @@
import React, { useEffect, useState } from 'react'
import {
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalFooter,
ModalBody,
Button,
Kbd,
useToast,
} from '@chakra-ui/react'
import useStore from '../Store'
const MenuOverlay: React.FC = () => {
const [helpToastShown, setHelpToastShown] = useState<boolean>(false)
const pointerLockControls = useStore((state) => state.pointerLockControls)
const pointerLocked = useStore((state) => state.pointerLocked)
const toast = useToast()
useEffect(() => {
if (!helpToastShown && pointerLocked) {
toast({
description: 'Para volver al menú, pulsá ESC',
duration: 5000,
isClosable: false,
})
setHelpToastShown(true)
}
}, [pointerLocked, helpToastShown])
const lockControls = () => {
if (pointerLockControls && !pointerLocked) {
pointerLockControls.lock?.()
}
}
return (
<>
<Modal isOpen={!pointerLocked} onClose={() => undefined}>
<ModalOverlay />
<ModalContent>
<ModalHeader>museo.red</ModalHeader>
<ModalBody>
Usa las teclas <Kbd>W</Kbd>, <Kbd>A</Kbd> <Kbd>S</Kbd> y <Kbd>D</Kbd> para
moverte. Usá el mouse para mirar al rededor
</ModalBody>
<ModalFooter>
<Button colorScheme="blue" mx="auto" onClick={lockControls}>
Continuar
</Button>
</ModalFooter>
</ModalContent>
</Modal>
</>
)
}
export default MenuOverlay

@ -3,11 +3,13 @@ import React from 'react'
import { Box } from '@chakra-ui/react'
import { Canvas } from 'react-three-fiber'
import MenuOverlay from './MenuOverlay'
import Scene from '../3d'
const Museo: React.FC = () => {
return (
<Box w="100vw" h="100vh">
<MenuOverlay />
<Canvas colorManagement>
<Scene />
</Canvas>

Loading…
Cancel
Save