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

@ -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 (
<group
@ -145,10 +165,10 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
>
{props.active ? (
<a.mesh
position-x={activeBlueOrbState.activeBlueOrbPosX}
position-y={activeBlueOrbState.activeBlueOrbPosY}
position-z={activeBlueOrbState.activeBlueOrbPosZ}
rotation-z={activeBlueOrbState.activeBlueOrbRotZ}
position-x={activeBlueOrbPosX}
position-y={activeBlueOrbPosY}
position-z={activeBlueOrbPosZ}
rotation-z={activeBlueOrbRotZ}
rotation-y={props.rotation[1]}
scale={[0.36, 0.18, 0.36]}
renderOrder={1}

View file

@ -43,10 +43,6 @@ const MainScene = () => {
setActiveBlueOrbHudId("fg_hud_1");
}, [setActiveBlueOrb, setActiveBlueOrbHudId, setLainMoveState]);
// set lain intro spritesheet before the page loads fully
useEffect(() => {
// setLainMoving(true);
// setLainMoveState(<LainIntro />);
}, [setLainMoveState]);
return (
<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 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*/}
<a.group rotation-y={siteState.siteRotY} position-y={siteState.sitePosY}>
{Object.entries(level_y_values).map((level: [string, number]) => {
return (
<Level
levelPosY={level[1]}
key={level[1]}
level={level[0].toString()}
/>
);
if (activeLevels.includes(level[0].toString()))
return (
<Level
levelPosY={level[1]}
key={level[1]}
level={level[0].toString()}
/>
);
})}
{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 (
<BlueOrb
sprite={(blueOrb as any)[1]["node_name"]}

View file

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