transient updates on active blue orb

This commit is contained in:
ad044 2020-10-18 15:49:26 +04:00
parent bc4fc74f45
commit 4f86d2dbe0
4 changed files with 67 additions and 35 deletions

View file

@ -28,13 +28,6 @@ type BlueOrbContructorProps = {
}; };
const BlueOrb = memo((props: 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 // the game only has a couple of sprites that it displays in the hub
// dynamically importnig them would be worse for performance, // dynamically importnig them would be worse for performance,
// so we import all of them here and then use this function to // 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({ // these pieces of state get updated transiently rather than reactively
activeBlueOrbPosX: isActiveBlueOrbInteractedWith // to avoid excess unnecessary renders (this is absolutely crucial for performance).
? activeBlueOrbPosX const [
{
activeBlueOrbPosX,
activeBlueOrbPosY,
activeBlueOrbPosZ,
activeBlueOrbRotZ,
},
set,
] = useSpring(() => ({
activeBlueOrbPosX: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith
? useBlueOrbStore.getState().activeBlueOrbPosX
: props.position[0], : props.position[0],
activeBlueOrbPosY: isActiveBlueOrbInteractedWith activeBlueOrbPosY: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith
? level_y_values[props.level as keyof typeof level_y_values] ? level_y_values[props.level as keyof typeof level_y_values]
: props.position[1], : props.position[1],
activeBlueOrbPosZ: isActiveBlueOrbInteractedWith activeBlueOrbPosZ: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith
? activeBlueOrbPosZ ? useBlueOrbStore.getState().activeBlueOrbPosZ
: props.position[2], : props.position[2],
activeBlueOrbRotZ: isActiveBlueOrbInteractedWith activeBlueOrbRotZ: useBlueOrbStore.getState().isActiveBlueOrbInteractedWith
? activeBlueOrbRotZ ? useBlueOrbStore.getState().activeBlueOrbRotZ
: 0.001, : 0,
config: { duration: 800 }, 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 ( return (
<group <group
@ -145,10 +165,10 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
> >
{props.active ? ( {props.active ? (
<a.mesh <a.mesh
position-x={activeBlueOrbState.activeBlueOrbPosX} position-x={activeBlueOrbPosX}
position-y={activeBlueOrbState.activeBlueOrbPosY} position-y={activeBlueOrbPosY}
position-z={activeBlueOrbState.activeBlueOrbPosZ} position-z={activeBlueOrbPosZ}
rotation-z={activeBlueOrbState.activeBlueOrbRotZ} rotation-z={activeBlueOrbRotZ}
rotation-y={props.rotation[1]} rotation-y={props.rotation[1]}
scale={[0.36, 0.18, 0.36]} scale={[0.36, 0.18, 0.36]}
renderOrder={1} renderOrder={1}

View file

@ -43,10 +43,6 @@ const MainScene = () => {
setActiveBlueOrbHudId("fg_hud_1"); setActiveBlueOrbHudId("fg_hud_1");
}, [setActiveBlueOrb, setActiveBlueOrbHudId, setLainMoveState]); }, [setActiveBlueOrb, setActiveBlueOrbHudId, setLainMoveState]);
// set lain intro spritesheet before the page loads fully // set lain intro spritesheet before the page loads fully
useEffect(() => {
// setLainMoving(true);
// setLainMoveState(<LainIntro />);
}, [setLainMoveState]);
return ( return (
<perspectiveCamera position-z={3}> <perspectiveCamera position-z={3}>

View file

@ -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 blue_orb_positions from "../resources/blue_orb_positions.json";
import BlueOrb from "./BlueOrb"; import BlueOrb from "./BlueOrb";
import { a, useSpring } from "@react-spring/three"; import { a, useSpring } from "@react-spring/three";
import { useBlueOrbStore, useSiteStore } from "../store"; import { useBlueOrbStore, useLevelStore, useSiteStore } from "../store";
const Site = memo(() => { const Site = memo(() => {
const activeBlueOrbId = useBlueOrbStore((state) => state.blueOrbId); const activeBlueOrbId = useBlueOrbStore((state) => state.blueOrbId);
const activeLevels = useLevelStore((state) => state.activeLevels);
const siteRotY = useSiteStore((state) => state.siteRotY); const siteRotY = useSiteStore((state) => state.siteRotY);
const sitePosY = useSiteStore((state) => state.sitePosY); const sitePosY = useSiteStore((state) => state.sitePosY);
@ -24,6 +26,7 @@ const Site = memo(() => {
{/*distance between LEVELS is 1.5*/} {/*distance between LEVELS is 1.5*/}
<a.group rotation-y={siteState.siteRotY} position-y={siteState.sitePosY}> <a.group rotation-y={siteState.siteRotY} position-y={siteState.sitePosY}>
{Object.entries(level_y_values).map((level: [string, number]) => { {Object.entries(level_y_values).map((level: [string, number]) => {
if (activeLevels.includes(level[0].toString()))
return ( return (
<Level <Level
levelPosY={level[1]} levelPosY={level[1]}
@ -34,7 +37,10 @@ const Site = memo(() => {
})} })}
{Object.entries(site_a).map((blueOrb) => { {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 ( return (
<BlueOrb <BlueOrb
sprite={(blueOrb as any)[1]["node_name"]} sprite={(blueOrb as any)[1]["node_name"]}

View file

@ -71,6 +71,11 @@ type SiteState = {
setIsSiteChanging: (to: boolean) => void; setIsSiteChanging: (to: boolean) => void;
}; };
type LevelState = {
activeLevels: string[];
setActiveLevels: (to: string[]) => void;
};
type MiddleRingState = { type MiddleRingState = {
middleRingWobbleStrength: number; middleRingWobbleStrength: number;
middleRingRotating: boolean; middleRingRotating: boolean;
@ -188,3 +193,8 @@ export const useMiddleRingStore = create<MiddleRingState>((set) => ({
setMiddleRingAnimDuration: (to) => setMiddleRingAnimDuration: (to) =>
set(() => ({ middleRingAnimDuration: to })), set(() => ({ middleRingAnimDuration: to })),
})); }));
export const useLevelStore = create<LevelState>((set) => ({
activeLevels: ["03", "04", "05"],
setActiveLevels: (to) => set(() => ({ activeLevels: to })),
}));