cleaning stuff up

This commit is contained in:
ad044 2021-01-15 22:01:59 +04:00
parent 908479f21a
commit 40545c74a5
29 changed files with 519 additions and 362 deletions

View file

@ -40,7 +40,6 @@ const App = () => {
<div id="game-root" className="game">
<span className="canvas">
<Canvas concurrent>
<EventManager />
<Suspense fallback={null}>
{dispatchScene[currentScene as keyof typeof dispatchScene]}
</Suspense>

View file

@ -4,6 +4,7 @@ import PauseSquare from "./PauseSquare";
import StaticBigLetter from "../../TextRenderer/StaticBigLetter";
import { usePauseStore } from "../../../store";
import { useLoader } from "react-three-fiber";
import MainSceneEventManager from "../../../core/StateManagers/MainSceneEventManager";
const Pause = (props: { visible: boolean }) => {
const exit = usePauseStore((state) => state.exitAnimation);
@ -341,6 +342,7 @@ const Pause = (props: { visible: boolean }) => {
depthTest={false}
/>
</mesh>
<MainSceneEventManager loaded={!exit} />
</group>
</group>
) : (

View file

@ -1,12 +1,12 @@
import React, { useEffect, useMemo, useState } from "react";
import HUD from "./SyncedComponents/HUD";
import GreenTextRenderer from "../TextRenderer/GreenTextRenderer";
import YellowTextRenderer from "../TextRenderer/YellowTextRenderer";
import YellowOrb from "./SyncedComponents/YellowOrb";
import GrayPlanes from "./SyncedComponents/GrayPlanes";
import Starfield from "./SyncedComponents/Starfield";
import Site from "./SyncedComponents/Site";
import MiddleRing from "./SyncedComponents/MiddleRing";
import MainSceneEventManager from "../../core/StateManagers/MainSceneEventManager";
type SyncedComponentLoaderProps = {
paused: boolean;
@ -40,7 +40,6 @@ const SyncedComponentLoader = (props: SyncedComponentLoaderProps) => {
<>
<group visible={visible}>
<HUD />
<GreenTextRenderer />
<YellowTextRenderer />
<YellowOrb visible={visible} />
<MiddleRing />
@ -51,6 +50,7 @@ const SyncedComponentLoader = (props: SyncedComponentLoaderProps) => {
introFinished={introFinished}
/>
<Site shouldIntro={props.shouldIntro} introFinished={introFinished} />
<MainSceneEventManager loaded={visible} />
</>
);
};

View file

@ -1,54 +1,33 @@
import React, { createRef, memo, RefObject, useRef } from "react";
import React, { useMemo, useRef } from "react";
import * as THREE from "three";
import { useFrame } from "react-three-fiber";
import GrayPlane from "./GrayPlanes/GrayPlane";
const GrayPlanes = () => {
const grayPlaneGroupRef = useRef<THREE.Object3D>();
const grayPlanePoses = [
[1.2, 0, -1.2],
[1.2, 0, 1.2],
[1.2, 0, -0.5],
[-1.2, 0, -1.2],
[-1.2, 0, 1.2],
[-1.2, 0, 1],
[0.5, 0, 1],
];
const grayPlaneRefs = grayPlanePoses.map((poses: number[]) =>
// eslint-disable-next-line react-hooks/rules-of-hooks
useRef<RefObject<THREE.Object3D>[]>(
poses.map(() => createRef<THREE.Object3D>())
)
const grayPlanePoses = useMemo(
() => [
[1.2, 0, -1.2],
[1.2, 0, 1.2],
[1.2, 0, -0.5],
[-1.2, 0, -1.2],
[-1.2, 0, 1.2],
[-1.2, 0, 1],
[0.5, 0, 1],
],
[]
);
useFrame(() => {
grayPlaneGroupRef.current!.rotation.y -= 0.01;
grayPlaneRefs.forEach((ref: any) => (ref.current!.rotation.y += 0.03));
});
return (
// separate wrapper group to make it rotate around [0,0,0]
<group position={[0.1, 0, -2]} ref={grayPlaneGroupRef}>
{grayPlaneRefs.map((ref, idx: number) => {
return (
<mesh
scale={[0.04, 10, 0.04]}
position={grayPlanePoses[idx] as [number, number, number]}
ref={ref}
key={idx}
>
<planeBufferGeometry attach="geometry" />
<meshBasicMaterial
attach="material"
color={0xd3d3d3}
opacity={0.2}
transparent={true}
side={THREE.DoubleSide}
/>
</mesh>
);
})}
{grayPlanePoses.map((pos, idx: number) => (
<GrayPlane position={pos as [number, number, number]} key={idx} />
))}
</group>
);
};

View file

@ -0,0 +1,35 @@
import React, { useRef } from "react";
import * as THREE from "three";
import { useFrame } from "react-three-fiber";
type GrayPlaneProps = {
position: [number, number, number];
};
const GrayPlane = (props: GrayPlaneProps) => {
const meshRef = useRef<THREE.Object3D>();
useFrame(() => {
if (meshRef.current) {
meshRef.current.rotation.y += 0.03;
}
});
return (
<mesh
scale={[0.04, 10, 0.04]}
position={props.position as [number, number, number]}
>
<planeBufferGeometry attach="geometry" />
<meshBasicMaterial
attach="material"
color={0xd3d3d3}
opacity={0.2}
transparent={true}
side={THREE.DoubleSide}
/>
</mesh>
);
};
export default GrayPlane;

View file

@ -1,4 +1,4 @@
import React, { memo } from "react";
import React, { useMemo } from "react";
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import bigHud from "../../../static/sprite/big_hud.png";
@ -8,19 +8,39 @@ import longHudMirrored from "../../../static/sprite/long_hud_mirrored.png";
import boringHud from "../../../static/sprite/long_hud_boring.png";
import boringHudMirrored from "../../../static/sprite/long_hud_boring_mirrored.png";
import { a, useSpring } from "@react-spring/three";
import { useHudStore } from "../../../store";
import { useHudStore, useNodeStore, useSiteStore } from "../../../store";
import node_huds from "../../../resources/node_huds.json";
import MediumLetter from "../../TextRenderer/MediumLetter";
import site_a from "../../../resources/site_a.json";
import site_b from "../../../resources/site_b.json";
import { SiteType } from "./Site";
const HUD = () => {
const activeNodeId = useNodeStore((state) => state.activeNodeState.id);
const currentSite = useSiteStore((state) => state.currentSite);
const greenText = useMemo(() => {
if (activeNodeId === "UNKNOWN") return "".split("");
else {
const siteData = currentSite === "a" ? site_a : site_b;
const level = activeNodeId.substr(0, 2);
return (siteData as SiteType)[level][activeNodeId].title.split("");
}
}, [activeNodeId, currentSite]);
const active = useHudStore((state) => state.active);
const id = useHudStore((state) => state.id);
const currentHud = node_huds[id as keyof typeof node_huds];
const currentHud = useMemo(() => node_huds[id as keyof typeof node_huds], [
id,
]);
const hudElementState = useSpring({
bigHUDPositionX: active,
longHUDPositionX: active,
boringHUDPositionX: active,
greenTextPositionX: active,
config: { duration: 400 },
});
@ -39,9 +59,14 @@ const HUD = () => {
[currentHud.long.initial_position[0], currentHud.long.position[0]]
);
// these hud elements come in all shapes and forms, some of them are mirrored, rotated
// you name it. this function allows me to specify whether i want a normal texture
// for the blue orb or the mirrored/rotated one.
const greenTextPosX = hudElementState.greenTextPositionX.to(
[0, 1],
[
currentHud.medium_text.initial_position[0],
currentHud.medium_text.position[0],
]
);
const spriteTypeToSprite = (spriteType: string, hudElement: string) => {
switch (spriteType) {
case "normal":
@ -85,8 +110,8 @@ const HUD = () => {
<group position={[0, 0, 10]}>
<a.sprite
position-x={longHUDPosX}
position-y={currentHud!.long.position[1]}
position-z={currentHud!.long.position[2]}
position-y={currentHud.long.position[1]}
position-z={currentHud.long.position[2]}
scale={[1, 0.03, 1]}
renderOrder={2}
>
@ -99,8 +124,8 @@ const HUD = () => {
</a.sprite>
<a.sprite
position-x={boringHUDPosX}
position-y={currentHud!.boring.position[1]}
position-z={currentHud!.boring.position[2]}
position-y={currentHud.boring.position[1]}
position-z={currentHud.boring.position[2]}
scale={[1, 0.03, 1]}
renderOrder={2}
>
@ -113,8 +138,8 @@ const HUD = () => {
</a.sprite>
<a.sprite
position-x={bigHUDPosX}
position-y={currentHud!.big.position[1]}
position-z={currentHud!.big.position[2]}
position-y={currentHud.big.position[1]}
position-z={currentHud.big.position[2]}
scale={[0.5, 0.06, 1]}
renderOrder={2}
>
@ -125,6 +150,16 @@ const HUD = () => {
depthTest={false}
/>
</a.sprite>
<a.group
position-x={greenTextPosX}
position-y={currentHud.medium_text.position[1]}
position-z={-8.7}
scale={[0.02, 0.035, 0.02]}
>
{greenText.map((letter, idx) => (
<MediumLetter letter={letter} letterIdx={idx} key={idx} />
))}
</a.group>
</group>
);
};

View file

@ -1,4 +1,4 @@
import React, { useEffect, useMemo, useRef } from "react";
import React, { useMemo, useRef } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import middleRingTexture from "../../../static/sprite/middle_ring_tex.png";
import * as THREE from "three";
@ -14,8 +14,6 @@ const MiddleRing = () => {
const animDuration = useMiddleRingStore((state) => state.animDuration);
const mainRingVisible = useMiddleRingStore((state) => state.mainRingVisible);
const partSeparatorVal = useMiddleRingStore(state=> state.partSeparatorVal)
const wobbleState = useSpring({
wobbleStrength: transformState.wobbleStrength,
noiseStrength: transformState.noiseStrength,
@ -198,8 +196,10 @@ const MiddleRing = () => {
middleRingMaterialRef.current.needsUpdate = true;
}
if (rotating && middleRingRef && middleRingPartRef) {
if (rotating && middleRingRef.current) {
middleRingRef.current!.rotation.y += 0.05;
}
if (rotating && middleRingPartRef.current) {
middleRingPartRef.current!.rotation.y += 0.05;
}
});
@ -229,23 +229,26 @@ const MiddleRing = () => {
/>
</a.mesh>
<group
rotation={[0, 0.9, 0]}
ref={middleRingPartRef}
position={[0, 0.5, 0.3]}
visible={!mainRingVisible}
>
{[...Array(30).keys()].map((i) => {
const angle = (i / 30) * 2 * Math.PI;
return (
<MiddleRingPart
position={[Math.cos(angle) / 1.35, 0, Math.sin(angle) / 1.35]}
rotation={[0, -angle + Math.PI / 2, 0]}
key={angle}
/>
);
})}
</group>
{!mainRingVisible ? (
<group
rotation={[0, 0.9, 0]}
ref={middleRingPartRef}
position={[0, 0.5, 0.3]}
>
{[...Array(30).keys()].map((i) => {
const angle = (i / 30) * 2 * Math.PI;
return (
<MiddleRingPart
position={[Math.cos(angle) / 1.35, 0, Math.sin(angle) / 1.35]}
rotation={[0, -angle + Math.PI / 2, 0]}
key={angle}
/>
);
})}
</group>
) : (
<></>
)}
</a.group>
);
};

View file

@ -5,13 +5,13 @@ import * as THREE from "three";
import { useLoader } from "react-three-fiber";
import orange_font_json from "../../resources/font_data/big_font.json";
import { a, useSpring } from "@react-spring/three";
import React, { useMemo } from "react";
import React, { useEffect, useMemo } from "react";
import { useBigTextStore } from "../../store";
const BigLetter = (props: {
color: string;
letter: string;
letterIdx: number;
xOffsetCoeff: number;
}) => {
const colorToTexture = (color: string) => {
const colorTexture = {
@ -89,17 +89,23 @@ const BigLetter = (props: {
return geometry;
}, [letterData, lineYOffsets, props.letter]);
const textRendererState = useSpring({
letterOffsetXCoeff:
props.letterIdx +
0.3 +
(props.letterIdx + 0.3) * props.xOffsetCoeff,
const [{ letterOffsetX }, set] = useSpring(() => ({
letterOffsetX: props.letterIdx + 0.3 + (props.letterIdx + 0.3),
config: { duration: 200 },
});
}));
useEffect(() => {
useBigTextStore.subscribe(set, (state) => ({
letterOffsetX:
props.letterIdx +
0.3 +
(props.letterIdx + 0.3) * state.transformState.xOffset,
}));
}, [props.letterIdx, set]);
return (
<a.mesh
position-x={textRendererState.letterOffsetXCoeff}
position-x={letterOffsetX}
position-y={-letterData[4] / 12.5}
scale={[1, 1, 0]}
geometry={geom}

View file

@ -1,52 +0,0 @@
import { a, useSpring } from "@react-spring/three";
import React, { useEffect, useRef } from "react";
import { GreenTextState, useGreenTextStore } from "../../store";
import MediumLetter from "./MediumLetter";
const GreenTextRenderer = () => {
const greenTextActive = useGreenTextStore((state) => state.active);
const transformRef = useRef(useGreenTextStore.getState().transformState);
const textArrRef = useRef(useGreenTextStore.getState().text.split(""));
const { greenTextPosXToggle } = useSpring({
greenTextPosXToggle: greenTextActive,
config: { duration: 400 },
});
const greenTextPosX = greenTextPosXToggle.to(
[0, 1],
[transformRef.current.posX.initial, transformRef.current.posX.final]
);
// subscribing to state and updating transiently
useEffect(
() =>
useGreenTextStore.subscribe(
(state) => {
transformRef.current = (state as GreenTextState).transformState;
textArrRef.current = (state as GreenTextState).text.split("");
},
(state) => state
),
[]
);
return (
<group position={[0, 0, 10]}>
<a.group
position-x={greenTextPosX}
position-y={transformRef.current.posY}
position-z={-8.7}
scale={[0.02, 0.035, 0.02]}
>
{textArrRef.current.map((letter, idx) => (
<MediumLetter letter={letter} letterIdx={idx} key={idx} />
))}
</a.group>
</group>
);
};
export default GreenTextRenderer;

View file

@ -1,17 +1,24 @@
import React from "react";
import React, { useEffect, useRef } from "react";
import { useMediaBigTextStore } from "../../store";
import { a, useTrail } from "@react-spring/three";
import BigLetter from "./BigLetter";
const MediaYellowTextAnimator = () => {
const transformState = useMediaBigTextStore((state) => state.transformState);
const textArr = useMediaBigTextStore((state) => state.text).split("");
const textArrRef = useRef(useMediaBigTextStore.getState().text.split(""));
const trail = useTrail(textArr.length, {
posX: transformState.posX,
posY: transformState.posY,
config: { duration: 280 },
});
const [trail, set] = useTrail(textArrRef.current.length, () => ({
posX: 0,
posY: 0,
xOffset: 0,
config: { duration: 200 },
}));
useEffect(() => {
useMediaBigTextStore.subscribe(set, (state) => ({
posX: state.transformState.posX,
posY: state.transformState.posY,
}));
}, [set]);
return (
<group position={[0, 0, 10]}>
@ -25,8 +32,7 @@ const MediaYellowTextAnimator = () => {
>
<BigLetter
color={"yellow"}
xOffsetCoeff={transformState.xOffset}
letter={textArr[idx]}
letter={textArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>

View file

@ -1,82 +1,45 @@
import React, { useEffect, useRef } from "react";
import { BigTextState, useBigTextStore } from "../../store";
import { BigTextState, useBigTextStore, useNodeStore } from "../../store";
import { a, useSpring, useTrail } from "@react-spring/three";
import BigLetter from "./BigLetter";
const YellowTextRenderer = () => {
const disableTrail = useBigTextStore((state) => state.disableTrail);
const transformState = useBigTextStore((state) => state.transformState);
const visible = useBigTextStore((state) => state.visible);
const color = useBigTextStore((state) => state.color);
const textArrRef = useRef(useBigTextStore.getState().text.split(""));
const transformRef = useRef(useBigTextStore.getState().transformState);
// this is used to animate the letters moving one after another
const trail = useTrail(textArrRef.current.length, {
posX: transformRef.current.posX,
posY: transformRef.current.posY,
const [trail, set] = useTrail(textArrRef.current.length, () => ({
posX: 0,
posY: 0,
config: { duration: 280 },
});
}));
// this is used when the whole GROUP itself needs to be animated
const spring = useSpring({
posX: transformState.posX,
posY: transformState.posY,
config: { duration: 1200 },
});
useEffect(
() =>
useBigTextStore.subscribe(
(state) => {
transformRef.current = (state as BigTextState).transformState;
textArrRef.current = (state as BigTextState).text.split("");
},
(state) => state
),
[]
);
useEffect(() => {
useBigTextStore.subscribe(set, (state) => ({
posX: state.transformState.posX,
posY: state.transformState.posY,
}));
}, [set]);
return (
<group position={[0, 0, 10]} visible={visible}>
{disableTrail
? textArrRef.current.map((letter, idx) => (
<a.group
key={idx}
position-x={spring.posX}
position-y={spring.posY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={color}
xOffsetCoeff={0}
letter={textArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))
: trail.map(({ posX, posY }, idx) => (
<a.group
key={idx}
position-x={posX}
position-y={posY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={color}
xOffsetCoeff={transformRef.current.xOffset}
letter={textArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))}
{trail.map(({ posX, posY }, idx) => (
<a.group
key={idx}
position-x={posX}
position-y={posY}
position-z={-8.7}
scale={[0.04, 0.06, 0.04]}
>
<BigLetter
color={color}
letter={textArrRef.current[idx]}
letterIdx={idx}
key={idx}
/>
</a.group>
))}
</group>
);
};

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "./EventManager";
import { useAuthorizeUserStore, useBootStore } from "../../store";
import { StateManagerProps } from "../EventManager";
import { useAuthorizeUserStore, useBootStore } from "../../../store";
const BootAuthorizeUserManager = (props: StateManagerProps) => {
const setActiveLetterTextureOffset = useAuthorizeUserStore(

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "./EventManager";
import { useBootStore } from "../../store";
import { StateManagerProps } from "../EventManager";
import { useBootStore } from "../../../store";
const BootComponentManager = (props: StateManagerProps) => {
const toggleComponentMatrixIdx = useBootStore(

View file

@ -18,24 +18,23 @@ import {
useSiteStore,
useSSknStore,
} from "../../store";
import GreenTextManager from "./MainSceneManagers/GreenTextManager";
import MediaComponentManager from "./MediaSceneManagers/MediaComponentManager";
import SceneManager from "./SceneManager";
import SceneManager from "./GameManagers/SceneManager";
import YellowTextManager from "./MainSceneManagers/YellowTextManager";
import LevelManager from "./MainSceneManagers/LevelManager";
import BootComponentManager from "./BootComponentManager";
import SSknComponentManager from "./SSknComponentManager";
import BootComponentManager from "./BootSceneManagers/BootComponentManager";
import SSknComponentManager from "./SSknSceneManagers/SSknComponentManager";
import handleMainSceneEvent from "../mainSceneEventHandler";
import handleMediaSceneEvent from "../mediaSceneEventHandler";
import handleBootEvent from "../bootEventHandler";
import handleSSknSceneEvent from "../ssknSceneEventHandler";
import BootAuthorizeUserManager from "./BootAuthorizeUserManager";
import BootAuthorizeUserManager from "./BootSceneManagers/BootAuthorizeUserManager";
import LevelSelectionManager from "./MainSceneManagers/LevelSelectionManager";
import SubsceneManager from "./SubsceneManager";
import SubsceneManager from "./GameManagers/SubsceneManager";
import PauseComponentManager from "./MainSceneManagers/PauseComponentManager";
import MediaYellowTextManager from "./MediaYellowTextManager";
import GameSaver from "./GameSaver";
import GameLoader from "./GameLoader";
import MediaYellowTextManager from "./MediaSceneManagers/MediaYellowTextManager";
import GameSaver from "./GameManagers/GameSaver";
import GameLoader from "./GameManagers/GameLoader";
import { useFrame } from "react-three-fiber";
import IdleManager from "./MainSceneManagers/IdleManager";
@ -279,7 +278,6 @@ const EventManager = () => {
<>
<NodeManager eventState={eventState!} />
<NodeHUDManager eventState={eventState!} />
<GreenTextManager eventState={eventState!} />
<SiteManager eventState={eventState!} />
<LainManager eventState={eventState!} />
<MiddleRingManager eventState={eventState!} />

View file

@ -7,12 +7,12 @@ import {
useNodeStore,
useSiteSaveStore,
useSiteStore,
} from "../../store";
import { StateManagerProps } from "./EventManager";
import node_huds from "./../../resources/node_huds.json";
import site_a from "./../../resources/site_a.json";
import site_b from "./../../resources/site_b.json";
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
} from "../../../store";
import { StateManagerProps } from "../EventManager";
import node_huds from "../../../resources/node_huds.json";
import site_a from "../../../resources/site_a.json";
import site_b from "../../../resources/site_b.json";
import { SiteType } from "../../../components/MainScene/SyncedComponents/Site";
const GameLoader = (props: StateManagerProps) => {
const siteASaveState = useSiteSaveStore((state) => state.a);

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { useSiteSaveStore } from "../../store";
import { StateManagerProps } from "./EventManager";
import { useSiteSaveStore } from "../../../store";
import { StateManagerProps } from "../EventManager";
const GameSaver = (props: StateManagerProps) => {
const setSiteSaveState = useSiteSaveStore((state) => state.setSiteSaveState);

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "./EventManager";
import { useMainSceneStore, useSceneStore } from "../../store";
import { StateManagerProps } from "../EventManager";
import { useMainSceneStore, useSceneStore } from "../../../store";
const SceneManager = (props: StateManagerProps) => {
const setScene = useSceneStore((state) => state.setScene);

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "./EventManager";
import { useBootStore, useMainSceneStore } from "../../store";
import { StateManagerProps } from "../EventManager";
import { useBootStore, useMainSceneStore } from "../../../store";
const SubsceneManager = (props: StateManagerProps) => {
const setMainSubscene = useMainSceneStore((state) => state.setSubscene);

View file

@ -0,0 +1,42 @@
import React, { useCallback, useEffect, useState } from "react";
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
import SceneManager from "./GameManagers/SceneManager";
const GateSceneManager = () => {
const [eventState, setEventState] = useState<any>();
const [loaded, setLoaded] = useState(false);
useEffect(() => {
setTimeout(() => {
setLoaded(true);
return () => {
setLoaded(false);
};
}, 3500);
}, []);
const handleKeyPress = useCallback((event) => {
const { keyCode } = event;
const keyPress = getKeyCodeAssociation(keyCode);
if (keyPress && loaded) {
const event = { event: "exit_gate" };
setEventState(event);
}
}, [loaded]);
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleKeyPress]);
return <SceneManager eventState={eventState!} />;
};
export default GateSceneManager;

View file

@ -0,0 +1,119 @@
import React, { useCallback, useEffect, useRef, useState } from "react";
import {
useLevelSelectionStore,
useLevelStore,
useMainSceneStore,
useNodeStore,
usePauseStore,
useSiteStore,
} from "../../store";
import handleMainSceneEvent from "../mainSceneEventHandler";
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
import NodeManager from "./MainSceneManagers/NodeManager";
import NodeHUDManager from "./MainSceneManagers/NodeHUDManager";
import SiteManager from "./MainSceneManagers/SiteManager";
import LainManager from "./MainSceneManagers/LainManager";
import MiddleRingManager from "./MainSceneManagers/MiddleRingManager";
import SceneManager from "./GameManagers/SceneManager";
import YellowTextManager from "./MainSceneManagers/YellowTextManager";
import LevelManager from "./MainSceneManagers/LevelManager";
import LevelSelectionManager from "./MainSceneManagers/LevelSelectionManager";
import SubsceneManager from "./GameManagers/SubsceneManager";
import PauseComponentManager from "./MainSceneManagers/PauseComponentManager";
import GameSaver from "./GameManagers/GameSaver";
import GameLoader from "./GameManagers/GameLoader";
import IdleManager from "./MainSceneManagers/IdleManager";
type MainSceneEventManagerProps = {
loaded: boolean;
};
const MainSceneEventManager = (props: MainSceneEventManagerProps) => {
// all the possible context needed to calculate new state
const currentSite = useSiteStore((state) => state.currentSite);
const activeNodeId = useNodeStore((state) => state.activeNodeState.id);
const nodeMatrixIndices = useNodeStore((state) => state.nodeMatrixIndices);
const siteTransformState = useSiteStore((state) => state.transformState);
const activeLevel = useLevelStore((state) => state.activeLevel);
const mainSubscene = useMainSceneStore((state) => state.subscene);
const selectedLevel = useLevelSelectionStore((state) => state.selectedLevel);
const pauseMatrixIdx = usePauseStore((state) => state.componentMatrixIdx);
const activePauseComponent = usePauseStore(
useCallback((state) => state.componentMatrix[pauseMatrixIdx], [
pauseMatrixIdx,
])
);
const gameProgress = useNodeStore((state) => state.gameProgress);
const timePassedSinceLastKeyPress = useRef(-1);
const [eventState, setEventState] = useState<any>();
const handleKeyPress = useCallback(
(event) => {
const { keyCode } = event;
const keyPress = getKeyCodeAssociation(keyCode);
if (keyPress && props.loaded) {
timePassedSinceLastKeyPress.current = Date.now() + 2500;
const event = handleMainSceneEvent({
mainSubscene: mainSubscene,
keyPress: keyPress,
siteTransformState: siteTransformState,
activeNodeId: activeNodeId,
nodeMatrixIndices: nodeMatrixIndices,
activeLevel: activeLevel,
selectedLevel: selectedLevel,
pauseMatrixIdx: pauseMatrixIdx,
activePauseComponent: activePauseComponent,
gameProgress: gameProgress,
currentSite: currentSite,
});
setEventState(event);
}
},
[
props.loaded,
mainSubscene,
siteTransformState,
activeNodeId,
nodeMatrixIndices,
activeLevel,
selectedLevel,
pauseMatrixIdx,
activePauseComponent,
gameProgress,
currentSite,
]
);
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleKeyPress]);
return (
<>
<NodeManager eventState={eventState!} />
<NodeHUDManager eventState={eventState!} />
<SiteManager eventState={eventState!} />
<LainManager eventState={eventState!} />
<MiddleRingManager eventState={eventState!} />
<SceneManager eventState={eventState!} />
<YellowTextManager eventState={eventState!} />
<LevelManager eventState={eventState!} />
<LevelSelectionManager eventState={eventState!} />
<SubsceneManager eventState={eventState!} />
<PauseComponentManager eventState={eventState!} />
<GameSaver eventState={eventState!} />
<GameLoader eventState={eventState!} />
<IdleManager eventState={eventState!} />
</>
);
};
export default MainSceneEventManager;

View file

@ -1,124 +0,0 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "../EventManager";
import node_huds from "../../../resources/node_huds.json";
import site_a from "../../../resources/site_a.json";
import { SiteType } from "../../../components/MainScene/SyncedComponents/Site";
import { useGreenTextStore, useSiteStore } from "../../../store";
import site_b from "../../../resources/site_b.json";
const GreenTextManager = (props: StateManagerProps) => {
const setGreenText = useGreenTextStore((state) => state.setText);
const toggleActive = useGreenTextStore((state) => state.toggleActive);
const setTransformState = useGreenTextStore(
(state) => state.setTransformState
);
const currentSite = useSiteStore((state) => state.currentSite);
const siteData = currentSite === "a" ? site_a : site_b;
const toggleAndSetGreenText = useCallback(
(
newActiveNodeId: string,
newActiveHudId: string,
newLevel: string,
delay: number,
shouldToggleAtStart: boolean
) => {
const targetGreenText =
newActiveNodeId === "UNKNOWN"
? ""
: (siteData as SiteType)[newLevel][newActiveNodeId].title;
const targetGreenTextPosData =
node_huds[newActiveHudId as keyof typeof node_huds].medium_text;
if (shouldToggleAtStart) toggleActive();
setTimeout(() => {
setTransformState(
{
initial: targetGreenTextPosData.initial_position[0],
final: targetGreenTextPosData.position[0],
},
"posX"
);
setTransformState(targetGreenTextPosData.position[1], "posY");
setGreenText(targetGreenText);
toggleActive();
}, delay);
},
[setGreenText, setTransformState, siteData, toggleActive]
);
const dispatchObject = useCallback(
(eventState: {
event: string;
activeNodeId: string;
activeHudId: string;
level: string;
}) => {
switch (eventState.event) {
case "site_up":
case "site_down":
case "site_left":
case "site_right":
return {
action: toggleAndSetGreenText,
value: [
eventState.activeNodeId,
eventState.activeHudId,
eventState.level,
3900,
true,
],
};
case "change_node":
return {
action: toggleAndSetGreenText,
value: [
eventState.activeNodeId,
eventState.activeHudId,
eventState.level,
500,
true,
],
};
case "toggle_level_selection":
case "level_selection_back":
return {
action: toggleActive,
};
case "select_level_up":
case "select_level_down":
return {
action: toggleAndSetGreenText,
value: [
eventState.activeNodeId,
eventState.activeHudId,
eventState.level,
3900,
false,
],
};
}
},
[toggleActive, toggleAndSetGreenText]
);
useEffect(() => {
if (props.eventState) {
const dispatchedObject = dispatchObject(props.eventState);
if (dispatchedObject) {
(dispatchedObject.action as any).apply(
null,
dispatchedObject.value as any
);
}
}
}, [props.eventState, dispatchObject]);
return null;
};
export default GreenTextManager;

View file

@ -0,0 +1,71 @@
import React, { useCallback, useEffect, useState } from "react";
import { useMediaStore, useMediaWordStore } from "../../store";
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
import SceneManager from "./GameManagers/SceneManager";
import handleMediaSceneEvent from "../mediaSceneEventHandler";
import MediaComponentManager from "./MediaSceneManagers/MediaComponentManager";
import MediaYellowTextManager from "./MediaSceneManagers/MediaYellowTextManager";
const MediaSceneEventManager = () => {
// all the possible context needed to calculate new state
const mediaComponentMatrixIndices = useMediaStore(
(state) => state.componentMatrixIndices
);
const activeMediaComponent = useMediaStore(
useCallback(
(state) =>
state.componentMatrix[mediaComponentMatrixIndices.sideIdx][
mediaComponentMatrixIndices.sideIdx === 0
? mediaComponentMatrixIndices.leftSideIdx
: mediaComponentMatrixIndices.rightSideIdx
],
[mediaComponentMatrixIndices]
)
);
const rightSideComponentIdx = useMediaStore(
(state) => state.componentMatrixIndices.rightSideIdx
);
const wordPosStateIdx = useMediaWordStore((state) => state.posStateIdx);
const [eventState, setEventState] = useState<any>();
const handleKeyPress = useCallback(
(event) => {
const { keyCode } = event;
const keyPress = getKeyCodeAssociation(keyCode);
if (keyPress) {
const event = handleMediaSceneEvent({
keyPress: keyPress,
activeMediaComponent: activeMediaComponent,
wordPosStateIdx: wordPosStateIdx,
rightSideComponentIdx: rightSideComponentIdx,
});
setEventState(event);
}
},
[activeMediaComponent, rightSideComponentIdx, wordPosStateIdx]
);
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleKeyPress]);
return (
<>
<MediaComponentManager eventState={eventState!} />
<SceneManager eventState={eventState!} />
<MediaYellowTextManager eventState={eventState!} />
</>
);
};
export default MediaSceneEventManager;

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { useMediaBigTextStore } from "../../store";
import { StateManagerProps } from "./EventManager";
import { useMediaBigTextStore } from "../../../store";
import { StateManagerProps } from "../EventManager";
const MediaYellowTextManager = (props: StateManagerProps) => {
const setTransformState = useMediaBigTextStore(

View file

@ -0,0 +1,55 @@
import React, { useCallback, useEffect, useState } from "react";
import { getKeyCodeAssociation } from "../utils/keyPressUtils";
import SceneManager from "./GameManagers/SceneManager";
import handleSSknSceneEvent from "../ssknSceneEventHandler";
import { useSSknStore } from "../../store";
import SSknComponentManager from "./SSknSceneManagers/SSknComponentManager";
const SSknSceneManager = () => {
// all the possible context needed to calculate new state
const ssknComponentMatrixIdx = useSSknStore(
(state) => state.componentMatrixIdx
);
const activeSSknComponent = useSSknStore(
useCallback((state) => state.componentMatrix[ssknComponentMatrixIdx], [
ssknComponentMatrixIdx,
])
);
const [eventState, setEventState] = useState<any>();
const handleKeyPress = useCallback(
(event) => {
const { keyCode } = event;
const keyPress = getKeyCodeAssociation(keyCode);
if (keyPress) {
const event = handleSSknSceneEvent({
keyPress: keyPress,
activeSSknComponent: activeSSknComponent,
});
setEventState(event);
}
},
[activeSSknComponent]
);
useEffect(() => {
window.addEventListener("keydown", handleKeyPress);
return () => {
window.removeEventListener("keydown", handleKeyPress);
};
}, [handleKeyPress]);
return (
<>
<SceneManager eventState={eventState!} />
<SSknComponentManager eventState={eventState!} />
</>
);
};
export default SSknSceneManager;

View file

@ -1,6 +1,6 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "./EventManager";
import { useMediaStore, useSSknStore } from "../../store";
import { StateManagerProps } from "../EventManager";
import { useMediaStore, useSSknStore } from "../../../store";
const SSknComponentManager = (props: StateManagerProps) => {
const toggleComponentMatrixIdx = useSSknStore(

View file

@ -0,0 +1,14 @@
export const getKeyCodeAssociation = (keyCode: number) => {
const keyCodeAssocs = {
40: "DOWN", // down arrow
37: "LEFT", // left arrow
38: "UP", // up arrow
39: "RIGHT", // right arrow
88: "CIRCLE", // x key
90: "X", // z key
68: "TRIANGLE", // d key
69: "L2", // e key
32: "SPACE",
};
return keyCodeAssocs[keyCode as keyof typeof keyCodeAssocs];
};

View file

@ -4,6 +4,7 @@ import { OrbitControls } from "@react-three/drei";
import GateHUD from "../components/GateScene/GateHUD";
import GateMiddleObject from "../components/GateScene/GateMiddleObject";
import { useGateStore } from "../store";
import GateSceneManager from "../core/StateManagers/GateSceneManager";
const GateScene = () => {
const gateLvl = useGateStore((state) => state.gateLvl);
@ -22,6 +23,7 @@ const GateScene = () => {
<GateSide />
<GateHUD intro={introAnim} gateLvl={gateLvl} />
<GateMiddleObject intro={introAnim} gateLvl={gateLvl} />
<GateSceneManager />
</perspectiveCamera>
);
};

View file

@ -19,6 +19,7 @@ import site_a from "../resources/site_a.json";
import { SiteType } from "../components/MainScene/SyncedComponents/Site";
import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator";
import site_b from "../resources/site_b.json";
import MediaSceneEventManager from "../core/StateManagers/MediaSceneEventManager";
const MediaScene = () => {
const currentScene = useSceneStore((state) => state.currentScene);
@ -91,6 +92,7 @@ const MediaScene = () => {
<></>
)}
</group>
<MediaSceneEventManager />
</perspectiveCamera>
);
};

View file

@ -3,6 +3,7 @@ import SSknIcon from "../components/SSknScene/SSknIcon";
import SSknBackground from "../components/SSknScene/SSknBackground";
import SSknHUD from "../components/SSknScene/SSknHUD";
import { useMediaStore, useSSknStore } from "../store";
import SSknSceneManager from "../core/StateManagers/SSknSceneManager";
const SSknScene = () => {
const ssknComponentMatrixIdx = useSSknStore(
@ -21,6 +22,7 @@ const SSknScene = () => {
<SSknBackground />
<SSknIcon />
<SSknHUD activeSSknComponent={activeSSknComponent} loading={loading} />
<SSknSceneManager />
</>
);
};