added loading screen, optimized ring generation code, fixed some eslint errors

This commit is contained in:
ad044 2021-02-15 22:41:20 +04:00
parent 4465fbf8ae
commit 3333bdcfca
30 changed files with 178 additions and 173 deletions

View file

@ -45,7 +45,7 @@ const App = () => {
<Canvas concurrent>
<KeyPressHandler />
<Suspense fallback={null}>
<Preloader />
{/*<Preloader />*/}
{dispatchScene[currentScene as keyof typeof dispatchScene]}
</Suspense>
</Canvas>

View file

@ -1,4 +1,4 @@
import React, { useCallback, useMemo } from "react";
import React, { useMemo } from "react";
import { a, useSpring } from "@react-spring/three";
import authorizeActive from "../../static/sprite/authorize_user_active.png";
import authorizeInactive from "../../static/sprite/authorize_user_inactive.png";
@ -27,11 +27,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
);
const activeMainMenuElement = useStore(
useCallback(
(state) =>
state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx],
[]
)
(state) => state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx]
);
const loadDataActiveTex = useLoader(THREE.TextureLoader, loadDataActive);

View file

@ -62,25 +62,23 @@ const GateMiddleObject = (props: GateMiddleObjectProps) => {
position-z={middleObjectGroupState.posZ}
visible={props.intro}
>
{springs.map((item, idx) => {
if (item.type) {
return item.type.get() === 1 ? (
<BlueOne
posX={item.posX}
posY={item.posY}
key={idx}
visibility={item.visibility}
/>
) : (
<BlueZero
posX={item.posX}
posY={item.posY}
key={idx}
visibility={item.visibility}
/>
);
}
})}
{springs.map((item, idx) =>
item.type.get() === 1 ? (
<BlueOne
posX={item.posX}
posY={item.posY}
key={idx}
visibility={item.visibility}
/>
) : (
<BlueZero
posX={item.posX}
posY={item.posY}
key={idx}
visibility={item.visibility}
/>
)
)}
</a.group>
<Mirror
visible={props.gateLvl === 1 ? !props.intro : props.gateLvl > 0}

View file

@ -3,7 +3,6 @@ import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import gateBlueBinarySingularOne from "../../../static/sprite/blue_binary_singular_one.png";
import { a, SpringValue } from "@react-spring/three";
import sleep from "../../../utils/sleep";
type BlueOneProps = {
posX: SpringValue<number>;

View file

@ -3,7 +3,6 @@ import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import gateBlueBinarySingularZero from "../../../static/sprite/blue_binary_singular_zero.png";
import { a, SpringValue } from "@react-spring/three";
import sleep from "../../../utils/sleep";
type BlueZeroProps = {
posX: SpringValue<number>;

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 * as THREE from "three";
import mirrorTexture from "../../../static/sprite/gate_object_texture.png";

View file

@ -4,7 +4,6 @@ import { a, useSpring } from "@react-spring/three";
import dummy from "../static/sprite/dummy.png";
import * as THREE from "three";
import { useLoader } from "react-three-fiber";
import sleep from "../utils/sleep";
const Images = () => {
const idleNodeImages = useStore((state) => state.idleImages);

View file

@ -36,7 +36,6 @@ import idleManager from "../core/setters/main/idleManager";
import * as audio from "../static/sfx";
import handleEndSceneKeyPress from "../core/scene-keypress-handlers/handleEndSceneKeyPress";
import endManager from "../core/setters/end/endManager";
import sleep from "../utils/sleep";
const KeyPressHandler = () => {
const mediaSceneSetters = useMemo(

View file

@ -0,0 +1,34 @@
import React, { useState } from "react";
import loadingSpritesheet from "../static/sprite/loading_spritesheet.png";
import lifeInstinct from "../static/sprite/life_instinct_function_os.png";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import { PlainAnimator } from "three-plain-animator/lib/plain-animator";
const Loading = () => {
const loadingTex: any = useLoader(THREE.TextureLoader, loadingSpritesheet);
const lifeInstinctTex = useLoader(THREE.TextureLoader, lifeInstinct);
const [animator] = useState(() => {
const anim = new PlainAnimator(loadingTex, 10, 3, 29, 60);
anim.init(0);
return anim;
});
useFrame(() => {
animator.animate();
});
return (
<>
<sprite scale={[0.35, 0.6, 0.35]} position={[0, 0.2, 0]}>
<spriteMaterial attach="material" map={loadingTex} />
</sprite>
<sprite scale={[0.4, 0.6, 0.4]} position={[0, -0.5, 0]}>
<spriteMaterial attach="material" map={lifeInstinctTex} />
</sprite>
</>
);
};
export default Loading;

View file

@ -1,7 +1,7 @@
import React, { Suspense, useEffect, useMemo, useRef, useState } from "react";
import { useFrame, useLoader } from "react-three-fiber";
import React, {Suspense, useEffect, useMemo, useRef, 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 {PlainSingularAnimator} from "three-plain-animator/lib/plain-singular-animator";
import moveDownSpriteSheet from "../../static/sprite/jump_down.png";
import moveUpSpriteSheet from "../../static/sprite/jump_up.png";
import moveLeftSpriteSheet from "../../static/sprite/move_left.png";
@ -32,8 +32,7 @@ import leanRightSpriteSheet from "../../static/sprite/lean_right.png";
import lookAroundSpriteSheet from "../../static/sprite/look_around.png";
import playWithHairSpriteSheet from "../../static/sprite/play_with_hair.png";
import { useStore } from "../../store";
import sleep from "../../utils/sleep";
import {useStore} from "../../store";
type LainConstructorProps = {
sprite: string;

View file

@ -12,7 +12,6 @@ import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import { a, useSpring } from "@react-spring/three";
import usePrevious from "../../hooks/usePrevious";
import sleep from "../../utils/sleep";
const LevelSelection = () => {
const levelSelectionFontTex = useLoader(

View file

@ -1,9 +1,8 @@
import React, { useEffect, useRef } from "react";
import React, { useRef } from "react";
import aboutBg from "../../../static/sprite/about_background.png";
import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three";
import { playAudio, useStore } from "../../../store";
import { sound27, sound6, sound7 } from "../../../static/sfx";
import { useStore } from "../../../store";
const About = () => {
const setShowingAbout = useStore((state) => state.setShowingAbout);

View file

@ -21,14 +21,10 @@ const Pause = () => {
[wordFont]
);
const activeComponent = useStore(
useCallback(
(state) =>
showActiveComponent
? state.pauseComponentMatrix[state.pauseComponentMatrixIdx]
: "",
[showActiveComponent]
)
const activeComponent = useStore((state) =>
showActiveComponent
? state.pauseComponentMatrix[state.pauseComponentMatrixIdx]
: ""
);
const generateSqaureGeom = useCallback((row: number, square: number) => {

View file

@ -9,7 +9,7 @@ import site_a from "../../resources/site_a.json";
import site_b from "../../resources/site_b.json";
import level_y_values from "../../resources/level_y_values.json";
import { filterInvisibleNodes } from "../../utils/node-utils";
import NodeNameContainer from "../MediaScene/NodeNameContainer";
import Loading from "../Loading";
export type NodeDataType = {
id: string;
@ -88,7 +88,7 @@ const Site = (props: SiteProps) => {
);
return (
<Suspense fallback={null}>
<Suspense fallback={<Loading />}>
<a.group rotation-x={rotState.x}>
<a.group rotation-y={rotState.y} position-y={posState.y}>
<ActiveLevelNodes visibleNodes={visibleNodes} />

View file

@ -4,7 +4,6 @@ import node_positions from "../../../resources/node_positions.json";
import { useStore } from "../../../store";
import { NodeDataType, SiteType } from "../Site";
import usePrevious from "../../../hooks/usePrevious";
import sleep from "../../../utils/sleep";
type ActiveLevelNodesProps = {
visibleNodes: SiteType;

View file

@ -5,7 +5,6 @@ import { SiteType } from "../Site";
import InactiveLevelNode from "./InactiveLevelNode";
import usePrevious from "../../../hooks/usePrevious";
import { generateInactiveNodes } from "../../../utils/node-utils";
import sleep from "../../../utils/sleep";
type ActiveLevelNodesProps = {
visibleNodes: SiteType;
@ -26,9 +25,11 @@ const InactiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
) {
const prevLevel = parseInt(prevData?.activeLevel);
const newLevel = parseInt(activeLevel);
// if singular jump
if (prevLevel - 1 === newLevel || prevLevel + 1 === newLevel) {
setVisibleNodes(generateInactiveNodes(props.visibleNodes, activeLevel));
} else {
// if changed from level selection
setTimeout(
() =>
setVisibleNodes(
@ -42,24 +43,22 @@ const InactiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
return (
<>
{Object.entries(visibleNodes).map((node: [string, any]) => {
return (
<InactiveLevelNode
nodeName={node[1].node_name}
position={
node_positions[node[0].substr(2) as keyof typeof node_positions]
.position
}
rotation={
node_positions[node[0].substr(2) as keyof typeof node_positions]
.rotation
}
key={node[1].node_name}
level={node[0].substr(0, 2)}
viewed={Boolean(node[1].is_viewed)}
/>
);
})}
{Object.entries(visibleNodes).map((node: [string, any]) => (
<InactiveLevelNode
nodeName={node[1].node_name}
position={
node_positions[node[0].substr(2) as keyof typeof node_positions]
.position
}
rotation={
node_positions[node[0].substr(2) as keyof typeof node_positions]
.rotation
}
key={node[1].node_name}
level={node[0].substr(0, 2)}
viewed={Boolean(node[1].is_viewed)}
/>
))}
</>
);
});

View file

@ -1,4 +1,4 @@
import React, { useMemo, memo } from "react";
import React, { memo, useMemo } from "react";
import level_y_values from "../../../resources/level_y_values.json";
import PurpleRing from "./PurpleRing";
import GrayRing from "./GrayRing";
@ -11,54 +11,56 @@ type RingsProps = {
const Rings = memo((props: RingsProps) => {
const activeLevel = useStore((state) => state.activeLevel);
const currentSite = useStore((state) => state.activeSite);
const visibleRings = useMemo(() => {
const rings: [string, number][] = [];
if (props.activateAllRings) {
Object.entries(level_y_values).forEach((levelDataPair) => {
rings.push([levelDataPair[0], levelDataPair[1]]);
});
} else {
const activeLevelNr = parseInt(activeLevel);
const visibleLevels = [
(activeLevelNr - 2).toString().padStart(2, "0"),
(activeLevelNr - 1).toString().padStart(2, "0"),
activeLevelNr.toString().padStart(2, "0"),
(activeLevelNr + 1).toString().padStart(2, "0"),
(activeLevelNr + 2).toString().padStart(2, "0"),
];
const levelUpperLimit = useMemo(() => (currentSite === "a" ? 22 : 13), [
currentSite,
]);
visibleLevels.forEach((level) => {
rings.push([
const possibleLevels = useMemo(
() =>
Array.from({ length: levelUpperLimit }, (_, i) =>
(i + 1).toString().padStart(2, "0")
),
[levelUpperLimit]
);
const visibleRings: [string, number][] = useMemo(() => {
if (props.activateAllRings) {
return Object.entries(level_y_values)
.sort((a, b) => a[0].localeCompare(b[0]))
.slice(0, levelUpperLimit);
} else {
const activeLevelIdx = parseInt(activeLevel) - 1;
return possibleLevels
.slice(
activeLevelIdx < 3 ? 0 : activeLevelIdx - 3,
activeLevelIdx > levelUpperLimit - 3
? levelUpperLimit
: activeLevelIdx + 3
)
.map((level) => [
level,
level_y_values[level as keyof typeof level_y_values],
]);
});
}
return rings;
}, [props.activateAllRings, activeLevel]);
}, [props.activateAllRings, activeLevel, possibleLevels, levelUpperLimit]);
return (
<>
{visibleRings.map((level: [string, number]) => {
if (
(currentSite === "b" && parseInt(level[0]) <= 13) ||
currentSite === "a"
) {
return (
<group position={[0, level[1], 0]} key={level[0]}>
<PurpleRing
purpleRingPosY={0.44}
level={level[0]}
site={currentSite}
/>
<GrayRing grayRingPosY={-0.29} />
<CyanCrystal crystalRingPosY={-0.45} />
</group>
);
}
})}
{visibleRings.map((level: [string, number]) => (
<group position={[0, level[1], 0]} key={level[0]}>
<PurpleRing
purpleRingPosY={0.44}
level={level[0]}
site={currentSite}
/>
<GrayRing grayRingPosY={-0.29} />
<CyanCrystal crystalRingPosY={-0.45} />
</group>
))}
</>
);
});

View file

@ -1,7 +1,7 @@
import React, { useCallback, useMemo, memo } from "react";
import React, { memo, useMemo } from "react";
import TriangularPrism from "./LeftSide/TriangularPrism";
import Cube from "./LeftSide/Cube";
import { useSpring, a } from "@react-spring/three";
import { a, useSpring } from "@react-spring/three";
import { useStore } from "../../../store";
export type ShapeProps = {
@ -12,15 +12,12 @@ export type ShapeProps = {
const LeftSide = memo(() => {
const activeMediaComponent = useStore(
useCallback(
(state) =>
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
state.mediaComponentMatrixIndices.sideIdx === 0
? state.mediaComponentMatrixIndices.leftSideIdx
: state.mediaComponentMatrixIndices.rightSideIdx
],
[]
)
(state) =>
state.mediaComponentMatrix[state.mediaComponentMatrixIndices.sideIdx][
state.mediaComponentMatrixIndices.sideIdx === 0
? state.mediaComponentMatrixIndices.leftSideIdx
: state.mediaComponentMatrixIndices.rightSideIdx
]
);
const cubesActive = useMemo(() => activeMediaComponent === "exit", [

View file

@ -10,13 +10,10 @@ const RightSide = memo(() => {
const words = useStore((state) => state.activeNode.words);
const wordPositionState = useStore(
useCallback(
(state) =>
word_position_states[
state.mediaWordPosStateIdx.toString() as keyof typeof word_position_states
],
[]
)
(state) =>
word_position_states[
state.mediaWordPosStateIdx.toString() as keyof typeof word_position_states
]
);
const wordPositionStateSpring = useSpring({

View file

@ -1,4 +1,4 @@
import React, { useCallback, useEffect } from "react";
import React from "react";
import answerContainer from "../static/sprite/prompt_answer_container.png";
import questionContainer from "../static/sprite/prompt_question_container.png";
import yes from "../static/sprite/prompt_yes.png";
@ -19,10 +19,7 @@ const Prompt = () => {
const noTex = useLoader(THREE.TextureLoader, no);
const activeComponent = useStore(
useCallback(
(state) => state.promptComponentMatrix[state.promptComponentMatrixIdx],
[]
)
(state) => state.promptComponentMatrix[state.promptComponentMatrixIdx]
);
return (

View file

@ -1,4 +1,4 @@
import React, { memo, useCallback } from "react";
import React, { memo } from "react";
import ssknOk from "../../static/sprite/sskn_ok.png";
import ssknOkInactive from "../../static/sprite/sskn_ok_inactive.png";
import ssknCancel from "../../static/sprite/sskn_cancel.png";
@ -31,10 +31,7 @@ const SSknHUD = memo(() => {
const ssknLineTex = useLoader(THREE.TextureLoader, ssknLine);
const activeSSknComponent = useStore(
useCallback(
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx],
[]
)
(state) => state.ssknComponentMatrix[state.ssknComponentMatrixIdx]
);
const loading = useStore((state) => state.ssknLoading);

View file

@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import React from "react";
import statusContainer from "../static/sprite/status_container.png";
import loadSuccessfulImg from "../static/sprite/load_successful.png";
import loadFailImg from "../static/sprite/load_fail.png";

View file

@ -4,7 +4,6 @@ import { a, useTrail } from "@react-spring/three";
import SiteBigLetter from "./SiteBigLetter";
import usePrevious from "../../hooks/usePrevious";
import { getNodeHud } from "../../utils/node-utils";
import sleep from "../../utils/sleep";
const MainYellowTextAnimator = (props: { visible?: boolean }) => {
const activeNode = useStore((state) => state.activeNode);

View file

@ -2,7 +2,6 @@ import React, { memo, useEffect, useState } from "react";
import { useStore } from "../../store";
import { a, useTrail } from "@react-spring/three";
import SiteBigLetter from "./SiteBigLetter";
import sleep from "../../utils/sleep";
const MediaYellowTextAnimator = memo(() => {
const [lastLeftComponent, setLastLeftComponent] = useState("play");

View file

@ -1,5 +1,4 @@
import { useStore } from "../../../../store";
import sleep from "../../../../utils/sleep";
const lainManager = (eventState: any) => {
const setLainMoveState = useStore.getState().setLainMoveState;

View file

@ -1,13 +1,7 @@
import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import React, { useEffect, useMemo, useRef, useState } from "react";
import * as THREE from "three";
import { useFrame } from "react-three-fiber";
import { createAudioAnalyser, useStore } from "../store";
import { useStore } from "../store";
import EndSelectionScreen from "../components/EndScene/EndSelectionScreen";
import endroll from "../static/movie/ENDROLL1.STR[0].webm";
import endrollVtt from "../static/webvtt/Endroll.vtt";

View file

@ -1,6 +1,6 @@
import { OrbitControls } from "@react-three/drei";
import React, { Suspense, useEffect, useRef, useState } from "react";
import { useStore } from "../store";
import { playAudio, useStore } from "../store";
import Pause from "../components/MainScene/PauseSubscene/Pause";
import LevelSelection from "../components/MainScene/LevelSelection";
import HUD from "../components/MainScene/HUD";
@ -15,9 +15,8 @@ import * as THREE from "three";
import { useFrame } from "react-three-fiber";
import NotFound from "../components/MainScene/NotFound";
import PausePopUps from "../components/MainScene/PauseSubscene/PausePopUps";
import { playAudio } from "../store";
import * as audio from "../static/sfx";
import sleep from "../utils/sleep";
import Loading from "../components/Loading";
const MainScene = () => {
const intro = useStore((state) => state.intro);
@ -91,7 +90,7 @@ const MainScene = () => {
return (
<perspectiveCamera position-z={3}>
<Suspense fallback={null}>
<Suspense fallback={<Loading />}>
<LevelSelection />
<PausePopUps />
<Pause />

View file

@ -1,4 +1,4 @@
import React, { useEffect } from "react";
import React, { useEffect, useState } from "react";
import { createAudioAnalyser, useStore } from "../store";
import LeftSide from "../components/MediaScene/Selectables/LeftSide";
import RightSide from "../components/MediaScene/Selectables/RightSide";
@ -8,6 +8,7 @@ import NodeNameContainer from "../components/MediaScene/NodeNameContainer";
import Images from "../components/Images";
import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer";
import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator";
import Loading from "../components/Loading";
const MediaScene = () => {
const percentageElapsed = useStore((state) => state.mediaPercentageElapsed);
@ -65,26 +66,36 @@ const MediaScene = () => {
}
}, [activeNode.media_file, activeNode.node_name, setAudioAnalyser]);
const [loaded, setLoaded] = useState(false);
useEffect(() => {
setLoaded(true);
}, []);
return (
<perspectiveCamera position-z={3}>
<group position={[0.4, -0.3, 0]}>
<pointLight intensity={1.2} color={0xffffff} position={[-2, 0, 0]} />
<LeftSide />
<group position={[0, 0.5, -3]}>
<MediaLoadingBar />
<NodeNameContainer />
</group>
<group scale={[0.06, 0.12, 0]} position={[0.8, 1.37, 0]}>
<GreenTextRenderer />
</group>
<MediaYellowTextAnimator />
{loaded ? (
<group position={[0.4, -0.3, 0]}>
<pointLight intensity={1.2} color={0xffffff} position={[-2, 0, 0]} />
<LeftSide />
<group position={[0, 0.5, -3]}>
<MediaLoadingBar />
<NodeNameContainer />
</group>
<group scale={[0.06, 0.12, 0]} position={[0.8, 1.37, 0]}>
<GreenTextRenderer />
</group>
<MediaYellowTextAnimator />
<group visible={activeNode.media_file.includes("XA")}>
<RightSide />
<AudioVisualizer />
<Images />
<group visible={activeNode.media_file.includes("XA")}>
<RightSide />
<AudioVisualizer />
<Images />
</group>
</group>
</group>
) : (
<Loading />
)}
</perspectiveCamera>
);
};

View file

@ -1,7 +1,6 @@
import React, { useEffect, useState } from "react";
import LainSpeak from "../components/LainSpeak";
import { createAudioAnalyser, useStore } from "../store";
import sleep from "../utils/sleep";
const TaKScene = () => {
const setScene = useStore((state) => state.setScene);

View file

@ -157,12 +157,12 @@ export const useStore = create(
// site
activeSite: "a",
siteRot: [0, 0, 0],
// this one is used for word selection animation to start from the correct point
// this is used for word selection animation to start from the correct point
oldSiteRot: [0, 0, 0],
// level
activeLevel: "04",
// this one is used for word selection animation to start from the correct point
// this is used for word selection animation to start from the correct point
oldLevel: "04",
// level selection