From ba9a16ea745bb5bcbfb518be1267b7ae44356e31 Mon Sep 17 00:00:00 2001 From: ad044 Date: Wed, 14 Oct 2020 23:33:32 +0400 Subject: [PATCH] fixed some bugs, porting recoil stuff to zustand. this is a mess for now. --- package-lock.json | 5 + package.json | 3 +- src/App.tsx | 6 +- src/components/{Intro.tsx => Boot.tsx} | 4 +- src/components/HUD/HUDElement.tsx | 116 ++++++++++++-- src/components/HUD/HUDElementAtom.tsx | 13 +- src/components/HUD/HUDText.tsx | 112 ------------- .../InputHandler/BlueOrbHUDStateManager.tsx | 27 ++-- .../BlueOrbHUDTextStateManager.tsx | 149 ++++++++++-------- .../InputHandler/BlueOrbStateManager.tsx | 15 +- src/components/InputHandler/InputHandler.tsx | 20 +-- .../InputHandler/LainStateManager.tsx | 15 +- .../InputHandler/MiddleRingStateManager.tsx | 10 +- .../InputHandler/SiteStateManager.tsx | 36 ++--- src/components/Lain/Lain.tsx | 2 +- src/components/Lain/LainAtom.tsx | 5 - src/components/MainScene/MainScene.tsx | 10 +- src/components/MainScene/MainSceneIntro.tsx | 19 +-- src/components/Site/Site.tsx | 8 +- src/components/TextRenderer/TextRenderer.tsx | 11 +- src/components/store.ts | 39 +++++ 21 files changed, 322 insertions(+), 303 deletions(-) rename src/components/{Intro.tsx => Boot.tsx} (99%) delete mode 100644 src/components/HUD/HUDText.tsx create mode 100644 src/components/store.ts diff --git a/package-lock.json b/package-lock.json index d5bbd56..fc13fa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13946,6 +13946,11 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==" + }, + "zustand": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-3.1.3.tgz", + "integrity": "sha512-Otuzh3r0GsatvsUWeXEwdYjZEw1TItWcAXwDGEHdXE4/k6WbAdVDxC21t/Poq4ZMB+2VaQNKICWu7eCBUJ65tQ==" } } } diff --git a/package.json b/package.json index d56f41f..76715d4 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "three": "^0.119.1", "three-plain-animator": "^1.0.2", "ts-node": "^9.0.0", - "typescript": "^3.7.5" + "typescript": "^3.7.5", + "zustand": "^3.1.3" }, "scripts": { "start": "react-scripts start", diff --git a/src/App.tsx b/src/App.tsx index bd74619..21e9a96 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,7 +4,7 @@ import "./static/css/hub.css"; import "./static/css/main.css"; import { Canvas } from "react-three-fiber"; import { RecoilRoot } from "recoil"; -import Intro from "./components/Intro"; +import Boot from "./components/Boot"; const App = () => { const [moveToGame, setMoveToGame] = useState(false); @@ -19,8 +19,8 @@ const App = () => { return (
- {/**/} - {/* {moveToGame ? : } */} + {/**/} + {/* {moveToGame ? : } */} diff --git a/src/components/Intro.tsx b/src/components/Boot.tsx similarity index 99% rename from src/components/Intro.tsx rename to src/components/Boot.tsx index 1706579..cd7c127 100644 --- a/src/components/Intro.tsx +++ b/src/components/Boot.tsx @@ -50,7 +50,7 @@ type IntroProps = { setMoveToGame: React.Dispatch>; }; -const Intro = (props: IntroProps) => { +const Boot = (props: IntroProps) => { const [looping, setLooping] = useState(true); const [isArrowUp, setIsArrowUp] = useState(true); @@ -283,4 +283,4 @@ const Intro = (props: IntroProps) => { ); }; -export default Intro; +export default Boot; diff --git a/src/components/HUD/HUDElement.tsx b/src/components/HUD/HUDElement.tsx index d97cd75..69850fe 100644 --- a/src/components/HUD/HUDElement.tsx +++ b/src/components/HUD/HUDElement.tsx @@ -1,5 +1,5 @@ import React, { memo } from "react"; -import { useFrame, useLoader } from "react-three-fiber"; +import { useLoader } from "react-three-fiber"; import * as THREE from "three"; import bigHud from "../../static/sprites/big_hud.png"; import bigHudMirrored from "../../static/sprites/big_hud_mirrored.png"; @@ -7,27 +7,68 @@ import longHud from "../../static/sprites/long_hud.png"; import longHudMirrored from "../../static/sprites/long_hud_mirrored.png"; import boringHud from "../../static/sprites/long_hud_boring.png"; import boringHudMirrored from "../../static/sprites/long_hud_boring_mirrored.png"; -import { a, useSpring } from "@react-spring/three"; +import { a, useSpring, useTrail } from "@react-spring/three"; import { useRecoilValue } from "recoil"; -import { - bigHudTextAtom, - hudActiveAtom, - mediumHudTextAtom, -} from "./HUDElementAtom"; -import { currentHUDAtom } from "./HUDElementAtom"; -import HUDText from "./HUDText"; +import { useBlueOrbStore } from "../store"; +import blue_orb_huds from "../../resources/blue_orb_huds.json"; +import site_a from "../../resources/site_a.json"; +import { BigLetter, MediumLetter } from "../TextRenderer/TextRenderer"; +import { isSiteYChangingAtom } from "../Site/SiteAtom"; export type HUDElementProps = { hudVisibility: boolean; }; const HUDElement = memo((props: HUDElementProps) => { - const currentHud = useRecoilValue(currentHUDAtom); + const hudActive = useBlueOrbStore((state) => state.hudActive); - const currentBigHudText = useRecoilValue(bigHudTextAtom); - const currentMediumHudText = useRecoilValue(mediumHudTextAtom); + const currentBlueOrbId = useBlueOrbStore((state) => state.blueOrbId); + const currentHudId = useBlueOrbStore((state) => state.hudId); - const hudActive = useRecoilValue(hudActiveAtom); + const yellowHudTextPosY = useBlueOrbStore((state) => state.yellowHudTextPosY); + const yellowHudTextPosX = useBlueOrbStore((state) => state.yellowHudTextPosX); + + const currentHud = blue_orb_huds[currentHudId as keyof typeof blue_orb_huds]; + + const currentYellowHudText = useBlueOrbStore((state) => state.yellowHudText); + const currentGreenHudText = + site_a[currentBlueOrbId as keyof typeof site_a].green_text; + + const yellowTextArr = currentYellowHudText.split(""); + const greenTextArr = currentGreenHudText.split(""); + + const yellowLetterPosY = yellowHudTextPosY; + const yellowLetterPosX = yellowHudTextPosX; + + const isSiteChangingY = useRecoilValue(isSiteYChangingAtom); + + // this one is used for letter actions + const letterTrail = useTrail(currentYellowHudText.length, { + yellowLetterPosX: yellowLetterPosX, + yellowLetterPosY: yellowLetterPosY, + config: { duration: 280 }, + }); + + // this one is used when the site moves up/down and + // the text has to stay stationary + const letterStaticState = useSpring({ + yellowLetterPosX: yellowLetterPosX, + yellowLetterPosY: yellowLetterPosY, + config: { duration: 1200 }, + }); + + const { greenTextHUDPositionX } = useSpring({ + greenTextHUDPositionX: hudActive, + config: { duration: 500 }, + }); + + const mediumHudPosX = greenTextHUDPositionX.to( + [0, 1], + [ + currentHud["medium_text"]["initial_position"][0], + currentHud["medium_text"]["position"][0], + ] + ); const hudElementState = useSpring({ bigHUDPositionX: hudActive, @@ -137,7 +178,54 @@ const HUDElement = memo((props: HUDElementProps) => { depthTest={false} /> - + {isSiteChangingY + ? yellowTextArr.map((letter, idx) => ( + + + + )) + : letterTrail.map(({ yellowLetterPosX, yellowLetterPosY }, idx) => ( + + + + ))} + + {greenTextArr.map((letter, idx) => ( + + ))} + ); }); diff --git a/src/components/HUD/HUDElementAtom.tsx b/src/components/HUD/HUDElementAtom.tsx index 5538e36..6ed6cbf 100644 --- a/src/components/HUD/HUDElementAtom.tsx +++ b/src/components/HUD/HUDElementAtom.tsx @@ -1,11 +1,6 @@ import { atom } from "recoil"; import blue_orb_huds from "../../resources/blue_orb_huds.json"; -export const hudActiveAtom = atom({ - key: "hudActiveAtom", - default: 1, -}); - export const hudVisibilityAtom = atom({ key: "hudVisibilityAtom", default: true, @@ -16,13 +11,13 @@ export const currentHUDAtom = atom({ default: blue_orb_huds.fg_hud_1, }); -export const bigLetterPosYAtom = atom({ - key: "bigLetterPosYAtom", +export const yellowLetterPosYAtom = atom({ + key: "yellowLetterPosYAtom", default: blue_orb_huds.fg_hud_1.big_text[1], }); -export const bigLetterPosXAtom = atom({ - key: "bigLetterPosXAtom", +export const yellowLetterPosXAtom = atom({ + key: "yellowLetterPosXAtom", default: blue_orb_huds.fg_hud_1.big_text[0], }); diff --git a/src/components/HUD/HUDText.tsx b/src/components/HUD/HUDText.tsx deleted file mode 100644 index f04fc82..0000000 --- a/src/components/HUD/HUDText.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from "react"; -import { BigLetter, MediumLetter } from "../TextRenderer/TextRenderer"; -import { a, useSpring, useTrail } from "@react-spring/three"; -import { useRecoilValue } from "recoil"; -import { - bigLetterPosXAtom, - bigLetterPosYAtom, currentHUDAtom, - hudActiveAtom, -} from "./HUDElementAtom"; -import { isSiteYChangingAtom } from "../Site/SiteAtom"; - -type HUDTextProps = { - bigText: string; - mediumText: string; -}; - -const HUDText = (props: HUDTextProps) => { - const bigLetterPosX = useRecoilValue(bigLetterPosXAtom); - const bigLetterPosY = useRecoilValue(bigLetterPosYAtom); - - const currentHud = useRecoilValue(currentHUDAtom); - - const isSiteChangingY = useRecoilValue(isSiteYChangingAtom); - - const hudActive = useRecoilValue(hudActiveAtom); - - const { mediumTextHUDPositionX } = useSpring({ - mediumTextHUDPositionX: hudActive, - config: { duration: 500 }, - }); - - const mediumHudPosX = mediumTextHUDPositionX.to( - [0, 1], - [ - currentHud["medium_text"]["initial_position"][0], - currentHud["medium_text"]["position"][0], - ] - ); - - const bigTextArr = props.bigText.split(""); - const mediumTextArr = props.mediumText.split(""); - - // this one is used for letter animations - const letterTrail = useTrail(bigTextArr.length, { - bigLetterPosX: bigLetterPosX, - bigLetterPosY: bigLetterPosY, - config: { duration: 280 }, - }); - - // this one is used when the site moves up/down and - // the text has to stay stationary - const letterStaticState = useSpring({ - bigLetterPosX: bigLetterPosX, - bigLetterPosY: bigLetterPosY, - config: { duration: 1200 }, - }); - - return ( - <> - {isSiteChangingY - ? bigTextArr.map((letter, idx) => ( - - - - )) - : letterTrail.map(({ bigLetterPosX, bigLetterPosY }, idx) => ( - - - - ))} - - {mediumTextArr.map((letter, idx) => ( - - ))} - - - ); -}; - -export default HUDText; diff --git a/src/components/InputHandler/BlueOrbHUDStateManager.tsx b/src/components/InputHandler/BlueOrbHUDStateManager.tsx index 8bca644..c3789a4 100644 --- a/src/components/InputHandler/BlueOrbHUDStateManager.tsx +++ b/src/components/InputHandler/BlueOrbHUDStateManager.tsx @@ -2,13 +2,14 @@ import React, { useEffect, useMemo } from "react"; import { useSetRecoilState } from "recoil"; import { currentHUDAtom, - hudActiveAtom, mediumHudTextAtom, } from "../HUD/HUDElementAtom"; -import blue_orb_huds from "../../resources/blue_orb_huds.json"; +import { useBlueOrbStore } from "../store"; const BlueOrbHUDStateManager = (props: any) => { - const setHudActive = useSetRecoilState(hudActiveAtom); + const setCurrentHudId = useBlueOrbStore((state) => state.setCurrentHudId); + const toggleHud = useBlueOrbStore((state) => state.toggleHud); + const setCurrentHUDElement = useSetRecoilState(currentHUDAtom); const setMediumHudText = useSetRecoilState(mediumHudTextAtom); @@ -16,8 +17,8 @@ const BlueOrbHUDStateManager = (props: any) => { () => ({ moveUp: { duration: 3903.704 }, moveDown: { duration: 3903.704 }, - rotateLeft: { duration: 3903.704 }, - rotateRight: { duration: 3903.704 }, + moveLeft: { duration: 3903.704 }, + moveRight: { duration: 3903.704 }, changeBlueOrbUp: { duration: 500 }, changeBlueOrbDown: { duration: 500 }, changeBlueOrbLeft: { duration: 500 }, @@ -29,21 +30,18 @@ const BlueOrbHUDStateManager = (props: any) => { useEffect(() => { if (props.eventState) { const targetBlueOrbHudId = props.targetBlueOrbHudId; - const targetBlueOrbGreenText = props.targetBlueOrbGreenText; - - const targetBlueOrbHudData = - blue_orb_huds[targetBlueOrbHudId as keyof typeof blue_orb_huds]; const dispatchedAction = dispatcherObjects[props.eventState as keyof typeof dispatcherObjects]; // setHudActive((prev: boolean) => !prev); - setHudActive((prev: number) => Number(!prev)); + toggleHud(); setTimeout(() => { - setCurrentHUDElement(targetBlueOrbHudData); - setMediumHudText(targetBlueOrbGreenText); - setHudActive((prev: number) => Number(!prev)); + setCurrentHudId(targetBlueOrbHudId); + // setCurrentHUDElement(targetBlueOrbHudData); + // setMediumHudText(targetBlueOrbGreenText); + toggleHud(); }, dispatchedAction.duration); } }, [ @@ -52,8 +50,9 @@ const BlueOrbHUDStateManager = (props: any) => { props.targetBlueOrbGreenText, props.targetBlueOrbHudId, setCurrentHUDElement, - setHudActive, + setCurrentHudId, setMediumHudText, + toggleHud, ]); return null; }; diff --git a/src/components/InputHandler/BlueOrbHUDTextStateManager.tsx b/src/components/InputHandler/BlueOrbHUDTextStateManager.tsx index 2059e42..7aaab14 100644 --- a/src/components/InputHandler/BlueOrbHUDTextStateManager.tsx +++ b/src/components/InputHandler/BlueOrbHUDTextStateManager.tsx @@ -2,95 +2,112 @@ import React, { useCallback, useEffect, useMemo } from "react"; import blue_orb_huds from "../../resources/blue_orb_huds.json"; import site_a from "../../resources/site_a.json"; import { useSetRecoilState } from "recoil"; -import { bigLetterOffsetXCoeffAtom } from "../TextRenderer/TextRendererAtom"; -import { - bigHudTextAtom, - bigLetterPosXAtom, - bigLetterPosYAtom, -} from "../HUD/HUDElementAtom"; +import { bigHudTextAtom } from "../HUD/HUDElementAtom"; +import { useBlueOrbStore } from "../store"; const BlueOrbHUDTextStateManager = (props: any) => { - const setBigLetterOffSetXCoeff = useSetRecoilState(bigLetterOffsetXCoeffAtom); - const setBigLetterPosY = useSetRecoilState(bigLetterPosYAtom); - const setBigLetterPosX = useSetRecoilState(bigLetterPosXAtom); - const setBigHudText = useSetRecoilState(bigHudTextAtom); + const currentBlueOrbHudId = useBlueOrbStore((state) => state.hudId); + const currentBlueOrbId = useBlueOrbStore((state) => state.blueOrbId); + const setYellowHudText = useBlueOrbStore((state) => state.setYellowHudText); + const setYellowHudTextOffsetXCoeff = useBlueOrbStore( + (state) => state.setYellowHudTextOffsetXCoeff + ); - const animateBigTextWithMove = useCallback( + const incrementYellowHudTextPosY = useBlueOrbStore( + (state) => state.incrementYellowHudTextPosY + ); + const setYellowHudTextPosY = useBlueOrbStore( + (state) => state.setYellowHudTextPosY + ); + const setYellowHudTextPosX = useBlueOrbStore( + (state) => state.setYellowHudTextPosX + ); + + const animateYellowTextWithMove = useCallback( ( targetBlueOrbHudId: string, targetBlueOrbId: string, - bigLetterPosYOffset: number + yellowLetterPosYOffset: number ) => { // animate the letters to match that of site's // to create an illusion of not moving setTimeout(() => { - setBigLetterPosY((prev: number) => prev + bigLetterPosYOffset); + incrementYellowHudTextPosY(yellowLetterPosYOffset); }, 1300); setTimeout(() => { // make current hud big text shrink - setBigLetterOffSetXCoeff(-1); + setYellowHudTextOffsetXCoeff(-1); }, 2500); setTimeout(() => { // animate it to new pos x/y - setBigLetterPosX( - blue_orb_huds[targetBlueOrbHudId as keyof typeof blue_orb_huds] + setYellowHudTextPosX( + blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds] .big_text[0] ); - setBigLetterPosY( - blue_orb_huds[targetBlueOrbHudId as keyof typeof blue_orb_huds] + setYellowHudTextPosY( + blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds] .big_text[1] ); // set new text according to the node name - setBigHudText(site_a[targetBlueOrbId as keyof typeof site_a].node_name); + setYellowHudText( + site_a[currentBlueOrbId as keyof typeof site_a].node_name + ); }, 3000); // unshrink text setTimeout(() => { - setBigLetterOffSetXCoeff(0); + setYellowHudTextOffsetXCoeff(0); }, 3900); }, [ - setBigHudText, - setBigLetterOffSetXCoeff, - setBigLetterPosX, - setBigLetterPosY, + currentBlueOrbHudId, + currentBlueOrbId, + incrementYellowHudTextPosY, + setYellowHudText, + setYellowHudTextOffsetXCoeff, + setYellowHudTextPosX, + setYellowHudTextPosY, ] ); - const animateBigTextWithoutMove = useCallback( + const animateYellowTextWithoutMove = useCallback( (targetBlueOrbHudId: string, targetBlueOrbId: string) => { // make current hud big text shrink - setBigLetterOffSetXCoeff(-1); + setYellowHudTextOffsetXCoeff(-1); setTimeout(() => { // animate it to new pos x/y - setBigLetterPosX( - blue_orb_huds[targetBlueOrbHudId as keyof typeof blue_orb_huds] + setYellowHudTextPosX( + blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds] .big_text[0] ); - setBigLetterPosY( - blue_orb_huds[targetBlueOrbHudId as keyof typeof blue_orb_huds] + setYellowHudTextPosY( + blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds] .big_text[1] ); }, 400); setTimeout(() => { // set new text according to the node name - setBigHudText(site_a[targetBlueOrbId as keyof typeof site_a].node_name); + setYellowHudText( + site_a[currentBlueOrbId as keyof typeof site_a].node_name + ); }, 1000); setTimeout(() => { // unshrink text - setBigLetterOffSetXCoeff(0); + setYellowHudTextOffsetXCoeff(0); }, 1200); }, [ - setBigHudText, - setBigLetterOffSetXCoeff, - setBigLetterPosX, - setBigLetterPosY, + currentBlueOrbHudId, + currentBlueOrbId, + setYellowHudText, + setYellowHudTextOffsetXCoeff, + setYellowHudTextPosX, + setYellowHudTextPosY, ] ); @@ -98,46 +115,46 @@ const BlueOrbHUDTextStateManager = (props: any) => { () => ({ moveUp: { action: "animateWithMove", - animation: animateBigTextWithMove, - bigLetterPosYOffset: -1.5, + actionFunction: animateYellowTextWithMove, + yellowLetterPosYOffset: -1.5, }, moveDown: { action: "animateWithMove", - animation: animateBigTextWithMove, - bigLetterPosYOffset: 1.5, + actionFunction: animateYellowTextWithMove, + yellowLetterPosYOffset: 1.5, }, - rotateLeft: { + moveLeft: { action: "animateWithMove", - animation: animateBigTextWithMove, - bigLetterPosYOffset: 0, + actionFunction: animateYellowTextWithMove, + yellowLetterPosYOffset: 0, }, - rotateRight: { + moveRight: { action: "animateWithMove", - animation: animateBigTextWithMove, - bigLetterPosYOffset: 0, + actionFunction: animateYellowTextWithMove, + yellowLetterPosYOffset: 0, }, changeBlueOrbUp: { - action: "animateWithMove", - animation: animateBigTextWithoutMove, - bigLetterPosYOffset: 0, + action: "animateWithoutMove", + actionFunction: animateYellowTextWithoutMove, + yellowLetterPosYOffset: 0, }, changeBlueOrbDown: { - action: "animateWithMove", - animation: animateBigTextWithoutMove, - bigLetterPosYOffset: 0, + action: "animateWithoutMove", + actionFunction: animateYellowTextWithoutMove, + yellowLetterPosYOffset: 0, }, changeBlueOrbLeft: { - action: "animateWithMove", - animation: animateBigTextWithoutMove, - bigLetterPosYOffset: 0, + action: "animateWithoutMove", + actionFunction: animateYellowTextWithoutMove, + yellowLetterPosYOffset: 0, }, changeBlueOrbRight: { - action: "animateWithMove", - animation: animateBigTextWithoutMove, - bigLetterPosYOffset: 0, + action: "animateWithoutMove", + actionFunction: animateYellowTextWithoutMove, + yellowLetterPosYOffset: 0, }, }), - [animateBigTextWithMove, animateBigTextWithoutMove] + [animateYellowTextWithMove, animateYellowTextWithoutMove] ); useEffect(() => { @@ -149,26 +166,22 @@ const BlueOrbHUDTextStateManager = (props: any) => { dispatcherObjects[props.eventState as keyof typeof dispatcherObjects]; if (dispatchedAction.action === "animateWithMove") { - animateBigTextWithMove( + animateYellowTextWithMove( targetBlueOrbHudId, targetBlueOrbId, - dispatchedAction.bigLetterPosYOffset + dispatchedAction.yellowLetterPosYOffset ); } else { - animateBigTextWithoutMove(targetBlueOrbHudId, targetBlueOrbId); + animateYellowTextWithoutMove(targetBlueOrbHudId, targetBlueOrbId); } } }, [ - animateBigTextWithMove, - animateBigTextWithoutMove, + animateYellowTextWithMove, + animateYellowTextWithoutMove, dispatcherObjects, props.eventState, props.targetBlueOrbHudId, props.targetBlueOrbId, - setBigHudText, - setBigLetterOffSetXCoeff, - setBigLetterPosX, - setBigLetterPosY, ]); return null; diff --git a/src/components/InputHandler/BlueOrbStateManager.tsx b/src/components/InputHandler/BlueOrbStateManager.tsx index f183926..95a2035 100644 --- a/src/components/InputHandler/BlueOrbStateManager.tsx +++ b/src/components/InputHandler/BlueOrbStateManager.tsx @@ -1,9 +1,13 @@ import React, { useEffect, useMemo } from "react"; import { useSetRecoilState } from "recoil"; import { currentBlueOrbAtom } from "../BlueOrb/CurrentBlueOrbAtom"; +import { useBlueOrbStore } from "../store"; const BlueOrbStateManager = (props: any) => { - const setCurrentBlueOrb = useSetRecoilState(currentBlueOrbAtom); + // const setCurrentBlueOrb = useSetRecoilState(currentBlueOrbAtom); + const setCurrentBlueOrb = useBlueOrbStore( + (state) => state.setCurrentBlueOrbId + ); // this one is repetitive for now but ill leave them separated // in case it comes in handy later on @@ -11,8 +15,8 @@ const BlueOrbStateManager = (props: any) => { () => ({ moveUp: { duration: 3903.704 }, moveDown: { duration: 3903.704 }, - rotateLeft: { duration: 3903.704 }, - rotateRight: { duration: 3903.704 }, + moveLeft: { duration: 3903.704 }, + moveRight: { duration: 3903.704 }, changeBlueOrbUp: { duration: 0 }, changeBlueOrbDown: { duration: 0 }, changeBlueOrbLeft: { duration: 0 }, @@ -26,10 +30,7 @@ const BlueOrbStateManager = (props: any) => { const dispatchedAction = dispatcherObjects[props.eventState as keyof typeof dispatcherObjects]; - // disable glow on current blue orb - setCurrentBlueOrb(""); - - // set new one after animation ends + // set new one after action ends setTimeout(() => { setCurrentBlueOrb(props.targetBlueOrbId); }, dispatchedAction.duration); diff --git a/src/components/InputHandler/InputHandler.tsx b/src/components/InputHandler/InputHandler.tsx index 2027fc8..84f35e7 100644 --- a/src/components/InputHandler/InputHandler.tsx +++ b/src/components/InputHandler/InputHandler.tsx @@ -1,8 +1,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; -import { useRecoilValue, useSetRecoilState } from "recoil"; +import { useSetRecoilState } from "recoil"; import { currentBlueOrbAnimatingAtom, - currentBlueOrbAtom, currentBlueOrbPosXAtom, currentBlueOrbPosYAtom, currentBlueOrbPosZAtom, @@ -11,13 +10,13 @@ import blue_orb_directions from "../../resources/blue_orb_directions.json"; import blue_orb_positions from "../../resources/blue_orb_positions.json"; import level_y_values from "../../resources/level_y_values.json"; import site_a from "../../resources/site_a.json"; -import { lainMovingAtom } from "../Lain/LainAtom"; import SiteStateManager from "./SiteStateManager"; import MiddleRingStateManager from "./MiddleRingStateManager"; import LainStateManager from "./LainStateManager"; import BlueOrbStateManager from "./BlueOrbStateManager"; import BlueOrbHUDStateManager from "./BlueOrbHUDStateManager"; import BlueOrbHUDTextStateManager from "./BlueOrbHUDTextStateManager"; +import { useBlueOrbStore } from "../store"; type KeyCodeAssociations = { [keyCode: number]: string; @@ -41,7 +40,7 @@ type BlueOrbStateData = { const InputHandler = () => { const [eventState, setEventState] = useState(); - const currentBlueOrb = useRecoilValue(currentBlueOrbAtom); + const currentBlueOrb = useBlueOrbStore((state) => state.blueOrbId); const setCurrentBlueOrbAnimating = useSetRecoilState( currentBlueOrbAnimatingAtom ); @@ -54,12 +53,12 @@ const InputHandler = () => { const [inputCooldown, setInputCooldown] = useState(false); - const moveAndRotationEvents = useMemo( + const moveEvents = useMemo( () => ({ up: "moveUp", down: "moveDown", - left: "rotateLeft", - right: "rotateRight", + left: "moveLeft", + right: "moveRight", }), [] ); @@ -117,10 +116,7 @@ const InputHandler = () => { }); if (moveOrRotate) { - const event = - moveAndRotationEvents[ - keyPress as keyof typeof moveAndRotationEvents - ]; + const event = moveEvents[keyPress as keyof typeof moveEvents]; setEventState(event); } else { @@ -160,7 +156,7 @@ const InputHandler = () => { [ inputCooldown, currentBlueOrb, - moveAndRotationEvents, + moveEvents, blueOrbChangeEvents, setCurrentBlueOrbPosX, setCurrentBlueOrbPosY, diff --git a/src/components/InputHandler/LainStateManager.tsx b/src/components/InputHandler/LainStateManager.tsx index de96ebd..1a2a402 100644 --- a/src/components/InputHandler/LainStateManager.tsx +++ b/src/components/InputHandler/LainStateManager.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo } from "react"; import { useSetRecoilState } from "recoil"; -import { lainMoveStateAtom, lainMovingAtom } from "../Lain/LainAtom"; +import { lainMoveStateAtom } from "../Lain/LainAtom"; import { LainMoveDown, LainMoveLeft, @@ -11,15 +11,14 @@ import { } from "../Lain/Lain"; const LainStateManager = (props: any) => { - const setLainMoving = useSetRecoilState(lainMovingAtom); const setLainMoveState = useSetRecoilState(lainMoveStateAtom); const dispatcherObjects = useMemo( () => ({ - moveUp: { animation: , duration: 3903.704 }, - moveDown: { animation: , duration: 3903.704 }, - rotateLeft: { animation: , duration: 3903.704 }, - rotateRight: { animation: , duration: 3903.704 }, + moveUp: { action: , duration: 3903.704 }, + moveDown: { action: , duration: 3903.704 }, + moveLeft: { action: , duration: 3903.704 }, + moveRight: { action: , duration: 3903.704 }, }), [] ); @@ -30,14 +29,14 @@ const LainStateManager = (props: any) => { dispatcherObjects[props.eventState as keyof typeof dispatcherObjects]; if (dispatchedAction) { - setLainMoveState(dispatchedAction.animation); + setLainMoveState(dispatchedAction.action); setTimeout(() => { setLainMoveState(); }, dispatchedAction.duration); } } - }, [dispatcherObjects, props.eventState, setLainMoveState, setLainMoving]); + }, [dispatcherObjects, props.eventState, setLainMoveState]); return null; }; diff --git a/src/components/InputHandler/MiddleRingStateManager.tsx b/src/components/InputHandler/MiddleRingStateManager.tsx index 92cfdcd..9c87a27 100644 --- a/src/components/InputHandler/MiddleRingStateManager.tsx +++ b/src/components/InputHandler/MiddleRingStateManager.tsx @@ -178,10 +178,10 @@ const MiddleRingStateManager = (props: any) => { const dispatcherObjects = useMemo( () => ({ - moveUp: { animation: moveMiddleRingUp }, - moveDown: { animation: moveMiddleRingDown }, - rotateLeft: { animation: rotateMiddleRingLeft }, - rotateRight: { animation: rotateMiddleRingRight }, + moveUp: { action: moveMiddleRingUp }, + moveDown: { action: moveMiddleRingDown }, + moveLeft: { action: rotateMiddleRingLeft }, + moveRight: { action: rotateMiddleRingRight }, }), [ moveMiddleRingDown, @@ -197,7 +197,7 @@ const MiddleRingStateManager = (props: any) => { dispatcherObjects[props.eventState as keyof typeof dispatcherObjects]; if (dispatchedAction) { - dispatchedAction.animation(); + dispatchedAction.action(); } } }, [ diff --git a/src/components/InputHandler/SiteStateManager.tsx b/src/components/InputHandler/SiteStateManager.tsx index a280fbe..717e667 100644 --- a/src/components/InputHandler/SiteStateManager.tsx +++ b/src/components/InputHandler/SiteStateManager.tsx @@ -13,12 +13,16 @@ const SiteStateManager = (props: any) => { const dispatcherObjects = useMemo( () => ({ - moveUp: { action: "move", value: -1.5 }, - moveDown: { action: "move", value: 1.5 }, - rotateLeft: { action: "rotate", value: Math.PI / 4 }, - rotateRight: { action: "rotate", value: -Math.PI / 4 }, + moveUp: { action: setSitePosY, value: -1.5, actionDelay: 1300 }, + moveDown: { action: setSitePosY, value: 1.5, actionDelay: 1300 }, + moveLeft: { action: setSiteRotY, value: Math.PI / 4, actionDelay: 1100 }, + moveRight: { + action: setSiteRotY, + value: -Math.PI / 4, + actionDelay: 1100, + }, }), - [] + [setSitePosY, setSiteRotY] ); useEffect(() => { @@ -27,20 +31,14 @@ const SiteStateManager = (props: any) => { dispatcherObjects[props.eventState as keyof typeof dispatcherObjects]; if (dispatchedAction) { - switch (dispatchedAction.action) { - case "rotate": - setTimeout(() => { - setSiteRotY((prev: number) => prev + dispatchedAction.value); - }, 1100); - break; - case "move": - setTimeout(() => { - setSitePosY((prev: number) => prev + dispatchedAction.value); - }, 1300); - break; - default: - break; - } + setIsSiteYChanging(true); + + setTimeout(() => { + dispatchedAction.action( + (prev: number) => prev + dispatchedAction.value + ); + }, dispatchedAction.actionDelay); + setTimeout(() => { setIsSiteYChanging(false); }, 3000); diff --git a/src/components/Lain/Lain.tsx b/src/components/Lain/Lain.tsx index 6276093..b833076 100644 --- a/src/components/Lain/Lain.tsx +++ b/src/components/Lain/Lain.tsx @@ -10,7 +10,7 @@ import standingSpriteSheet from "../../static/sprites/standing.png"; import introSpriteSheet from "../../static/sprites/intro.png"; import throwBlueOrbSpriteSheet from "../../static/sprites/throw_blue_orb.png"; import { useRecoilValue } from "recoil"; -import { lainMoveStateAtom, lainMovingAtom } from "./LainAtom"; +import { lainMoveStateAtom } from "./LainAtom"; type LainConstructorProps = { sprite: string; diff --git a/src/components/Lain/LainAtom.tsx b/src/components/Lain/LainAtom.tsx index bfb4522..1208923 100644 --- a/src/components/Lain/LainAtom.tsx +++ b/src/components/Lain/LainAtom.tsx @@ -1,11 +1,6 @@ import { atom } from "recoil"; import React from "react"; -export const lainMovingAtom = atom({ - key: "lainMovingAtom", - default: false, -}); - export const lainMoveStateAtom = atom({ key: "lainMoveStateAtom", default: <>, diff --git a/src/components/MainScene/MainScene.tsx b/src/components/MainScene/MainScene.tsx index 69125ce..d60d267 100644 --- a/src/components/MainScene/MainScene.tsx +++ b/src/components/MainScene/MainScene.tsx @@ -2,12 +2,12 @@ import { a, useSpring } from "@react-spring/three"; import { OrbitControls } from "drei"; import React, { Suspense, useEffect } from "react"; import Site from "../Site/Site"; -import Lain from "../Lain/Lain"; +import Lain, { LainStanding } from "../Lain/Lain"; import Lights from "../Lights"; import OrthoCamera from "../OrthoCamera/OrthoCamera"; import Preloader from "../Preloader"; import { useRecoilValue, useSetRecoilState } from "recoil"; -import { lainMoveStateAtom, lainMovingAtom } from "../Lain/LainAtom"; +import { lainMoveStateAtom } from "../Lain/LainAtom"; import InputHandler from "../InputHandler/InputHandler"; import MainSceneIntro from "./MainSceneIntro"; import { @@ -20,7 +20,6 @@ import MiddleRing from "../MiddleRing/MiddleRing"; import Starfield from "../Starfield/Starfield"; const MainScene = () => { - const setLainMoving = useSetRecoilState(lainMovingAtom); const setLainMoveState = useSetRecoilState(lainMoveStateAtom); const mainGroupPosY = useRecoilValue(mainGroupPosYAtom); const mainGroupPosZ = useRecoilValue(mainGroupPosZAtom); @@ -37,11 +36,14 @@ const MainScene = () => { config: { duration: 1500 }, }); + useEffect(() => { + setLainMoveState(); + }, [setLainMoveState]); // set lain intro spritesheet before the page loads fully useEffect(() => { // setLainMoving(true); // setLainMoveState(); - }, [setLainMoveState, setLainMoving]); + }, [setLainMoveState]); return ( diff --git a/src/components/MainScene/MainSceneIntro.tsx b/src/components/MainScene/MainSceneIntro.tsx index 61ab440..f2af82c 100644 --- a/src/components/MainScene/MainSceneIntro.tsx +++ b/src/components/MainScene/MainSceneIntro.tsx @@ -1,13 +1,13 @@ import React, { memo, useEffect } from "react"; import { useSetRecoilState } from "recoil"; -import { hudActiveAtom, hudVisibilityAtom } from "../HUD/HUDElementAtom"; +import { hudVisibilityAtom } from "../HUD/HUDElementAtom"; import { mainGroupPosYAtom, mainGroupPosZAtom, mainGroupRotXAtom, } from "./MainGroupAtom"; import { LainStanding } from "../Lain/Lain"; -import { lainMoveStateAtom, lainMovingAtom } from "../Lain/LainAtom"; +import { lainMoveStateAtom } from "../Lain/LainAtom"; import { orbVisibilityAtom } from "../Orb/OrbAtom"; import { introStarfieldVisibilityAtom, @@ -15,19 +15,19 @@ import { mainStarfieldVisibilityAtom, } from "../Starfield/StarfieldAtom"; import { grayPlanesVisibleAtom } from "../GrayPlanes/GrayPlanesAtom"; +import { useBlueOrbStore } from "../store"; -// ghost component to manipulate the intro animation for the main scene. +// ghost component to manipulate the intro action for the main scene. // we separate this file because having something like this // inside tags makes it behave in a more stable manner // by waiting for the components to load and synchronously calling the functions. const MainSceneIntro = memo(() => { - const setHudActive = useSetRecoilState(hudActiveAtom); + const toggleHud = useBlueOrbStore((state) => state.toggleHud); const setHudVisible = useSetRecoilState(hudVisibilityAtom); const setOrbVisible = useSetRecoilState(orbVisibilityAtom); - const setLainMoving = useSetRecoilState(lainMovingAtom); const setLainMoveState = useSetRecoilState(lainMoveStateAtom); const setIntroStarfieldVisible = useSetRecoilState( @@ -60,10 +60,9 @@ const MainSceneIntro = memo(() => { setMainStarfieldBoostVal(0); }, 2800); - setHudActive((prev: number) => Number(!prev)); + toggleHud(); setTimeout(() => { - setLainMoving(false); setLainMoveState(); setOrbVisible(true); @@ -71,8 +70,7 @@ const MainSceneIntro = memo(() => { setIntroStarfieldVisible(false); - setHudActive((prev: number) => Number(!prev)); - + toggleHud(); setTimeout(() => { document.getElementsByTagName("canvas")[0].className = "hub-background"; }, 300); @@ -84,12 +82,11 @@ const MainSceneIntro = memo(() => { setHudVisible, setOrbVisible, setIntroStarfieldVisible, - setHudActive, setMainGroupRotX, setMainGroupPosZ, setMainGroupPosY, - setLainMoving, setLainMoveState, + toggleHud, ]); return <>; diff --git a/src/components/Site/Site.tsx b/src/components/Site/Site.tsx index f9fa4bc..2efdfd0 100644 --- a/src/components/Site/Site.tsx +++ b/src/components/Site/Site.tsx @@ -5,12 +5,12 @@ import level_y_values from "../../resources/level_y_values.json"; import blue_orb_positions from "../../resources/blue_orb_positions.json"; import BlueOrb from "../BlueOrb/BlueOrb"; import { useRecoilValue } from "recoil"; -import { currentBlueOrbAtom } from "../BlueOrb/CurrentBlueOrbAtom"; -import { useSpring, a } from "@react-spring/three"; +import { a, useSpring } from "@react-spring/three"; import { sitePosYAtom, siteRotYAtom } from "./SiteAtom"; +import { useBlueOrbStore } from "../store"; const Site = memo(() => { - const currentBlueOrb = useRecoilValue(currentBlueOrbAtom); + const currentBlueOrbId = useBlueOrbStore((state) => state.blueOrbId); const siteRotY = useRecoilValue(siteRotYAtom); const sitePosY = useRecoilValue(sitePosYAtom); @@ -51,7 +51,7 @@ const Site = memo(() => { ] } key={(blueOrb as any)[1]["node_name"]} - active={(blueOrb as any)[0] === currentBlueOrb} + active={(blueOrb as any)[0] === currentBlueOrbId} level={(blueOrb as any)[0].substr(0, 2)} /> ); diff --git a/src/components/TextRenderer/TextRenderer.tsx b/src/components/TextRenderer/TextRenderer.tsx index d035dcb..c2c0835 100644 --- a/src/components/TextRenderer/TextRenderer.tsx +++ b/src/components/TextRenderer/TextRenderer.tsx @@ -9,6 +9,7 @@ import { a, useSpring } from "@react-spring/three"; import React from "react"; import { useRecoilValue } from "recoil"; import { bigLetterOffsetXCoeffAtom } from "./TextRendererAtom"; +import { useBlueOrbStore } from "../store"; type LetterProps = { color: string; @@ -36,7 +37,9 @@ type FontData = { }; export const BigLetter = (props: LetterProps) => { - const bigLetterOffsetXCoeff = useRecoilValue(bigLetterOffsetXCoeffAtom); + const yellowTextOffsetXCoeff = useBlueOrbStore( + (state) => state.yellowHudTextOffsetXCoeff + ); const colorToTexture = (color: string) => { return ({ orange: orangeFont, yellow: yellowFont } as ColorToTexture)[ @@ -105,10 +108,10 @@ export const BigLetter = (props: LetterProps) => { const textRendererState = useSpring({ letterOffsetXCoeff: props.kerningOffset === 0 - ? props.kerningOffset + props.kerningOffset * bigLetterOffsetXCoeff + ? props.kerningOffset + props.kerningOffset * yellowTextOffsetXCoeff : props.kerningOffset + 0.3 + - (props.kerningOffset + 0.3) * bigLetterOffsetXCoeff, + (props.kerningOffset + 0.3) * yellowTextOffsetXCoeff, config: { duration: 200 }, }); @@ -167,7 +170,7 @@ export const MediumLetter = (props: LetterProps) => { 2: 0.297, 3: 0.238, 4: 0.18, - 5: 1 + 5: 1, }; const letterData = (medium_font_json as FontData)["glyphs"][props.letter]; diff --git a/src/components/store.ts b/src/components/store.ts new file mode 100644 index 0000000..2fa9cdf --- /dev/null +++ b/src/components/store.ts @@ -0,0 +1,39 @@ +import create from "zustand"; + +type HUDState = { + blueOrbId: string; + hudId: string; + hudActive: number; + yellowHudText: string; + yellowHudTextPosY: number; + yellowHudTextPosX: number; + yellowHudTextOffsetXCoeff: number; + setCurrentBlueOrbId: (to: string) => void; + setCurrentHudId: (to: string) => void; + toggleHud: () => void; + setYellowHudText: (to: string) => void; + incrementYellowHudTextPosY: (by: number) => void; + setYellowHudTextPosY: (to: number) => void; + setYellowHudTextPosX: (to: number) => void; + setYellowHudTextOffsetXCoeff: (to: number) => void; +}; + +export const useBlueOrbStore = create((set) => ({ + blueOrbId: "0422", + hudId: "fg_hud_1", + hudActive: 1, + yellowHudText: "", + yellowHudTextPosY: 0, + yellowHudTextPosX: 0, + yellowHudTextOffsetXCoeff: 0, + setCurrentBlueOrbId: (to) => set(() => ({ blueOrbId: to })), + setCurrentHudId: (to) => set(() => ({ hudId: to })), + toggleHud: () => set((state) => ({ hudActive: Number(!state.hudActive) })), + setYellowHudText: (to) => set(() => ({ yellowHudText: to })), + incrementYellowHudTextPosY: (by) => + set((state) => ({ yellowHudTextPosY: state.yellowHudTextPosY + by })), + setYellowHudTextPosY: (to) => set(() => ({ yellowHudTextPosY: to })), + setYellowHudTextPosX: (to) => set(() => ({ yellowHudTextPosY: to })), + setYellowHudTextOffsetXCoeff: (to) => + set(() => ({ yellowHudTextOffsetXCoeff: to })), +}));