ported to zustand, still gotta do some bugfixing.

This commit is contained in:
ad044 2020-10-15 01:34:21 +04:00
parent ba9a16ea74
commit 6554e689ab
38 changed files with 557 additions and 783 deletions

5
package-lock.json generated
View file

@ -10842,11 +10842,6 @@
"util.promisify": "^1.0.0"
}
},
"recoil": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/recoil/-/recoil-0.0.10.tgz",
"integrity": "sha512-+9gRqehw3yKETmoZbhSnWu4GO10HDb5xYf1CjLF1oXGK2uT6GX5Lu9mfTXwjxV/jXxEKx8MIRUUbgPxvbJ8SEw=="
},
"recursive-readdir": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",

View file

@ -17,7 +17,6 @@
"react-dom": "^16.13.1",
"react-scripts": "3.4.3",
"react-three-fiber": "^4.2.20",
"recoil": "0.0.10",
"three": "^0.119.1",
"three-plain-animator": "^1.0.2",
"ts-node": "^9.0.0",

View file

@ -1,9 +1,8 @@
import React, { useEffect, useState } from "react";
import MainScene from "./components/MainScene/MainScene";
import MainScene from "./components/MainScene";
import "./static/css/hub.css";
import "./static/css/main.css";
import { Canvas } from "react-three-fiber";
import { RecoilRoot } from "recoil";
import Boot from "./components/Boot";
const App = () => {
@ -21,11 +20,9 @@ const App = () => {
<div id="game-root" className="game">
{/*<Boot setMoveToGame={setMoveToGame} />*/}
{/* {moveToGame ? <MainScene /> : <Boot setMoveToGame={setMoveToGame} />} */}
<Canvas concurrent>
<RecoilRoot>
<MainScene />
</RecoilRoot>
</Canvas>
<Canvas concurrent>
<MainScene />
</Canvas>
</div>
);
};

View file

