From 4f86d2dbe034f8a293ae90c7f933a281236d72b5 Mon Sep 17 00:00:00 2001 From: ad044 Date: Sun, 18 Oct 2020 15:49:26 +0400 Subject: [PATCH] transient updates on active blue orb --- src/components/BlueOrb.tsx | 64 +++++++++++++++++++++++------------- src/components/MainScene.tsx | 4 --- src/components/Site.tsx | 24 +++++++++----- src/store.ts | 10 ++++++ 4 files changed, 67 insertions(+), 35 deletions(-) diff --git a/src/components/BlueOrb.tsx b/src/components/BlueOrb.tsx index 10ffe9b..1673ba7 100644 --- a/src/components/BlueOrb.tsx +++ b/src/components/BlueOrb.tsx @@ -1,4 +1,4 @@ -import React, {memo, useEffect, useMemo, useRef} from "react"; +import React, { memo, useEffect, useMemo, useRef } from "react"; import { useFrame, useLoader } from "react-three-fiber"; import { useSpring, a } from "@react-spring/three"; import * as THREE from "three"; @@ -28,13 +28,6 @@ type BlueOrbContructorProps = { }; const BlueOrb = memo((props: BlueOrbContructorProps) => { - const isActiveBlueOrbInteractedWith = useBlueOrbStore( - (state) => state.isActiveBlueOrbInteractedWith - ); - const activeBlueOrbPosX = useBlueOrbStore((state) => state.activeBlueOrbPosX); - const activeBlueOrbPosZ = useBlueOrbStore((state) => state.activeBlueOrbPosZ); - const activeBlueOrbRotZ = useBlueOrbStore((state) => state.activeBlueOrbRotZ); - // the game only has a couple of sprites that it displays in the hub // dynamically importnig them would be worse for performance, // so we import all of them here and then use this function to @@ -119,21 +112,48 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => { } }); - const activeBlueOrbState = useSpring({ - activeBlueOrbPosX: isActiveBlueOrbInteractedWith - ? activeBlueOrbPosX + // these pieces of state get updated transiently rather than reactively + // to avoid excess unnecessary renders (this is absolutely crucial for performance). + const [ + { + activeBlueOrbPosX, + activeBlueOrbPosY, + activeBlueOrbPosZ, + activeBlueOrbRotZ, + }, + set, + ] = useSpring(() => ({ + activeBlueOrbPosX: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith + ? useBlueOrbStore.getState().activeBlueOrbPosX : props.position[0], - activeBlueOrbPosY: isActiveBlueOrbInteractedWith + activeBlueOrbPosY: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith ? level_y_values[props.level as keyof typeof level_y_values] : props.position[1], - activeBlueOrbPosZ: isActiveBlueOrbInteractedWith - ? activeBlueOrbPosZ + activeBlueOrbPosZ: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith + ? useBlueOrbStore.getState().activeBlueOrbPosZ : props.position[2], - activeBlueOrbRotZ: isActiveBlueOrbInteractedWith - ? activeBlueOrbRotZ - : 0.001, + activeBlueOrbRotZ: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith + ? useBlueOrbStore.getState().activeBlueOrbRotZ + : 0, config: { duration: 800 }, - }); + })); + + useEffect(() => { + useBlueOrbStore.subscribe(set, (state) => ({ + activeBlueOrbPosX: useBlueOrbStore.getState() + .isActiveBlueOrbInteractedWith + ? state.activeBlueOrbPosX + : props.position[0], + activeBlueOrbPosZ: useBlueOrbStore.getState() + .isActiveBlueOrbInteractedWith + ? state.activeBlueOrbPosZ + : props.position[2], + activeBlueOrbRotZ: useBlueOrbStore.getState() + .isActiveBlueOrbInteractedWith + ? state.activeBlueOrbRotZ + : 0, + })); + }, [activeBlueOrbPosX, activeBlueOrbPosZ, activeBlueOrbRotZ, set]); return ( { > {props.active ? ( { setActiveBlueOrbHudId("fg_hud_1"); }, [setActiveBlueOrb, setActiveBlueOrbHudId, setLainMoveState]); // set lain intro spritesheet before the page loads fully - useEffect(() => { - // setLainMoving(true); - // setLainMoveState(); - }, [setLainMoveState]); return ( diff --git a/src/components/Site.tsx b/src/components/Site.tsx index 305b577..bbe0ee3 100644 --- a/src/components/Site.tsx +++ b/src/components/Site.tsx @@ -5,11 +5,13 @@ import level_y_values from "../resources/level_y_values.json"; import blue_orb_positions from "../resources/blue_orb_positions.json"; import BlueOrb from "./BlueOrb"; import { a, useSpring } from "@react-spring/three"; -import { useBlueOrbStore, useSiteStore } from "../store"; +import { useBlueOrbStore, useLevelStore, useSiteStore } from "../store"; const Site = memo(() => { const activeBlueOrbId = useBlueOrbStore((state) => state.blueOrbId); + const activeLevels = useLevelStore((state) => state.activeLevels); + const siteRotY = useSiteStore((state) => state.siteRotY); const sitePosY = useSiteStore((state) => state.sitePosY); @@ -24,17 +26,21 @@ const Site = memo(() => { {/*distance between LEVELS is 1.5*/} {Object.entries(level_y_values).map((level: [string, number]) => { - return ( - - ); + if (activeLevels.includes(level[0].toString())) + return ( + + ); })} {Object.entries(site_a).map((blueOrb) => { - if ((blueOrb as any)[1]["unlocked_by"] === "-1") + if ( + (blueOrb as any)[1]["unlocked_by"] === "-1" && + activeLevels.includes((blueOrb as any)[0].substr(0, 2)) + ) return ( void; }; +type LevelState = { + activeLevels: string[]; + setActiveLevels: (to: string[]) => void; +}; + type MiddleRingState = { middleRingWobbleStrength: number; middleRingRotating: boolean; @@ -188,3 +193,8 @@ export const useMiddleRingStore = create((set) => ({ setMiddleRingAnimDuration: (to) => set(() => ({ middleRingAnimDuration: to })), })); + +export const useLevelStore = create((set) => ({ + activeLevels: ["03", "04", "05"], + setActiveLevels: (to) => set(() => ({ activeLevels: to })), +}));