@ -2,28 +2,21 @@ import React, { memo, useMemo, useRef } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import { useSpring, a } from "@react-spring/three";
import * as THREE from "three";
import Cou from "../../static/sprites/Cou.png";
import CouActive from "../../static/sprites/Cou_active.png";
import Dc from "../../static/sprites/Dc.png";
import DcActive from "../../static/sprites/Dc_active.png";
import SSkn from "../../static/sprites/SSkn.png";
import SSKnActive from "../../static/sprites/SSkn_active.png";
import Tda from "../../static/sprites/Tda.png";
import TdaActive from "../../static/sprites/Tda_active.png";
import Dia from "../../static/sprites/Dia.png";
import DiaActive from "../../static/sprites/Dia_active.png";
import Lda from "../../static/sprites/Lda.png";
import LdaActive from "../../static/sprites/Lda_active.png";
import MULTI from "../../static/sprites/MULTI.png";
import MULTIActive from "../../static/sprites/MULTI_active.png";
import level_y_values from "../../resources/level_y_values.json";
import { useRecoilValue } from "recoil";
import {
currentBlueOrbAnimatingAtom,
currentBlueOrbPosXAtom,
currentBlueOrbPosYAtom,
currentBlueOrbPosZAtom,
} from "./CurrentBlueOrbAtom";
import Cou from "../static/sprites/Cou.png";
import CouActive from "../static/sprites/Cou_active.png";
import Dc from "../static/sprites/Dc.png";
import DcActive from "../static/sprites/Dc_active.png";
import SSkn from "../static/sprites/SSkn.png";
import SSKnActive from "../static/sprites/SSkn_active.png";
import Tda from "../static/sprites/Tda.png";
import TdaActive from "../static/sprites/Tda_active.png";
import Dia from "../static/sprites/Dia.png";
import DiaActive from "../static/sprites/Dia_active.png";
import Lda from "../static/sprites/Lda.png";
import LdaActive from "../static/sprites/Lda_active.png";
import MULTI from "../static/sprites/MULTI.png";
import MULTIActive from "../static/sprites/MULTI_active.png";
import level_y_values from "../resources/level_y_values.json";
type BlueOrbContructorProps = {
sprite: string;
@ -46,10 +39,6 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
// dynamically importnig them would be worse for performance,
// so we import all of them here and then use this function to
// associate a sprite with the path
const currentBlueOrbAnimating = useRecoilValue(currentBlueOrbAnimatingAtom);
const currentBlueOrbPosX = useRecoilValue(currentBlueOrbPosXAtom);
const currentBlueOrbPosY = useRecoilValue(currentBlueOrbPosYAtom);
const currentBlueOrbPosZ = useRecoilValue(currentBlueOrbPosZAtom);
const spriteToPath = (sprite: string) => {
if (sprite.includes("S")) {
@ -128,31 +117,12 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
}
});
const currentBlueOrbState = useSpring({
currentBlueOrbPosX: currentBlueOrbPosX,
currentBlueOrbPosY: currentBlueOrbPosY,
currentBlueOrbPosZ: currentBlueOrbPosZ,
config: { duration: 900 },
});
return (
<group position={[0, (level_y_values as LevelYValues)[props.level], 0]}>
<a.mesh
position-x={
props.active && currentBlueOrbAnimating
? currentBlueOrbState.currentBlueOrbPosX
: props.position[0]
}
position-y={
props.active && currentBlueOrbAnimating
? currentBlueOrbState.currentBlueOrbPosY
: props.position[1]
}
position-z={
props.active && currentBlueOrbAnimating
? currentBlueOrbState.currentBlueOrbPosZ
: props.position[2]
}
position-x={props.position[0]}
position-y={props.position[1]}
position-z={props.position[2]}
rotation-y={props.rotation[1]}
scale={[0.36, 0.18, 0.36]}
renderOrder={1}

View file

@ -1,26 +0,0 @@
import { atom } from "recoil";
export const currentBlueOrbAtom = atom({
key: "currentBlueOrbAtom",
default: "0422",
});
export const currentBlueOrbAnimatingAtom = atom({
key: "currentBlueOrbAnimatingAtom",
default: false,
});
export const currentBlueOrbPosXAtom = atom({
key: "currentBlueOrbPosXAtom",
default: 0,
});
export const currentBlueOrbPosYAtom = atom({
key: "currentBlueOrbPosYAtom",
default: 0,
});
export const currentBlueOrbPosZAtom = atom({
key: "currentBlueOrbPosZAtom",
default: 0,
});

View file

@ -1,13 +1,14 @@
import React, { createRef, memo, RefObject, useRef } from "react";
import * as THREE from "three";
import { useFrame } from "react-three-fiber";
import { useRecoilValue } from "recoil";
import { grayPlanesVisibleAtom } from "./GrayPlanesAtom";
import { useGrayPlanesStore } from "../store";
const GrayPlanes = memo(() => {
const grayPlaneGroupRef = useRef<THREE.Object3D>();
const grayPlanesVisible = useRecoilValue(grayPlanesVisibleAtom);
const grayPlanesVisible = useGrayPlanesStore(
(state) => state.grayPlanesVisible
);
const grayPlanePoses = [
[1.2, 0, -1.2],

View file

@ -1,6 +0,0 @@
import { atom } from "recoil";
export const grayPlanesVisibleAtom = atom({
key: "grayPlanesVisibleAtom",
default: false,
});

View file

@ -1,25 +1,23 @@
import React, { memo } from "react";
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";
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 bigHud from "../static/sprites/big_hud.png";
import bigHudMirrored from "../static/sprites/big_hud_mirrored.png";
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, useTrail } from "@react-spring/three";
import { useRecoilValue } from "recoil";
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";
import { useBlueOrbStore, useSiteStore } 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";
export type HUDElementProps = {
hudVisibility: boolean;
};
const HUDElement = memo((props: HUDElementProps) => {
const HUD = memo((props: HUDElementProps) => {
const hudActive = useBlueOrbStore((state) => state.hudActive);
const currentBlueOrbId = useBlueOrbStore((state) => state.blueOrbId);
@ -37,23 +35,22 @@ const HUDElement = memo((props: HUDElementProps) => {
const yellowTextArr = currentYellowHudText.split("");
const greenTextArr = currentGreenHudText.split("");
const yellowLetterPosY = yellowHudTextPosY;
const yellowLetterPosX = yellowHudTextPosX;
const isSiteChangingY = useRecoilValue(isSiteYChangingAtom);
const isSiteChangingY = useSiteStore((state) => state.isSiteChangingY);
// this one is used for letter actions
const letterTrail = useTrail(currentYellowHudText.length, {
yellowLetterPosX: yellowLetterPosX,
yellowLetterPosY: yellowLetterPosY,
yellowLetterPosX: yellowHudTextPosX,
yellowLetterPosY: yellowHudTextPosY,
config: { duration: 280 },
});
console.log(yellowHudTextPosY);
console.log(yellowHudTextPosX);
// this one is used when the site moves up/down and
// the text has to stay stationary
const letterStaticState = useSpring({
yellowLetterPosX: yellowLetterPosX,
yellowLetterPosY: yellowLetterPosY,
yellowLetterPosX: yellowHudTextPosX,
yellowLetterPosY: yellowHudTextPosY,
config: { duration: 1200 },
});
@ -230,4 +227,4 @@ const HUDElement = memo((props: HUDElementProps) => {
);
});
export default HUDElement;
export default HUD;

View file

@ -1,42 +0,0 @@
import { atom } from "recoil";
import blue_orb_huds from "../../resources/blue_orb_huds.json";
export const hudVisibilityAtom = atom({
key: "hudVisibilityAtom",
default: true,
});
export const currentHUDAtom = atom({
key: "currentHUDAtom",
default: blue_orb_huds.fg_hud_1,
});
export const yellowLetterPosYAtom = atom({
key: "yellowLetterPosYAtom",
default: blue_orb_huds.fg_hud_1.big_text[1],
});
export const yellowLetterPosXAtom = atom({
key: "yellowLetterPosXAtom",
default: blue_orb_huds.fg_hud_1.big_text[0],
});
export const bigHudTextAtom = atom({
key: "bigHudTextAtom",
default: "Tda031",
});
export const mediumHudTextAtom = atom({
key: "mediumHudTextAtom",
default: "TOUKO's DIARY",
});
export const mediumHudTextPosYAtom = atom({
key: "mediumHudTextPosYAtom",
default: 0.16,
});
export const mediumHudTextPosXAtom = atom({
key: "mediumHudTextPosXAtom",
default: 0.18,
});

View file

@ -1,21 +1,12 @@
import React, { useCallback, useEffect, useMemo, useState } from "react";
import { useSetRecoilState } from "recoil";
import {
currentBlueOrbAnimatingAtom,
currentBlueOrbPosXAtom,
currentBlueOrbPosYAtom,
currentBlueOrbPosZAtom,
} from "../BlueOrb/CurrentBlueOrbAtom";
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 SiteStateManager from "./SiteStateManager";
import MiddleRingStateManager from "./MiddleRingStateManager";
import LainStateManager from "./LainStateManager";
import BlueOrbStateManager from "./BlueOrbStateManager";
import BlueOrbHUDStateManager from "./BlueOrbHUDStateManager";
import BlueOrbHUDTextStateManager from "./BlueOrbHUDTextStateManager";
import blue_orb_directions from "../resources/blue_orb_directions.json";
import site_a from "../resources/site_a.json";
import SiteStateManager from "./StateManagers/SiteStateManager";
import MiddleRingStateManager from "./StateManagers/MiddleRingStateManager";
import LainStateManager from "./StateManagers/LainStateManager";
import BlueOrbStateManager from "./StateManagers/BlueOrbStateManager";
import BlueOrbHUDStateManager from "./StateManagers/BlueOrbHUDStateManager";
import BlueOrbHUDTextStateManager from "./StateManagers/BlueOrbHUDTextStateManager";
import { useBlueOrbStore } from "../store";
type KeyCodeAssociations = {
@ -41,16 +32,9 @@ type BlueOrbStateData = {
const InputHandler = () => {
const [eventState, setEventState] = useState<string>();
const currentBlueOrb = useBlueOrbStore((state) => state.blueOrbId);
const setCurrentBlueOrbAnimating = useSetRecoilState(
currentBlueOrbAnimatingAtom
);
const [blueOrbStateData, setBlueOrbStateData] = useState<BlueOrbStateData>();
const setCurrentBlueOrbPosX = useSetRecoilState(currentBlueOrbPosXAtom);
const setCurrentBlueOrbPosY = useSetRecoilState(currentBlueOrbPosYAtom);
const setCurrentBlueOrbPosZ = useSetRecoilState(currentBlueOrbPosZAtom);
const [inputCooldown, setInputCooldown] = useState(false);
const moveEvents = useMemo(
@ -126,43 +110,9 @@ const InputHandler = () => {
setEventState(event);
}
} else if (blueOrbPressKeys.includes(keyPress) && !inputCooldown) {
const currentBlueOrbLevel = currentBlueOrb.substr(0, 2);
const currentBlueOrbPosId = currentBlueOrb.substr(2);
const levelYVal =
level_y_values[currentBlueOrbLevel as keyof typeof level_y_values];
const currentBlueOrbPos =
blue_orb_positions[
currentBlueOrbPosId as keyof typeof blue_orb_positions
].position;
setCurrentBlueOrbPosX(currentBlueOrbPos[0]);
setCurrentBlueOrbPosY(currentBlueOrbPos[1] + levelYVal);
setCurrentBlueOrbPosZ(currentBlueOrbPos[2]);
setTimeout(() => {
setCurrentBlueOrbAnimating(true);
setCurrentBlueOrbPosX(0.5);
setCurrentBlueOrbPosY(levelYVal);
setCurrentBlueOrbPosZ(0);
}, 1500);
setTimeout(() => {
setCurrentBlueOrbAnimating(false);
}, 4200);
}
},
[
inputCooldown,
currentBlueOrb,
moveEvents,
blueOrbChangeEvents,
setCurrentBlueOrbPosX,
setCurrentBlueOrbPosY,
setCurrentBlueOrbPosZ,
setCurrentBlueOrbAnimating,
]
[inputCooldown, currentBlueOrb, moveEvents, blueOrbChangeEvents]
);
useEffect(() => {

View file

@ -1,57 +0,0 @@
import React, { useEffect, useMemo } from "react";
import { useSetRecoilState } from "recoil";
import {
isSiteYChangingAtom,
sitePosYAtom,
siteRotYAtom,
} from "../Site/SiteAtom";
const SiteStateManager = (props: any) => {
const setSiteRotY = useSetRecoilState(siteRotYAtom);
const setSitePosY = useSetRecoilState(sitePosYAtom);
const setIsSiteYChanging = useSetRecoilState(isSiteYChangingAtom);
const dispatcherObjects = useMemo(
() => ({
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(() => {
if (props.eventState) {
const dispatchedAction =
dispatcherObjects[props.eventState as keyof typeof dispatcherObjects];
if (dispatchedAction) {
setIsSiteYChanging(true);
setTimeout(() => {
dispatchedAction.action(
(prev: number) => prev + dispatchedAction.value
);
}, dispatchedAction.actionDelay);
setTimeout(() => {
setIsSiteYChanging(false);
}, 3000);
}
}
}, [
dispatcherObjects,
props.eventState,
setIsSiteYChanging,
setSitePosY,
setSiteRotY,
]);
return null;
};
export default SiteStateManager;

View file

@ -2,15 +2,14 @@ import React, { Suspense, useState } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import { PlainSingularAnimator } from "three-plain-animator/lib/plain-singular-animator";
import moveDownSpriteSheet from "../../static/sprites/jump_down.png";
import moveUpSpriteSheet from "../../static/sprites/jump_up.png";
import moveLeftSpriteSheet from "../../static/sprites/move_left.png";
import moveRightSpriteSheet from "../../static/sprites/move_right.png";
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 } from "./LainAtom";
import moveDownSpriteSheet from "../static/sprites/jump_down.png";
import moveUpSpriteSheet from "../static/sprites/jump_up.png";
import moveLeftSpriteSheet from "../static/sprites/move_left.png";
import moveRightSpriteSheet from "../static/sprites/move_right.png";
import standingSpriteSheet from "../static/sprites/standing.png";
import introSpriteSheet from "../static/sprites/intro.png";
import throwBlueOrbSpriteSheet from "../static/sprites/throw_blue_orb.png";
import { useLainStore } from "../store";
type LainConstructorProps = {
sprite: string;
@ -113,12 +112,24 @@ export const LainThrowBlueOrb = () => {
};
const Lain = () => {
const lainMoveState = useRecoilValue(lainMoveStateAtom);
const lainMoveState = useLainStore((state) => state.lainMoveState);
const lainAnimationDispatch = {
standing: <LainStanding />,
moveLeft: <LainMoveLeft />,
moveRight: <LainMoveRight />,
moveUp: <LainMoveUp />,
moveDown: <LainMoveDown />,
};
return (
<Suspense fallback={<>loading...</>}>
<sprite scale={[4.5, 4.5, 4.5]} position={[0, -0.15, 0]}>
{lainMoveState}
{
lainAnimationDispatch[
lainMoveState as keyof typeof lainAnimationDispatch
]
}
</sprite>
</Suspense>
);

View file

@ -1,7 +0,0 @@
import { atom } from "recoil";
import React from "react";
export const lainMoveStateAtom = atom({
key: "lainMoveStateAtom",
default: <></>,
});

View file

@ -1,29 +1,23 @@
import { a, useSpring } from "@react-spring/three";
import { OrbitControls } from "drei";
import React, { Suspense, useEffect } from "react";
import Site from "../Site/Site";
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 } from "../Lain/LainAtom";
import InputHandler from "../InputHandler/InputHandler";
import Site from "./Site";
import Lain from "./Lain";
import Lights from "./Lights";
import OrthoCamera from "./OrthoCamera";
import Preloader from "./Preloader";
import InputHandler from "./InputHandler";
import MainSceneIntro from "./MainSceneIntro";
import {
mainGroupPosYAtom,
mainGroupPosZAtom,
mainGroupRotXAtom,
} from "./MainGroupAtom";
import GrayPlanes from "../GrayPlanes/GrayPlanes";
import MiddleRing from "../MiddleRing/MiddleRing";
import Starfield from "../Starfield/Starfield";
import GrayPlanes from "./GrayPlanes";
import MiddleRing from "./MiddleRing";
import Starfield from "./Starfield";
import { useLainStore, useMainGroupStore } from "../store";
const MainScene = () => {
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
const mainGroupPosY = useRecoilValue(mainGroupPosYAtom);
const mainGroupPosZ = useRecoilValue(mainGroupPosZAtom);
const mainGroupRotX = useRecoilValue(mainGroupRotXAtom);
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
const mainGroupPosY = useMainGroupStore((state) => state.mainGroupPosY);
const mainGroupPosZ = useMainGroupStore((state) => state.mainGroupPosZ);
const mainGroupRotX = useMainGroupStore((state) => state.mainGroupRotX);
const mainGroupStatePos = useSpring({
mainGroupPosY: mainGroupPosY,
@ -37,7 +31,7 @@ const MainScene = () => {
});
useEffect(() => {
setLainMoveState(<LainStanding />);
setLainMoveState("standing");
}, [setLainMoveState]);
// set lain intro spritesheet before the page loads fully
useEffect(() => {

View file

@ -1,19 +0,0 @@
import { atom } from "recoil";
// -2.5 - intro val
export const mainGroupPosYAtom = atom({
key: "mainGroupPosYAtom",
default: 0,
});
//-9.5 - intro val
export const mainGroupPosZAtom = atom({
key: "mainGroupPosZAtom",
default: 0,
});
//1.5 - intro val
export const mainGroupRotXAtom = atom({
key: "mainGroupRotXAtom",
default: 0,
});

View file

@ -1,95 +0,0 @@
import React, { memo, useEffect } from "react";
import { useSetRecoilState } from "recoil";
import { hudVisibilityAtom } from "../HUD/HUDElementAtom";
import {
mainGroupPosYAtom,
mainGroupPosZAtom,
mainGroupRotXAtom,
} from "./MainGroupAtom";
import { LainStanding } from "../Lain/Lain";
import { lainMoveStateAtom } from "../Lain/LainAtom";
import { orbVisibilityAtom } from "../Orb/OrbAtom";
import {
introStarfieldVisibilityAtom,
mainStarfieldBoostValAtom,
mainStarfieldVisibilityAtom,
} from "../Starfield/StarfieldAtom";
import { grayPlanesVisibleAtom } from "../GrayPlanes/GrayPlanesAtom";
import { useBlueOrbStore } from "../store";
// ghost component to manipulate the intro action for the main scene.
// we separate this file because having something like this
// inside <Suspense> 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 toggleHud = useBlueOrbStore((state) => state.toggleHud);
const setHudVisible = useSetRecoilState(hudVisibilityAtom);
const setOrbVisible = useSetRecoilState(orbVisibilityAtom);
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
const setIntroStarfieldVisible = useSetRecoilState(
introStarfieldVisibilityAtom
);
const setMainStarfieldVisible = useSetRecoilState(
mainStarfieldVisibilityAtom
);
const setMainStarfieldBoostVal = useSetRecoilState(mainStarfieldBoostValAtom);
const setMainGroupPosY = useSetRecoilState(mainGroupPosYAtom);
const setMainGroupPosZ = useSetRecoilState(mainGroupPosZAtom);
const setMainGroupRotX = useSetRecoilState(mainGroupRotXAtom);
const setGrayPlanesVisible = useSetRecoilState(grayPlanesVisibleAtom);
useEffect(() => {
setMainGroupPosY(0);
setMainGroupPosZ(0);
setTimeout(() => {
setMainGroupRotX(0);
}, 2400);
setTimeout(() => {
setGrayPlanesVisible(true);
}, 2500);
setTimeout(() => {
setMainStarfieldVisible(true);
setMainStarfieldBoostVal(0);
}, 2800);
toggleHud();
setTimeout(() => {
setLainMoveState(<LainStanding />);
setOrbVisible(true);
setHudVisible(true);
setIntroStarfieldVisible(false);
toggleHud();
setTimeout(() => {
document.getElementsByTagName("canvas")[0].className = "hub-background";
}, 300);
}, 3860);
}, [
setGrayPlanesVisible,
setMainStarfieldBoostVal,
setMainStarfieldVisible,
setHudVisible,
setOrbVisible,
setIntroStarfieldVisible,
setMainGroupRotX,
setMainGroupPosZ,
setMainGroupPosY,
setLainMoveState,
toggleHud,
]);
return <></>;
});
export default MainSceneIntro;

View file

@ -0,0 +1,89 @@
import React, { memo, useEffect } from "react";
import {
useBlueOrbStore,
useGrayPlanesStore,
useLainStore,
useMainGroupStore,
useStarfieldStore,
useYellowOrbStore,
} from "../store";
// ghost component to manipulate the intro action for the main scene.
// we separate this file because having something like this
// inside <Suspense> 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 toggleHud = useBlueOrbStore((state) => state.toggleHud);
//const setHudVisible = useSetRecoilState(hudVisibilityAtom);
const setOrbVisible = useYellowOrbStore((state) => state.setYellowOrbVisible);
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
const setIntroStarfieldVisible = useStarfieldStore(
(state) => state.setIntroStarfieldVisible
);
const setMainStarfieldVisible = useStarfieldStore(
(state) => state.setMainStarfieldVisible
);
const setMainStarfieldBoostVal = useStarfieldStore(
(state) => state.setMainStarfieldBoostVal
);
const setMainGroupPosY = useMainGroupStore((state) => state.setMainGroupPosY);
const setMainGroupPosZ = useMainGroupStore((state) => state.setMainGroupPosZ);
const setMainGroupRotX = useMainGroupStore((state) => state.setMainGroupRotX);
const setGrayPlanesVisible = useGrayPlanesStore(
(state) => state.setGrayPlanesVisible
);
useEffect(() => {
setMainGroupPosY(0);
setMainGroupPosZ(0);
setTimeout(() => {
setMainGroupRotX(0);
}, 2400);
setTimeout(() => {
setGrayPlanesVisible(true);
}, 2500);
setTimeout(() => {
setMainStarfieldVisible(true);
setMainStarfieldBoostVal(0);
}, 2800);
toggleHud();
setTimeout(() => {
setLainMoveState("standing");
setOrbVisible(true);
//setHudVisible(true);
setIntroStarfieldVisible(false);
toggleHud();
setTimeout(() => {
document.getElementsByTagName("canvas")[0].className = "hub-background";
}, 300);
}, 3860);
}, [
setGrayPlanesVisible,
setMainStarfieldBoostVal,
setMainStarfieldVisible,
setOrbVisible,
setIntroStarfieldVisible,
setMainGroupRotX,
setMainGroupPosZ,
setMainGroupPosY,
setLainMoveState,
toggleHud,
]);
return <></>;
});
export default MainSceneIntro;

View file

@ -1,29 +1,27 @@
import React, { useMemo, useRef } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import middleRingTexture from "../../static/sprites/middle_ring_tex.png";
import middleRingTexture from "../static/sprites/middle_ring_tex.png";
import * as THREE from "three";
import { a, useSpring } from "@react-spring/three";
import {
middleRingAnimDurationAtom,
middleRingNoiseAtom, middleRingPosYAtom,
middleRingRotatingAtom,
middleRingRotXAtom,
middleRingRotZAtom,
middleRingWobbleStrengthAtom,
} from "./MiddleRingAtom";
import { useRecoilValue } from "recoil";
import { useMiddleRingStore } from "../store";
const MiddleRing = () => {
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
const middleRingWobbleStrength = useRecoilValue(middleRingWobbleStrengthAtom);
const middleRingRotating = useRecoilValue(middleRingRotatingAtom);
const middleRingNoise = useRecoilValue(middleRingNoiseAtom);
const middleRingPosY = useRecoilValue(middleRingPosYAtom);
const middleRingRotX = useRecoilValue(middleRingRotXAtom);
const middleRingRotZ = useRecoilValue(middleRingRotZAtom);
const middleRingWobbleStrength = useMiddleRingStore(
(state) => state.middleRingWobbleStrength
);
const middleRingRotating = useMiddleRingStore(
(state) => state.middleRingRotating
);
const middleRingNoise = useMiddleRingStore((state) => state.middleRingNoise);
const middleRingPosY = useMiddleRingStore((state) => state.middleRingPosY);
const middleRingRotX = useMiddleRingStore((state) => state.middleRingRotX);
const middleRingRotZ = useMiddleRingStore((state) => state.middleRingRotZ);
const middleRingAnimDuration = useRecoilValue(middleRingAnimDurationAtom);
const middleRingAnimDuration = useMiddleRingStore(
(state) => state.middleRingAnimDuration
);
const middleRingWobbleState = useSpring({
middleRingWobbleStrength: middleRingWobbleStrength,
@ -212,9 +210,7 @@ const MiddleRing = () => {
});
return (
<a.group
rotation-z={middleRingRotState.middleRingRotZ}
>
<a.group rotation-z={middleRingRotState.middleRingRotZ}>
<a.mesh
position={[0, 0, 0.3]}
position-y={middleRingPosState.middleRingPosY}

View file

@ -1,36 +0,0 @@
import { atom } from "recoil";
export const middleRingWobbleStrengthAtom = atom({
key: "middleRingWobbleStrengthAtom",
default: 0.0,
});
export const middleRingRotatingAtom = atom({
key: "middleRingRotatingAtom",
default: true,
});
export const middleRingNoiseAtom = atom({
key: "middleRingNoiseAtom",
default: 0.03,
});
export const middleRingPosYAtom = atom({
key: "middleRingPosYAtom",
default: -0.11,
});
export const middleRingRotXAtom = atom({
key: "middleRingRotXAtom",
default: 0,
});
export const middleRingRotZAtom = atom({
key: "middleRingRotZAtom",
default: 0,
});
export const middleRingAnimDurationAtom = atom({
key: "middleRingAnimDurationAtom",
default: 600,
});

View file

@ -1,6 +0,0 @@
import { atom } from "recoil";
export const orbVisibilityAtom = atom({
key: "orbVisibilityAtom",
default: false,
});

View file

@ -0,0 +1,36 @@
import React, { memo, useMemo, useRef } from "react";
import { useFrame, useThree } from "react-three-fiber";
import { Scene } from "three";
import HUD from "./HUD";
import YellowOrb from "./YellowOrb";
import { useBlueOrbStore } from "../store";
const OrthoCamera = memo(() => {
const { gl, scene, camera } = useThree();
const virtualScene = useMemo(() => new Scene(), []);
const virtualCam = useRef();
const hudVisible = useBlueOrbStore((state) => state.hudVisible);
useFrame(() => {
gl.autoClear = false;
gl.clear();
gl.render(scene, camera);
gl.clearDepth();
gl.render(virtualScene, virtualCam.current!);
}, 1);
//-0.6
return (
<orthographicCamera
ref={virtualCam}
position={[0, 0, 10]}
rotation={[0, 0, 0]}
>
<HUD key={1} hudVisibility={hudVisible} />
<YellowOrb />
</orthographicCamera>
);
});
export default OrthoCamera;

View file

@ -1,53 +0,0 @@
import React, { memo, useMemo, useRef } from "react";
import { useFrame, useThree } from "react-three-fiber";
import { Scene } from "three";
import HUDElement from "../HUD/HUDElement";
import Orb from "../Orb/Orb";
import { useRecoilValue } from "recoil";
import { orthoCamPosYAtom, orthoCamRotYAtom } from "./OrthoCameraAtom";
import { useSpring, a } from "@react-spring/three";
import { orbVisibilityAtom } from "../Orb/OrbAtom";
import { hudVisibilityAtom } from "../HUD/HUDElementAtom";
const OrthoCamera = memo(() => {
const { gl, scene, camera } = useThree();
const virtualScene = useMemo(() => new Scene(), []);
const virtualCam = useRef();
const orthoCameraPosY = useRecoilValue(orthoCamPosYAtom);
const orthoCameraRotY = useRecoilValue(orthoCamRotYAtom);
const orbVisible = useRecoilValue(orbVisibilityAtom);
const hudVisible = useRecoilValue(hudVisibilityAtom);
const orthoCameraState = useSpring({
orthoCameraPosY: orthoCameraPosY,
orthoCameraRotY: orthoCameraRotY,
config: { duration: 1200 },
});
useFrame(() => {
gl.autoClear = false;
gl.clear();
gl.render(scene, camera);
gl.clearDepth();
gl.render(virtualScene, virtualCam.current!);
}, 1);
//-0.6
return (
<a.group rotation={[0, 0, 0]} rotation-y={orthoCameraState.orthoCameraRotY}>
<a.orthographicCamera
ref={virtualCam}
position={[0, 0, 10]}
rotation={[0, 0, 0]}
position-y={orthoCameraState.orthoCameraPosY}
>
<HUDElement key={1} hudVisibility={hudVisible} />
<Orb orbVisibility={orbVisible} />
</a.orthographicCamera>
</a.group>
);
});
export default OrthoCamera;

View file

@ -1,13 +0,0 @@
import { atom } from "recoil";
export const orthoCamPosYAtom = atom({
key: "orthoCamPosYAtom",
default: 0,
});
export const orthoCamRotYAtom = atom({
key: "orthoCamRotYAtom",
default: 0,
});

View file

@ -1,19 +1,17 @@
import React, { memo, Suspense } from "react";
import site_a from "../../resources/site_a.json";
import Level from "../Level";
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 site_a from "../resources/site_a.json";
import Level from "./Level";
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 { sitePosYAtom, siteRotYAtom } from "./SiteAtom";
import { useBlueOrbStore } from "../store";
import { useBlueOrbStore, useSiteStore } from "../store";
const Site = memo(() => {
const currentBlueOrbId = useBlueOrbStore((state) => state.blueOrbId);
const siteRotY = useRecoilValue(siteRotYAtom);
const sitePosY = useRecoilValue(sitePosYAtom);
const siteRotY = useSiteStore((state) => state.siteRotY);
const sitePosY = useSiteStore((state) => state.sitePosY);
const siteState = useSpring({
siteRotY: siteRotY,

View file

@ -1,16 +0,0 @@
import { atom } from "recoil";
export const siteRotYAtom = atom({
key: "siteRotYatom",
default: 0,
});
export const sitePosYAtom = atom({
key: "sitePosYAtom",
default: 0,
});
export const isSiteYChangingAtom = atom({
key: "isSiteYChangingAtom",
default: false,
});

View file

@ -2,12 +2,7 @@ import { a, useSpring } from "@react-spring/three";
import React, { createRef, memo, RefObject, useMemo, useRef } from "react";
import { useFrame } from "react-three-fiber";
import * as THREE from "three";
import {
introStarfieldVisibilityAtom,
mainStarfieldBoostValAtom,
mainStarfieldVisibilityAtom,
} from "./StarfieldAtom";
import { useRecoilValue } from "recoil";
import { useStarfieldStore } from "../store";
type StarRefsAndInitialPoses = [
React.MutableRefObject<React.RefObject<THREE.Object3D>[]>,
@ -35,10 +30,16 @@ type IntroStarfieldObjectData = {
const Starfield = memo(() => {
const introStarfieldGroupRef = useRef<THREE.Object3D>();
const introStarfieldVisible = useRecoilValue(introStarfieldVisibilityAtom);
const mainStarfieldVisible = useRecoilValue(mainStarfieldVisibilityAtom);
const introStarfieldVisible = useStarfieldStore(
(state) => state.introStarfieldVisible
);
const mainStarfieldVisible = useStarfieldStore(
(state) => state.mainStarfieldVisible
);
const mainStarfieldBoostVal = useRecoilValue(mainStarfieldBoostValAtom);
const mainStarfieldBoostVal = useStarfieldStore(
(state) => state.mainStarfieldBoostVal
);
const starfieldState = useSpring({
starfieldBoostVal: mainStarfieldBoostVal,

View file

@ -1,16 +0,0 @@
import { atom } from "recoil";
export const introStarfieldVisibilityAtom = atom({
key: "introStarfieldVisibilityAtom",
default: true,
});
export const mainStarfieldVisibilityAtom = atom({
key: "mainStarfieldVisibilityAtom",
default: false,
});
export const mainStarfieldBoostValAtom = atom({
key: "mainStarfieldBoostVal",
default: 0.2,
});

View file

@ -1,18 +1,10 @@
import React, { useEffect, useMemo } from "react";
import { useSetRecoilState } from "recoil";
import {
currentHUDAtom,
mediumHudTextAtom,
} from "../HUD/HUDElementAtom";
import { useBlueOrbStore } from "../store";
import { useBlueOrbStore } from "../../store";
const BlueOrbHUDStateManager = (props: any) => {
const setCurrentHudId = useBlueOrbStore((state) => state.setCurrentHudId);
const toggleHud = useBlueOrbStore((state) => state.toggleHud);
const setCurrentHUDElement = useSetRecoilState(currentHUDAtom);
const setMediumHudText = useSetRecoilState(mediumHudTextAtom);
const dispatcherObjects = useMemo(
() => ({
moveUp: { duration: 3903.704 },
@ -34,13 +26,11 @@ const BlueOrbHUDStateManager = (props: any) => {
const dispatchedAction =
dispatcherObjects[props.eventState as keyof typeof dispatcherObjects];
// setHudActive((prev: boolean) => !prev);
toggleHud();
setTimeout(() => {
setCurrentHudId(targetBlueOrbHudId);
// setCurrentHUDElement(targetBlueOrbHudData);
// setMediumHudText(targetBlueOrbGreenText);
toggleHud();
}, dispatchedAction.duration);
}
@ -49,9 +39,7 @@ const BlueOrbHUDStateManager = (props: any) => {
props.eventState,
props.targetBlueOrbGreenText,
props.targetBlueOrbHudId,
setCurrentHUDElement,
setCurrentHudId,
setMediumHudText,
toggleHud,
]);
return null;

View file

@ -1,9 +1,7 @@
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 { bigHudTextAtom } from "../HUD/HUDElementAtom";
import { useBlueOrbStore } from "../store";
import { useBlueOrbStore } from "../../store";
const BlueOrbHUDTextStateManager = (props: any) => {
const currentBlueOrbHudId = useBlueOrbStore((state) => state.hudId);
@ -24,11 +22,7 @@ const BlueOrbHUDTextStateManager = (props: any) => {
);
const animateYellowTextWithMove = useCallback(
(
targetBlueOrbHudId: string,
targetBlueOrbId: string,
yellowLetterPosYOffset: number
) => {
(yellowLetterPosYOffset: number) => {
// animate the letters to match that of site's
// to create an illusion of not moving
setTimeout(() => {
@ -72,44 +66,41 @@ const BlueOrbHUDTextStateManager = (props: any) => {
]
);
const animateYellowTextWithoutMove = useCallback(
(targetBlueOrbHudId: string, targetBlueOrbId: string) => {
// make current hud big text shrink
setYellowHudTextOffsetXCoeff(-1);
const animateYellowTextWithoutMove = useCallback(() => {
// make current hud big text shrink
setYellowHudTextOffsetXCoeff(-1);
setTimeout(() => {
// animate it to new pos x/y
setYellowHudTextPosX(
blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds]
.big_text[0]
);
setYellowHudTextPosY(
blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds]
.big_text[1]
);
}, 400);
setTimeout(() => {
// animate it to new pos x/y
setYellowHudTextPosX(
blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds]
.big_text[0]
);
setYellowHudTextPosY(
blue_orb_huds[currentBlueOrbHudId as keyof typeof blue_orb_huds]
.big_text[1]
);
}, 400);
setTimeout(() => {
// set new text according to the node name
setYellowHudText(
site_a[currentBlueOrbId as keyof typeof site_a].node_name
);
}, 1000);
setTimeout(() => {
// set new text according to the node name
setYellowHudText(
site_a[currentBlueOrbId as keyof typeof site_a].node_name
);
}, 1000);
setTimeout(() => {
// unshrink text
setYellowHudTextOffsetXCoeff(0);
}, 1200);
},
[
currentBlueOrbHudId,
currentBlueOrbId,
setYellowHudText,
setYellowHudTextOffsetXCoeff,
setYellowHudTextPosX,
setYellowHudTextPosY,
]
);
setTimeout(() => {
// unshrink text
setYellowHudTextOffsetXCoeff(0);
}, 1200);
}, [
currentBlueOrbHudId,
currentBlueOrbId,
setYellowHudText,
setYellowHudTextOffsetXCoeff,
setYellowHudTextPosX,
setYellowHudTextPosY,
]);
const dispatcherObjects = useMemo(
() => ({
@ -159,20 +150,13 @@ const BlueOrbHUDTextStateManager = (props: any) => {
useEffect(() => {
if (props.eventState) {
const targetBlueOrbId = props.targetBlueOrbId;
const targetBlueOrbHudId = props.targetBlueOrbHudId;
const dispatchedAction =
dispatcherObjects[props.eventState as keyof typeof dispatcherObjects];
if (dispatchedAction.action === "animateWithMove") {
animateYellowTextWithMove(
targetBlueOrbHudId,
targetBlueOrbId,
dispatchedAction.yellowLetterPosYOffset
);
animateYellowTextWithMove(dispatchedAction.yellowLetterPosYOffset);
} else {
animateYellowTextWithoutMove(targetBlueOrbHudId, targetBlueOrbId);
animateYellowTextWithoutMove();
}
}
}, [

View file

@ -1,10 +1,7 @@
import React, { useEffect, useMemo } from "react";
import { useSetRecoilState } from "recoil";
import { currentBlueOrbAtom } from "../BlueOrb/CurrentBlueOrbAtom";
import { useBlueOrbStore } from "../store";
import { useBlueOrbStore } from "../../store";
const BlueOrbStateManager = (props: any) => {
// const setCurrentBlueOrb = useSetRecoilState(currentBlueOrbAtom);
const setCurrentBlueOrb = useBlueOrbStore(
(state) => state.setCurrentBlueOrbId
);

View file

@ -1,24 +1,15 @@
import React, { useEffect, useMemo } from "react";
import { useSetRecoilState } from "recoil";
import { lainMoveStateAtom } from "../Lain/LainAtom";
import {
LainMoveDown,
LainMoveLeft,
LainMoveRight,
LainMoveUp,
LainStanding,
LainThrowBlueOrb,
} from "../Lain/Lain";
import { useLainStore } from "../../store";
const LainStateManager = (props: any) => {
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
const dispatcherObjects = useMemo(
() => ({
moveUp: { action: <LainMoveUp />, duration: 3903.704 },
moveDown: { action: <LainMoveDown />, duration: 3903.704 },
moveLeft: { action: <LainMoveLeft />, duration: 3903.704 },
moveRight: { action: <LainMoveRight />, duration: 3903.704 },
moveUp: { action: "moveUp", duration: 3903.704 },
moveDown: { action: "moveDown", duration: 3903.704 },
moveLeft: { action: "moveLeft", duration: 3903.704 },
moveRight: { action: "moveRight", duration: 3903.704 },
}),
[]
);
@ -32,7 +23,7 @@ const LainStateManager = (props: any) => {
setLainMoveState(dispatchedAction.action);
setTimeout(() => {
setLainMoveState(<LainStanding />);
setLainMoveState("standing");
}, dispatchedAction.duration);
}
}

View file

@ -1,26 +1,27 @@
import React, { useCallback, useEffect, useMemo } from "react";
import { useSetRecoilState } from "recoil";
import {
middleRingAnimDurationAtom,
middleRingNoiseAtom,
middleRingPosYAtom,
middleRingRotatingAtom,
middleRingRotXAtom,
middleRingRotZAtom,
middleRingWobbleStrengthAtom,
} from "../MiddleRing/MiddleRingAtom";
import { useMiddleRingStore } from "../../store";
const MiddleRingStateManager = (props: any) => {
const setMiddleRingWobbleStrength = useSetRecoilState(
middleRingWobbleStrengthAtom
const setMiddleRingWobbleStrength = useMiddleRingStore(
(state) => state.setMiddleRingWobbleStrength
);
const setMiddleRingRotating = useSetRecoilState(middleRingRotatingAtom);
const setMiddleRingNoise = useSetRecoilState(middleRingNoiseAtom);
const setMiddleRingPosY = useSetRecoilState(middleRingPosYAtom);
const setMiddleRingRotX = useSetRecoilState(middleRingRotXAtom);
const setMiddleRingRotZ = useSetRecoilState(middleRingRotZAtom);
const setMiddleRingAnimDuration = useSetRecoilState(
middleRingAnimDurationAtom
const setMiddleRingRotating = useMiddleRingStore(
(state) => state.setMiddleRingRotating
);
const setMiddleRingNoise = useMiddleRingStore(
(state) => state.setMiddleRingNoise
);
const addToMiddleRingPosY = useMiddleRingStore(
(state) => state.addToMiddleRingPosY
);
const setMiddleRingRotX = useMiddleRingStore(
(state) => state.setMiddleRingRotX
);
const setMiddleRingRotZ = useMiddleRingStore(
(state) => state.setMiddleRingRotZ
);
const setMiddleRingAnimDuration = useMiddleRingStore(
(state) => state.setMiddleRingAnimDuration
);
const rotateMiddleRingRight = useCallback(() => {
@ -66,7 +67,7 @@ const MiddleRingStateManager = (props: any) => {
}, 700);
setTimeout(() => {
setMiddleRingPosY((prev: number) => prev + 1.5);
addToMiddleRingPosY(1.5);
}, 1300);
// set ring rotation on x axis to craete motion effect
@ -79,11 +80,11 @@ const MiddleRingStateManager = (props: any) => {
}, 2900);
setTimeout(() => {
setMiddleRingPosY((prev: number) => prev - 1.7);
addToMiddleRingPosY(-1.7);
}, 3000);
setTimeout(() => {
setMiddleRingPosY((prev: number) => prev + 0.2);
addToMiddleRingPosY(0.2);
}, 3150);
// rotate it again, set ring noise to 0
@ -108,9 +109,9 @@ const MiddleRingStateManager = (props: any) => {
setMiddleRingNoise(0.03);
}, 11600);
}, [
addToMiddleRingPosY,
setMiddleRingAnimDuration,
setMiddleRingNoise,
setMiddleRingPosY,
setMiddleRingRotX,
setMiddleRingRotating,
]);
@ -136,7 +137,7 @@ const MiddleRingStateManager = (props: any) => {
// set the anim duration value to match that of the site's
setMiddleRingAnimDuration(1200);
// animate it after
setMiddleRingPosY((prev: number) => prev - 1.5);
addToMiddleRingPosY(-1.5);
}, 1300);
// reset the ring bend, set the rotation to slightly curve
@ -154,13 +155,13 @@ const MiddleRingStateManager = (props: any) => {
}, 2300);
setTimeout(() => {
setMiddleRingPosY((prev: number) => prev + 1.7);
addToMiddleRingPosY(1.7);
}, 2400);
// reset the rotation value to 0
setTimeout(() => {
setMiddleRingRotX(0);
setMiddleRingPosY((prev: number) => prev - 0.2);
addToMiddleRingPosY(-0.2);
}, 2650);
// enable noise again in about 8~ secs
@ -168,9 +169,9 @@ const MiddleRingStateManager = (props: any) => {
setMiddleRingNoise(0.03);
}, 7800);
}, [
addToMiddleRingPosY,
setMiddleRingAnimDuration,
setMiddleRingNoise,
setMiddleRingPosY,
setMiddleRingRotX,
setMiddleRingRotating,
setMiddleRingWobbleStrength,
@ -205,7 +206,6 @@ const MiddleRingStateManager = (props: any) => {
props.eventState,
setMiddleRingAnimDuration,
setMiddleRingNoise,
setMiddleRingPosY,
setMiddleRingRotX,
setMiddleRingRotZ,
setMiddleRingRotating,

View file

@ -0,0 +1,48 @@
import React, { useEffect, useMemo } from "react";
import { useSiteStore } from "../../store";
const SiteStateManager = (props: any) => {
const incrementSiteRotY = useSiteStore((state) => state.incrementSiteRotY);
const incrementSitePosY = useSiteStore((state) => state.incrementSitePosY);
const setIsSiteYChanging = useSiteStore((state) => state.setIsSiteChanging);
const dispatcherObjects = useMemo(
() => ({
moveUp: { action: incrementSitePosY, value: -1.5, actionDelay: 1300 },
moveDown: { action: incrementSitePosY, value: 1.5, actionDelay: 1300 },
moveLeft: {
action: incrementSiteRotY,
value: Math.PI / 4,
actionDelay: 1100,
},
moveRight: {
action: incrementSiteRotY,
value: -Math.PI / 4,
actionDelay: 1100,
},
}),
[incrementSitePosY, incrementSiteRotY]
);
useEffect(() => {
if (props.eventState) {
const dispatchedAction =
dispatcherObjects[props.eventState as keyof typeof dispatcherObjects];
if (dispatchedAction) {
setIsSiteYChanging(true);
setTimeout(() => {
dispatchedAction.action(dispatchedAction.value);
}, dispatchedAction.actionDelay);
setTimeout(() => {
setIsSiteYChanging(false);
}, 3000);
}
}
}, [dispatcherObjects, props.eventState, setIsSiteYChanging]);
return null;
};
export default SiteStateManager;

View file

@ -1,14 +1,12 @@
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import orangeFont from "../../static/sprites/orange_font_texture.png";
import greenFont from "../../static/sprites/white_and_green_texture.png";
import yellowFont from "../../static/sprites/yellow_font_texture.png";
import orange_font_json from "../../resources/orange_font.json";
import medium_font_json from "../../resources/medium_font.json";
import orangeFont from "../static/sprites/orange_font_texture.png";
import greenFont from "../static/sprites/white_and_green_texture.png";
import yellowFont from "../static/sprites/yellow_font_texture.png";
import orange_font_json from "../resources/orange_font.json";
import medium_font_json from "../resources/medium_font.json";
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 = {

View file

@ -1,6 +0,0 @@
import { atom } from "recoil";
export const bigLetterOffsetXCoeffAtom = atom({
key: "bigLetterOFfsetXCoeffAtom",
default: 0,
});

View file

@ -1,18 +1,16 @@
import React, { memo, useRef, useState } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import orbSprite from "../../static/sprites/orb.png";
import orbSprite from "../static/sprites/orb.png";
import { useYellowOrbStore } from "../store";
// initialize outside the component otherwise it gets overwritten when it rerenders
let orbIdx = 0;
let orbDirectionChangeCount = 0;
let renderOrder = -1;
type OrbProps = {
orbVisibility: boolean;
};
const Orb = memo((props: OrbProps) => {
const YellowOrb = memo(() => {
const yellowOrbVisible = useYellowOrbStore((state) => state.yellowOrbVisible);
const orbRef = useRef<THREE.Object3D>();
const [orbDirection, setOrbDirection] = useState("left");
const [currentCurve, setCurrentCurve] = useState("first");
@ -34,7 +32,7 @@ const Orb = memo((props: OrbProps) => {
);
useFrame(() => {
if (props.orbVisibility) {
if (yellowOrbVisible) {
let orbPosFirst = firstCurve.getPoint(orbIdx / 250);
let orbPosSecond = secondCurve.getPoint(orbIdx / 250);
@ -110,7 +108,7 @@ const Orb = memo((props: OrbProps) => {
});
return (
<group position={[0, -0.1, -9]} visible={props.orbVisibility}>
<group position={[0, -0.1, -9]} visible={yellowOrbVisible}>
<sprite scale={[0.5, 0.5, 0.5]} ref={orbRef} renderOrder={renderOrder}>
<spriteMaterial
attach="material"
@ -123,4 +121,4 @@ const Orb = memo((props: OrbProps) => {
);
});
export default Orb;
export default YellowOrb;

View file

@ -1,39 +0,0 @@
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<HUDState>((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 })),
}));

173
src/store.ts Normal file
View file

@ -0,0 +1,173 @@
import create from "zustand";
type BlueOrbState = {
blueOrbId: string;
hudId: string;
hudActive: number;
hudVisible: boolean;
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;
};
type LainState = {
lainMoveState: string;
setLainMoveState: (to: string) => void;
};
type MainGroupState = {
mainGroupPosY: number;
mainGroupPosZ: number;
mainGroupRotX: number;
setMainGroupPosY: (to: number) => void;
setMainGroupPosZ: (to: number) => void;
setMainGroupRotX: (to: number) => void;
};
type GrayPlanesState = {
grayPlanesVisible: boolean;
setGrayPlanesVisible: (to: boolean) => void;
};
type StarfieldState = {
introStarfieldVisible: boolean;
mainStarfieldVisible: boolean;
mainStarfieldBoostVal: number;
setIntroStarfieldVisible: (to: boolean) => void;
setMainStarfieldVisible: (to: boolean) => void;
setMainStarfieldBoostVal: (to: number) => void;
};
type YellowOrbState = {
yellowOrbVisible: boolean;
setYellowOrbVisible: (to: boolean) => void;
};
type SiteState = {
siteRotY: number;
sitePosY: number;
isSiteChangingY: boolean;
incrementSiteRotY: (by: number) => void;
incrementSitePosY: (by: number) => void;
setSiteRotY: (to: number) => void;
setSitePosY: (to: number) => void;
setIsSiteChanging: (to: boolean) => void;
};
type MiddleRingState = {
middleRingWobbleStrength: number;
middleRingRotating: boolean;
middleRingNoise: number;
middleRingPosY: number;
middleRingRotX: number;
middleRingRotZ: number;
middleRingAnimDuration: number;
setMiddleRingWobbleStrength: (to: number) => void;
setMiddleRingRotating: (to: boolean) => void;
setMiddleRingNoise: (to: number) => void;
addToMiddleRingPosY: (val: number) => void;
setMiddleRingPosY: (to: number) => void;
setMiddleRingRotX: (to: number) => void;
setMiddleRingRotZ: (to: number) => void;
setMiddleRingAnimDuration: (to: number) => void;
};
export const useBlueOrbStore = create<BlueOrbState>((set) => ({
blueOrbId: "0422",
hudId: "fg_hud_1",
hudActive: 1,
hudVisible: true,
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(() => ({ yellowHudTextPosX: to })),
setYellowHudTextOffsetXCoeff: (to) =>
set(() => ({ yellowHudTextOffsetXCoeff: to })),
}));
export const useLainStore = create<LainState>((set) => ({
lainMoveState: "standing",
setLainMoveState: (to) => set(() => ({ lainMoveState: to })),
}));
// -2.5 - intro val
//-9.5 - intro val
//1.5 - intro val
export const useMainGroupStore = create<MainGroupState>((set) => ({
mainGroupPosY: 0,
mainGroupPosZ: 0,
mainGroupRotX: 0,
setMainGroupPosY: (to) => set(() => ({ mainGroupPosY: to })),
setMainGroupPosZ: (to) => set(() => ({ mainGroupPosZ: to })),
setMainGroupRotX: (to) => set(() => ({ mainGroupRotX: to })),
}));
export const useGrayPlanesStore = create<GrayPlanesState>((set) => ({
grayPlanesVisible: true,
setGrayPlanesVisible: (to) => set(() => ({ grayPlanesVisible: to })),
}));
export const useStarfieldStore = create<StarfieldState>((set) => ({
introStarfieldVisible: false,
mainStarfieldVisible: true,
mainStarfieldBoostVal: 0.2,
setIntroStarfieldVisible: (to) => set(() => ({ introStarfieldVisible: to })),
setMainStarfieldVisible: (to) => set(() => ({ mainStarfieldVisible: to })),
setMainStarfieldBoostVal: (to) => set(() => ({ mainStarfieldBoostVal: to })),
}));
export const useYellowOrbStore = create<YellowOrbState>((set) => ({
yellowOrbVisible: false,
setYellowOrbVisible: (to) => set(() => ({ yellowOrbVisible: to })),
}));
export const useSiteStore = create<SiteState>((set) => ({
sitePosY: 0,
siteRotY: 0,
isSiteChangingY: false,
incrementSitePosY: (by) =>
set((state) => ({ sitePosY: state.sitePosY + by })),
incrementSiteRotY: (by) =>
set((state) => ({ siteRotY: state.siteRotY + by })),
setSitePosY: (to) => set(() => ({ sitePosY: to })),
setSiteRotY: (to) => set(() => ({ siteRotY: to })),
setIsSiteChanging: (to) => set(() => ({ isSiteChangingY: to })),
}));
export const useMiddleRingStore = create<MiddleRingState>((set) => ({
middleRingWobbleStrength: 0,
middleRingRotating: true,
middleRingNoise: 0.03,
middleRingPosY: -0.11,
middleRingRotX: 0,
middleRingRotZ: 0,
middleRingAnimDuration: 600,
setMiddleRingWobbleStrength: (to) =>
set(() => ({ middleRingWobbleStrength: to })),
setMiddleRingRotating: (to) => set(() => ({ middleRingRotating: to })),
setMiddleRingNoise: (to) => set(() => ({ middleRingNoise: to })),
addToMiddleRingPosY: (by) =>
set((state) => ({ middleRingPosY: state.middleRingPosY + by })),
setMiddleRingPosY: (to) => set(() => ({ middleRingPosY: to })),
setMiddleRingRotX: (to) => set(() => ({ middleRingRotX: to })),
setMiddleRingRotZ: (to) => set(() => ({ middleRingRotZ: to })),
setMiddleRingAnimDuration: (to) =>
set(() => ({ middleRingAnimDuration: to })),
}));