mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
added site b
This commit is contained in:
parent
07cc48ae49
commit
ac5edb303f
27 changed files with 7096 additions and 6654 deletions
|
@ -5,16 +5,21 @@ import site_a from "../../resources/site_a.json";
|
|||
import { useNodeStore, useLevelStore, useSiteStore } from "../../store";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { isNodeVisible } from "../../core/nodeSelector";
|
||||
import site_b from "../../resources/site_b.json";
|
||||
|
||||
const ActiveLevelNodes = () => {
|
||||
const gameProgress = useNodeStore((state) => state.gameProgress);
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const activeNodeState = useNodeStore((state) => state.activeNodeState);
|
||||
const activeLevel = useLevelStore((state) => state.activeLevel);
|
||||
|
||||
const activeLevelNodes = useMemo(
|
||||
() => site_a[activeLevel as keyof typeof site_a],
|
||||
[activeLevel]
|
||||
() => siteData[activeLevel as keyof typeof siteData],
|
||||
[activeLevel, siteData]
|
||||
);
|
||||
|
||||
const siteTransformState = useSiteStore((state) => state.transformState);
|
||||
|
@ -33,7 +38,7 @@ const ActiveLevelNodes = () => {
|
|||
rotation-x={siteState.siteRotX}
|
||||
>
|
||||
{Object.entries(activeLevelNodes).map((node: [string, any]) => {
|
||||
if (isNodeVisible(node[0], gameProgress)) {
|
||||
if (isNodeVisible(node[0], gameProgress, currentSite)) {
|
||||
return (
|
||||
<Node
|
||||
sprite={node[1].node_name}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { useLoader } from "react-three-fiber";
|
|||
import * as THREE from "three";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
|
||||
const LevelSelection = () => {
|
||||
const LevelSelection = (props: { visible: boolean }) => {
|
||||
const levelSelectionFontTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
level_selection_font
|
||||
|
@ -57,7 +57,7 @@ const LevelSelection = () => {
|
|||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<group visible={props.visible}>
|
||||
<a.group position-y={verticalHudPosY} renderOrder={5}>
|
||||
<mesh
|
||||
scale={[0.3, 0.4, 0]}
|
||||
|
@ -137,7 +137,7 @@ const LevelSelection = () => {
|
|||
depthTest={false}
|
||||
/>
|
||||
</a.sprite>
|
||||
</>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -73,7 +73,10 @@ const Pause = (props: { visible: boolean }) => {
|
|||
}, [props.visible]);
|
||||
|
||||
return animation ? (
|
||||
<group position={[-0.85, -0.7, 0]} scale={[0.85, 0.85, 0]}>
|
||||
<group
|
||||
position={[-0.85, -0.7, 0]}
|
||||
scale={[0.85, 0.85, 0]}
|
||||
>
|
||||
{[0, 1, 2, 3, 2, 1, 0].map((row: number, rowIdx: number) =>
|
||||
[0, 1, 2, 3, 4, 5, 6].map((col: number) => {
|
||||
if (rowIdx === 5 && col > 0 && col < 5) {
|
||||
|
|
|
@ -4,6 +4,7 @@ import * as THREE from "three";
|
|||
import siteATex from "../../static/sprite/site_a.png";
|
||||
import siteBTex from "../../static/sprite/site_b.png";
|
||||
import siteLevelTex from "../../static/sprite/site_levels.png";
|
||||
import { useSiteStore } from "../../store";
|
||||
|
||||
type PurpleRingProps = {
|
||||
purpleRingPosY: number;
|
||||
|
@ -15,6 +16,8 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
const siteB = useLoader(THREE.TextureLoader, siteBTex);
|
||||
const siteLevels = useLoader(THREE.TextureLoader, siteLevelTex);
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const purpleRingRef = useRef<THREE.Object3D>();
|
||||
|
||||
const dispatchSiteLevelTextureOffset = (level: string) => {
|
||||
|
@ -37,8 +40,7 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
|
||||
const formattedLevel = props.level.padStart(2, "0");
|
||||
|
||||
uniforms.siteA = { type: "t", value: siteA };
|
||||
uniforms.siteB = { type: "t", value: siteB };
|
||||
uniforms.tex = { type: "t", value: currentSite === "a" ? siteA : siteB };
|
||||
uniforms.siteLevels = { type: "t", value: siteLevels };
|
||||
uniforms.siteLevelFirstCharacterOffset = {
|
||||
value: dispatchSiteLevelTextureOffset(formattedLevel.charAt(0)),
|
||||
|
@ -65,8 +67,7 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
|
||||
const fragmentShader = `
|
||||
varying vec2 vUv;
|
||||
uniform sampler2D siteA;
|
||||
uniform sampler2D siteB;
|
||||
uniform sampler2D tex;
|
||||
uniform sampler2D siteLevels;
|
||||
uniform float siteLevelFirstCharacterOffset;
|
||||
uniform float siteLevelSecondCharacterOffset;
|
||||
|
@ -106,14 +107,14 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
float slope(float x, float thin) {
|
||||
return x*(1.0-thin);
|
||||
}
|
||||
|
||||
|
||||
// frag color
|
||||
vec4 color(vec2 vUv, float step, bool textureexists) {
|
||||
if (!textureexists) {
|
||||
return vec4(0.325,0.325,0.698, 1);
|
||||
} else {
|
||||
float dist = 1.0-tolocal(0.5 - mod(vUv.x+0.172, 0.5), 12, step);
|
||||
return texture2D(siteA, vec2(dist, vUv.y)) ;
|
||||
return texture2D(tex, vec2(dist, vUv.y)) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import React, { memo, Suspense, useMemo } from "react";
|
||||
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 node_positions from "../../resources/node_positions.json";
|
||||
import Node from "./Node";
|
||||
|
@ -35,6 +36,9 @@ export type SiteType = {
|
|||
|
||||
const Site = memo(() => {
|
||||
const gameProgress = useNodeStore((state) => state.gameProgress);
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const activeLevel = useLevelStore((state) => state.activeLevel);
|
||||
const visibleNodes = useMemo(() => {
|
||||
|
@ -48,11 +52,11 @@ const Site = memo(() => {
|
|||
];
|
||||
|
||||
visibleLevels.forEach((level) => {
|
||||
Object.assign(obj, site_a[level as keyof typeof site_a]);
|
||||
Object.assign(obj, siteData[level as keyof typeof siteData]);
|
||||
});
|
||||
|
||||
return obj;
|
||||
}, [activeLevel]);
|
||||
}, [activeLevel, siteData]);
|
||||
|
||||
const siteTransformState = useSiteStore((state) => state.transformState);
|
||||
|
||||
|
@ -70,15 +74,22 @@ const Site = memo(() => {
|
|||
position-y={siteState.sitePosY}
|
||||
rotation-x={siteState.siteRotX}
|
||||
>
|
||||
{Object.entries(level_y_values).map((level: [string, number]) => (
|
||||
<group position={[0, level[1], 0]} key={level[0]}>
|
||||
<PurpleRing purpleRingPosY={0.44} level={level[0]} />
|
||||
<GrayRing grayRingPosY={-0.29} />
|
||||
<CyanCrystal crystalRingPosY={-0.45} />
|
||||
</group>
|
||||
))}
|
||||
{Object.entries(level_y_values).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]} />
|
||||
<GrayRing grayRingPosY={-0.29} />
|
||||
<CyanCrystal crystalRingPosY={-0.45} />
|
||||
</group>
|
||||
);
|
||||
}
|
||||
})}
|
||||
{Object.entries(visibleNodes).map((node: [string, any]) => {
|
||||
if (isNodeVisible(node[0], gameProgress)) {
|
||||
if (isNodeVisible(node[0], gameProgress, currentSite)) {
|
||||
return (
|
||||
<Node
|
||||
sprite={node[1].node_name}
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { useLevelStore, useMediaStore, useNodeStore } from "../../store";
|
||||
import {
|
||||
useLevelStore,
|
||||
useMediaStore,
|
||||
useNodeStore,
|
||||
useSiteStore,
|
||||
} from "../../store";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { LevelType, SiteType } from "../MainScene/Site";
|
||||
import site_a from "../../resources/site_a.json";
|
||||
import site_b from "../../resources/site_b.json";
|
||||
import dummy from "../../static/sprite/dummy.png";
|
||||
import * as THREE from "three";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
|
@ -13,6 +19,10 @@ const Images = () => {
|
|||
const [sceneImages, setSceneImages] = useState([] as any);
|
||||
const [activeImage, setActiveImage] = useState<THREE.Texture>();
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const dummyTex = useLoader(THREE.TextureLoader, dummy);
|
||||
|
||||
const mediaPercentageElapsed = useMediaStore(
|
||||
|
@ -26,27 +36,37 @@ const Images = () => {
|
|||
|
||||
const activeLevel = useLevelStore((state) => state.activeLevel);
|
||||
const activeLevelData: LevelType = useMemo(
|
||||
() => site_a[activeLevel as keyof typeof site_a],
|
||||
[activeLevel]
|
||||
() => siteData[activeLevel as keyof typeof siteData],
|
||||
[activeLevel, siteData]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const images = (site_a as SiteType)[activeLevel][activeNodeId]
|
||||
const images = (siteData as SiteType)[activeLevel][activeNodeId]
|
||||
.image_table_indices;
|
||||
|
||||
// checking the length of the img arr doesn't work in some cases
|
||||
// since the amount of images varies from 1 to 3.
|
||||
// we try all 3 of them for each case, so logging the count to
|
||||
// determine whether or not its complete is optimal i think.
|
||||
let imgTries = 0;
|
||||
const imgArr: { default: string }[] = [];
|
||||
Object.entries(images).forEach((img) => {
|
||||
import("../../static/media_images/a/" + img[1] + ".png").then(
|
||||
(imageSrc: { default: string }) => {
|
||||
imgTries++;
|
||||
if (img[1] !== "-1") {
|
||||
import(
|
||||
"../../static/media_images/" + currentSite + "/" + img[1] + ".png"
|
||||
).then((imageSrc: { default: string }) => {
|
||||
imgArr.splice(parseInt(img[0]), 0, imageSrc);
|
||||
if (imgArr.length === 3) {
|
||||
console.log(imgTries);
|
||||
if (imgTries === 3) {
|
||||
setSceneImages(imgArr);
|
||||
new THREE.TextureLoader().load(imgArr[0].default, setActiveImage);
|
||||
console.log(imgArr);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}, [activeLevel, activeLevelData, activeNodeId]);
|
||||
}, [activeLevel, activeLevelData, activeNodeId, currentSite, siteData]);
|
||||
|
||||
useEffect(() => {
|
||||
if (mediaPercentageElapsed === 0 && sceneImages[0]) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import React, {
|
|||
useState,
|
||||
} from "react";
|
||||
import site_a from "../../resources/site_a.json";
|
||||
import site_b from "../../resources/site_b.json";
|
||||
import {
|
||||
useLevelStore,
|
||||
useMediaStore,
|
||||
|
@ -24,13 +25,16 @@ const MediaPlayer = () => {
|
|||
(state) => state.setPercentageElapsed
|
||||
);
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
const activeNodeId = useNodeStore((state) => state.activeNodeState.id);
|
||||
const activeLevel = useLevelStore((state) => state.activeLevel);
|
||||
|
||||
const requestRef = useRef();
|
||||
const videoRef = createRef<HTMLVideoElement>();
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const updateTime = useCallback(() => {
|
||||
(requestRef.current as any) = requestAnimationFrame(updateTime);
|
||||
if (videoRef.current) {
|
||||
|
@ -42,6 +46,7 @@ const MediaPlayer = () => {
|
|||
setPercentageElapsed(percentageElapsed);
|
||||
if (percentageElapsed === 100) {
|
||||
videoRef.current.pause();
|
||||
videoRef.current.currentTime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,7 +60,7 @@ const MediaPlayer = () => {
|
|||
|
||||
useEffect(() => {
|
||||
if (currentScene === "media" || currentScene === "tak") {
|
||||
const nodeMedia = (site_a as SiteType)[activeLevel][activeNodeId]
|
||||
const nodeMedia = (siteData as SiteType)[activeLevel][activeNodeId]
|
||||
.media_file;
|
||||
if (nodeMedia.includes("XA")) {
|
||||
import(
|
||||
|
@ -77,7 +82,14 @@ const MediaPlayer = () => {
|
|||
});
|
||||
}
|
||||
}
|
||||
}, [activeLevel, activeNodeId, currentScene, currentSite, videoRef]);
|
||||
}, [
|
||||
activeLevel,
|
||||
activeNodeId,
|
||||
currentScene,
|
||||
currentSite,
|
||||
siteData,
|
||||
videoRef,
|
||||
]);
|
||||
|
||||
return (
|
||||
<video
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import React, { useCallback, useMemo } from "react";
|
||||
import { useLevelStore, useMediaWordStore, useNodeStore } from "../../../store";
|
||||
import {useLevelStore, useMediaWordStore, useNodeStore, useSiteStore} from "../../../store";
|
||||
import Word from "./RightSide/Word";
|
||||
import { useSpring, a } from "@react-spring/three";
|
||||
import word_position_states from "../../../resources/word_position_states.json";
|
||||
import * as THREE from "three";
|
||||
import site_a from "../../../resources/site_a.json";
|
||||
import { SiteType } from "../../MainScene/Site";
|
||||
import site_b from "../../../resources/site_b.json";
|
||||
|
||||
type RightSideProps = {
|
||||
activeMediaComponent: string;
|
||||
|
@ -15,7 +16,11 @@ const RightSide = (props: RightSideProps) => {
|
|||
const activeLevel = useLevelStore((state) => state.activeLevel);
|
||||
const activeNodeId = useNodeStore((state) => state.activeNodeState.id);
|
||||
|
||||
const words = (site_a as SiteType)[activeLevel][activeNodeId].words;
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const words = (siteData as SiteType)[activeLevel][activeNodeId].words;
|
||||
|
||||
const posStateIdx = useMediaWordStore(
|
||||
(state) => state.posStateIdx
|
||||
|
|
39
src/components/TextRenderer/MediaYellowTextAnimator.tsx
Normal file
39
src/components/TextRenderer/MediaYellowTextAnimator.tsx
Normal file
|
@ -0,0 +1,39 @@
|
|||
import React 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 trail = useTrail(textArr.length, {
|
||||
posX: transformState.posX,
|
||||
posY: transformState.posY,
|
||||
config: { duration: 280 },
|
||||
});
|
||||
|
||||
return (
|
||||
<group position={[0, 0, 10]}>
|
||||
{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={"yellow"}
|
||||
xOffsetCoeff={transformState.xOffset}
|
||||
letter={textArr[idx]}
|
||||
letterIdx={idx}
|
||||
key={idx}
|
||||
/>
|
||||
</a.group>
|
||||
))}
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
export default MediaYellowTextAnimator;
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useEffect, useRef } from "react";
|
||||
import { useBigTextStore, BigTextState, useMainSceneStore } from "../../store";
|
||||
import { BigTextState, useBigTextStore } from "../../store";
|
||||
import { a, useSpring, useTrail } from "@react-spring/three";
|
||||
import BigLetter from "./BigLetter";
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ import {
|
|||
} from "../../store";
|
||||
import GreenTextManager from "./GreenTextManager";
|
||||
import MediaComponentManager from "./MediaComponentManager";
|
||||
import MediaWordManager from "./MediaWordManager";
|
||||
import SceneManager from "./SceneManager";
|
||||
import YellowTextManager from "./YellowTextManager";
|
||||
import LevelManager from "./LevelManager";
|
||||
|
@ -34,6 +33,7 @@ import BootAuthorizeUserManager from "./BootAuthorizeUserManager";
|
|||
import LevelSelectionManager from "./LevelSelectionManager";
|
||||
import SubsceneManager from "./SubsceneManager";
|
||||
import PauseComponentManager from "./PauseComponentManager";
|
||||
import MediaYellowTextManager from "./MediaYellowTextManager";
|
||||
|
||||
const getKeyCodeAssociation = (keyCode: number): string => {
|
||||
const keyCodeAssocs = {
|
||||
|
@ -57,6 +57,7 @@ const EventManager = () => {
|
|||
const currentScene = useSceneStore((state) => state.currentScene);
|
||||
|
||||
// main scene
|
||||
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);
|
||||
|
@ -154,6 +155,7 @@ const EventManager = () => {
|
|||
pauseMatrixIdx: pauseMatrixIdx,
|
||||
activePauseComponent: activePauseComponent,
|
||||
gameProgress: gameProgress,
|
||||
currentSite: currentSite,
|
||||
});
|
||||
break;
|
||||
case "media":
|
||||
|
@ -188,25 +190,27 @@ const EventManager = () => {
|
|||
}
|
||||
},
|
||||
[
|
||||
activeBootElement,
|
||||
activeLevel,
|
||||
activeMediaComponent,
|
||||
activePauseComponent,
|
||||
activeSSknComponent,
|
||||
authorizeUserActiveLetterTexOffset,
|
||||
authorizeUserBgLettersPos,
|
||||
authorizeUserMatrixIdx,
|
||||
currentBootSubscene,
|
||||
currentScene,
|
||||
inputCooldown,
|
||||
currentScene,
|
||||
mainSubscene,
|
||||
nodeMatrixIndices,
|
||||
pauseMatrixIdx,
|
||||
rightSideComponentIdx,
|
||||
selectedLevel,
|
||||
siteTransformState,
|
||||
activeNodeId,
|
||||
nodeMatrixIndices,
|
||||
activeLevel,
|
||||
selectedLevel,
|
||||
pauseMatrixIdx,
|
||||
activePauseComponent,
|
||||
gameProgress,
|
||||
currentSite,
|
||||
activeMediaComponent,
|
||||
wordPosStateIdx,
|
||||
rightSideComponentIdx,
|
||||
currentBootSubscene,
|
||||
activeBootElement,
|
||||
authorizeUserBgLettersPos,
|
||||
authorizeUserActiveLetterTexOffset,
|
||||
authorizeUserMatrixIdx,
|
||||
activeSSknComponent,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -227,7 +231,6 @@ const EventManager = () => {
|
|||
<LainManager eventState={eventState!} />
|
||||
<MiddleRingManager eventState={eventState!} />
|
||||
<MediaComponentManager eventState={eventState!} />
|
||||
<MediaWordManager eventState={eventState!} />
|
||||
<SceneManager eventState={eventState!} />
|
||||
<YellowTextManager eventState={eventState!} />
|
||||
<LevelManager eventState={eventState!} />
|
||||
|
@ -237,6 +240,7 @@ const EventManager = () => {
|
|||
<LevelSelectionManager eventState={eventState!} />
|
||||
<SubsceneManager eventState={eventState!} />
|
||||
<PauseComponentManager eventState={eventState!} />
|
||||
<MediaYellowTextManager eventState={eventState!} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -3,7 +3,8 @@ 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/Site";
|
||||
import { useGreenTextStore } from "../../store";
|
||||
import { useGreenTextStore, useSiteStore } from "../../store";
|
||||
import site_b from "../../resources/site_b.json";
|
||||
|
||||
const GreenTextManager = (props: StateManagerProps) => {
|
||||
const setGreenText = useGreenTextStore((state) => state.setText);
|
||||
|
@ -12,6 +13,10 @@ const GreenTextManager = (props: StateManagerProps) => {
|
|||
(state) => state.setTransformState
|
||||
);
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const toggleAndSetGreenText = useCallback(
|
||||
(
|
||||
newActiveNodeId: string,
|
||||
|
@ -23,7 +28,7 @@ const GreenTextManager = (props: StateManagerProps) => {
|
|||
const targetGreenText =
|
||||
newActiveNodeId === "UNKNOWN"
|
||||
? ""
|
||||
: (site_a as SiteType)[newLevel][newActiveNodeId].title;
|
||||
: (siteData as SiteType)[newLevel][newActiveNodeId].title;
|
||||
|
||||
const targetGreenTextPosData =
|
||||
node_huds[newActiveHudId as keyof typeof node_huds].medium_text;
|
||||
|
@ -43,7 +48,7 @@ const GreenTextManager = (props: StateManagerProps) => {
|
|||
toggleActive();
|
||||
}, delay);
|
||||
},
|
||||
[setGreenText, setTransformState, toggleActive]
|
||||
[setGreenText, setTransformState, siteData, toggleActive]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
|
|
|
@ -1,90 +1,121 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "./EventManager";
|
||||
import { useMediaStore } from "../../store";
|
||||
import { useMediaStore, useMediaWordStore } from "../../store";
|
||||
import * as THREE from "three";
|
||||
|
||||
const MediaComponentManager = (props: StateManagerProps) => {
|
||||
const toggleSide = useMediaStore((state) => state.toggleSide);
|
||||
const toggleLeftComponent = useMediaStore(
|
||||
(state) => state.toggleLeftComponent
|
||||
const setLeftComponentMatrixIdx = useMediaStore(
|
||||
(state) => state.setLeftComponentMatrixIdx
|
||||
);
|
||||
const setRightComponentMatrixIdx = useMediaStore(
|
||||
(state) => state.setRightComponentMatrixIdx
|
||||
);
|
||||
const setWordPosStateIdx = useMediaWordStore((state) => state.setPosStateIdx);
|
||||
|
||||
const resetComponentMatrixIndices = useMediaStore(
|
||||
(state) => state.resetComponentMatrixIndices
|
||||
);
|
||||
const resetWordPosStateIdx = useMediaWordStore(
|
||||
(state) => state.resetPosStateIdx
|
||||
);
|
||||
|
||||
const setAudioAnalyser = useMediaStore((state) => state.setAudioAnalyser);
|
||||
|
||||
const playMedia = useCallback(() => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
|
||||
const listener = new THREE.AudioListener();
|
||||
const audio = new THREE.Audio(listener);
|
||||
if (mediaElement && mediaElement.paused) {
|
||||
const listener = new THREE.AudioListener();
|
||||
const audio = new THREE.Audio(listener);
|
||||
|
||||
audio.setMediaElementSource(mediaElement);
|
||||
audio.setMediaElementSource(mediaElement);
|
||||
|
||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
||||
setAudioAnalyser(new THREE.AudioAnalyser(audio, 2048));
|
||||
|
||||
if (mediaElement) {
|
||||
mediaElement.play();
|
||||
}
|
||||
}, [setAudioAnalyser]);
|
||||
|
||||
const exitMedia = useCallback(() => {
|
||||
const mediaElement = document.getElementById("media") as HTMLMediaElement;
|
||||
if (mediaElement) {
|
||||
mediaElement.pause();
|
||||
mediaElement.currentTime = 0;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const updateRightSide = useCallback(
|
||||
(newRightSideComponentIdx: number, newWordPosStateIdx: number) => {
|
||||
setRightComponentMatrixIdx(newRightSideComponentIdx);
|
||||
setWordPosStateIdx(newWordPosStateIdx);
|
||||
},
|
||||
[setRightComponentMatrixIdx, setWordPosStateIdx]
|
||||
);
|
||||
|
||||
const resetMediaState = useCallback(() => {
|
||||
resetComponentMatrixIndices();
|
||||
resetWordPosStateIdx();
|
||||
}, [resetComponentMatrixIndices, resetWordPosStateIdx]);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(event: string, newRightSideComponentIdx) => {
|
||||
(
|
||||
event: string,
|
||||
newLeftSideComponentIdx: number,
|
||||
newRightSideComponentIdx: number,
|
||||
newWordPosStateIdx: number
|
||||
) => {
|
||||
switch (event) {
|
||||
case "fstWord_down":
|
||||
case "sndWord_down":
|
||||
case "thirdWord_down":
|
||||
case "fstWord_up":
|
||||
case "thirdWord_up":
|
||||
case "sndWord_up":
|
||||
case "media_rightside_down":
|
||||
case "media_rightside_up":
|
||||
return {
|
||||
action: setRightComponentMatrixIdx,
|
||||
value: [newRightSideComponentIdx],
|
||||
action: updateRightSide,
|
||||
value: [newRightSideComponentIdx, newWordPosStateIdx],
|
||||
};
|
||||
case "play_down":
|
||||
case "exit_up":
|
||||
case "media_leftside_down":
|
||||
case "media_leftside_up":
|
||||
return {
|
||||
action: toggleLeftComponent,
|
||||
action: setLeftComponentMatrixIdx,
|
||||
value: [newLeftSideComponentIdx],
|
||||
};
|
||||
case "play_right":
|
||||
case "exit_right":
|
||||
case "fstWord_left":
|
||||
case "sndWord_left":
|
||||
case "thirdWord_left":
|
||||
case "media_leftside_right":
|
||||
case "media_rightside_left":
|
||||
return {
|
||||
action: toggleSide,
|
||||
};
|
||||
case "throw_node_media":
|
||||
return {
|
||||
action: resetComponentMatrixIndices,
|
||||
action: resetMediaState,
|
||||
};
|
||||
case "play_select":
|
||||
case "media_play_select":
|
||||
return { action: playMedia };
|
||||
case "media_exit_select":
|
||||
return { action: exitMedia };
|
||||
}
|
||||
},
|
||||
[
|
||||
exitMedia,
|
||||
playMedia,
|
||||
resetComponentMatrixIndices,
|
||||
setRightComponentMatrixIdx,
|
||||
toggleLeftComponent,
|
||||
resetMediaState,
|
||||
setLeftComponentMatrixIdx,
|
||||
toggleSide,
|
||||
updateRightSide,
|
||||
]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const eventAction = props.eventState.event;
|
||||
const newLeftSideComponentIdx = props.eventState.newLeftSideComponentIdx;
|
||||
const newRightSideComponentIdx =
|
||||
props.eventState.newRightSideComponentIdx;
|
||||
const newWordPosStateIdx = props.eventState.newWordPosStateIdx;
|
||||
|
||||
const dispatchedObject = dispatchObject(
|
||||
eventAction,
|
||||
newRightSideComponentIdx
|
||||
newLeftSideComponentIdx,
|
||||
newRightSideComponentIdx,
|
||||
newWordPosStateIdx
|
||||
);
|
||||
|
||||
if (dispatchedObject) {
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { StateManagerProps } from "./EventManager";
|
||||
import { useMediaWordStore } from "../../store";
|
||||
|
||||
const MediaWordManager = (props: StateManagerProps) => {
|
||||
const setPosStateIdx = useMediaWordStore((state) => state.setPosStateIdx);
|
||||
const resetPosStateIdx = useMediaWordStore((state) => state.resetPosStateIdx);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(event: string, newWordPosStateIdx: number) => {
|
||||
switch (event) {
|
||||
case "fstWord_down":
|
||||
case "sndWord_down":
|
||||
case "thirdWord_down":
|
||||
case "fstWord_up":
|
||||
case "sndWord_up":
|
||||
case "thirdWord_up":
|
||||
return {
|
||||
action: setPosStateIdx,
|
||||
value: newWordPosStateIdx,
|
||||
};
|
||||
case "throw_node_media":
|
||||
return {
|
||||
action: resetPosStateIdx,
|
||||
};
|
||||
}
|
||||
},
|
||||
[resetPosStateIdx, setPosStateIdx]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const eventAction = props.eventState.event;
|
||||
const newWordPosStateIdx = props.eventState.newWordPosStateIdx;
|
||||
|
||||
const dispatchedObject = dispatchObject(eventAction, newWordPosStateIdx);
|
||||
|
||||
if (dispatchedObject) {
|
||||
dispatchedObject.action(dispatchedObject.value as any);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default MediaWordManager;
|
71
src/core/StateManagers/MediaYellowTextManager.tsx
Normal file
71
src/core/StateManagers/MediaYellowTextManager.tsx
Normal file
|
@ -0,0 +1,71 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import { useMediaBigTextStore } from "../../store";
|
||||
import { StateManagerProps } from "./EventManager";
|
||||
|
||||
const MediaYellowTextManager = (props: StateManagerProps) => {
|
||||
const setTransformState = useMediaBigTextStore(
|
||||
(state) => state.setTransformState
|
||||
);
|
||||
|
||||
const setText = useMediaBigTextStore((state) => state.setText);
|
||||
|
||||
const animateMediaYellowText = useCallback(
|
||||
(
|
||||
targetMediaComponentText: string,
|
||||
targetMediaComponentTextPos: number[]
|
||||
) => {
|
||||
// make current text shrink
|
||||
setTransformState(-1, "xOffset");
|
||||
|
||||
setTimeout(() => {
|
||||
setTransformState(targetMediaComponentTextPos[0], "posX");
|
||||
setTransformState(targetMediaComponentTextPos[1], "posY");
|
||||
}, 400);
|
||||
|
||||
setTimeout(() => {
|
||||
setText(targetMediaComponentText);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
// unshrink text
|
||||
setTransformState(0, "xOffset");
|
||||
}, 1200);
|
||||
},
|
||||
[setText, setTransformState]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
(event: string) => {
|
||||
switch (event) {
|
||||
case "media_leftside_up":
|
||||
case "throw_node_media":
|
||||
return {
|
||||
action: animateMediaYellowText,
|
||||
value: ["Play", [-0.8, 0.05, 0.6]],
|
||||
};
|
||||
case "media_leftside_down":
|
||||
return {
|
||||
action: animateMediaYellowText,
|
||||
value: ["Exit", [-0.8, -0.08, 0.6]],
|
||||
};
|
||||
}
|
||||
},
|
||||
[animateMediaYellowText]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (props.eventState) {
|
||||
const eventAction = props.eventState.event;
|
||||
|
||||
const dispatchedObject = dispatchObject(eventAction);
|
||||
|
||||
if (dispatchedObject) {
|
||||
(dispatchedObject.action as any).apply(null, dispatchedObject.value);
|
||||
}
|
||||
}
|
||||
}, [props.eventState, dispatchObject]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
export default MediaYellowTextManager;
|
|
@ -22,7 +22,7 @@ const PauseComponentManager = (props: StateManagerProps) => {
|
|||
action: setExitAnimation,
|
||||
value: true,
|
||||
};
|
||||
case "toggle_pause":
|
||||
case "pause_game":
|
||||
return {
|
||||
action: setExitAnimation,
|
||||
value: false,
|
||||
|
|
|
@ -17,7 +17,7 @@ const SceneManager = (props: StateManagerProps) => {
|
|||
value: newScene,
|
||||
delay: 3450,
|
||||
};
|
||||
case "exit_select":
|
||||
case "media_exit_select":
|
||||
case "exit_gate":
|
||||
case "sskn_cancel_select":
|
||||
return {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import { useCallback, useEffect } from "react";
|
||||
import { useSiteStore } from "../../store";
|
||||
import { StateManagerProps } from "./EventManager";
|
||||
|
||||
|
@ -24,10 +24,10 @@ const SiteManager = (props: StateManagerProps) => {
|
|||
value: [newSiteRotY, "rotY"],
|
||||
actionDelay: 1100,
|
||||
};
|
||||
case "toggle_pause":
|
||||
case "pause_game":
|
||||
return {
|
||||
action: setTransformState,
|
||||
value: [Math.PI / 2, "rotX"],
|
||||
value: [Math.PI / 2 - 0.5, "rotX"],
|
||||
actionDelay: 0,
|
||||
};
|
||||
case "pause_exit_select":
|
||||
|
|
|
@ -23,7 +23,7 @@ const SubsceneManager = (props: StateManagerProps) => {
|
|||
value: "level_selection",
|
||||
delay: 0,
|
||||
};
|
||||
case "toggle_pause":
|
||||
case "pause_game":
|
||||
return {
|
||||
action: setMainSubscene,
|
||||
value: "pause",
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { useCallback, useEffect } from "react";
|
||||
import node_huds from "../../resources/node_huds.json";
|
||||
import site_a from "../../resources/site_a.json";
|
||||
import { useBigTextStore } from "../../store";
|
||||
import site_b from "../../resources/site_b.json";
|
||||
import { useBigTextStore, useSiteStore } from "../../store";
|
||||
import { SiteType } from "../../components/MainScene/Site";
|
||||
import { StateManagerProps } from "./EventManager";
|
||||
|
||||
|
@ -18,6 +19,9 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
|
||||
const setVisible = useBigTextStore((state) => state.setVisible);
|
||||
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const animateYellowTextWithMove = useCallback(
|
||||
(
|
||||
posXOffset: number,
|
||||
|
@ -55,7 +59,7 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
const targetText =
|
||||
newActiveNodeId === "UNKNOWN"
|
||||
? "Unknown"
|
||||
: (site_a as SiteType)[newLevel][newActiveNodeId].node_name;
|
||||
: (siteData as SiteType)[newLevel][newActiveNodeId].node_name;
|
||||
|
||||
setText(targetText);
|
||||
setDisableTrail(false);
|
||||
|
@ -66,7 +70,7 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
setTransformState(0, "xOffset");
|
||||
}, 3900);
|
||||
},
|
||||
[addToTransformState, setDisableTrail, setText, setTransformState]
|
||||
[addToTransformState, setDisableTrail, setText, setTransformState, siteData]
|
||||
);
|
||||
|
||||
const animateYellowTextWithoutMove = useCallback(
|
||||
|
@ -88,7 +92,7 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
|
||||
setTimeout(() => {
|
||||
// set new text according to the node name
|
||||
setText((site_a as SiteType)[level][newActiveNodeId].node_name);
|
||||
setText((siteData as SiteType)[level][newActiveNodeId].node_name);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
|
@ -96,55 +100,7 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
setTransformState(0, "xOffset");
|
||||
}, 1200);
|
||||
},
|
||||
[setText, setTransformState]
|
||||
);
|
||||
|
||||
const animateMediaYellowText = useCallback(
|
||||
(
|
||||
targetMediaComponentText: string,
|
||||
targetMediaComponentTextPos: number[]
|
||||
) => {
|
||||
// make current text shrink
|
||||
setTransformState(-1, "xOffset");
|
||||
|
||||
setTimeout(() => {
|
||||
setTransformState(targetMediaComponentTextPos[0], "posX");
|
||||
setTransformState(targetMediaComponentTextPos[1], "posY");
|
||||
}, 400);
|
||||
|
||||
setTimeout(() => {
|
||||
setText(targetMediaComponentText);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
// unshrink text
|
||||
setTransformState(0, "xOffset");
|
||||
}, 1200);
|
||||
},
|
||||
[setText, setTransformState]
|
||||
);
|
||||
|
||||
const initializeYellowTextForMediaScene = useCallback(() => {
|
||||
setTimeout(() => {
|
||||
setText("Play");
|
||||
setTransformState(-0.8, "posX");
|
||||
setTransformState(0.05, "posY");
|
||||
}, 3950);
|
||||
}, [setText, setTransformState]);
|
||||
|
||||
const initializeYellowTextForMainScene = useCallback(
|
||||
(activeNodeId: string, activeHudId: string, level: string) => {
|
||||
setText((site_a as SiteType)[level][activeNodeId].node_name);
|
||||
setTransformState(
|
||||
node_huds[activeHudId as keyof typeof node_huds].big_text[0],
|
||||
"posX"
|
||||
);
|
||||
setTransformState(
|
||||
node_huds[activeHudId as keyof typeof node_huds].big_text[1],
|
||||
"posY"
|
||||
);
|
||||
},
|
||||
[setText, setTransformState]
|
||||
[setText, setTransformState, siteData]
|
||||
);
|
||||
|
||||
const initializeLevelSelection = useCallback(() => {
|
||||
|
@ -182,14 +138,14 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
|
||||
setTimeout(() => {
|
||||
setColor("yellow");
|
||||
setText((site_a as SiteType)[level][activeNodeId].node_name);
|
||||
setText((siteData as SiteType)[level][activeNodeId].node_name);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
setTransformState(0, "xOffset");
|
||||
}, 1200);
|
||||
},
|
||||
[setColor, setText, setTransformState]
|
||||
[setColor, setText, setTransformState, siteData]
|
||||
);
|
||||
|
||||
const toggleVisibleAfterLevelSelect = useCallback(
|
||||
|
@ -209,7 +165,7 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
const targetText =
|
||||
activeNodeId === "UNKNOWN"
|
||||
? "Unknown"
|
||||
: (site_a as SiteType)[level][activeNodeId].node_name;
|
||||
: (siteData as SiteType)[level][activeNodeId].node_name;
|
||||
|
||||
setText(targetText);
|
||||
}, 400);
|
||||
|
@ -218,7 +174,7 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
setVisible(true);
|
||||
}, 3900);
|
||||
},
|
||||
[setColor, setText, setTransformState, setVisible]
|
||||
[setColor, setText, setTransformState, setVisible, siteData]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
|
@ -263,30 +219,11 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
1100,
|
||||
],
|
||||
};
|
||||
case "exit_up":
|
||||
return {
|
||||
action: animateMediaYellowText,
|
||||
value: ["Play", [-0.8, 0.05, 0.6]],
|
||||
};
|
||||
case "change_node":
|
||||
return {
|
||||
action: animateYellowTextWithoutMove,
|
||||
value: [newActiveHudId, newActiveNodeId, newLevel],
|
||||
};
|
||||
case "play_down":
|
||||
return {
|
||||
action: animateMediaYellowText,
|
||||
value: ["Exit", [-0.8, -0.08, 0.6]],
|
||||
};
|
||||
case "throw_node_media":
|
||||
return {
|
||||
action: initializeYellowTextForMediaScene,
|
||||
};
|
||||
case "exit_media_scene":
|
||||
return {
|
||||
action: initializeYellowTextForMainScene,
|
||||
value: [newActiveNodeId, newActiveHudId, newLevel],
|
||||
};
|
||||
case "level_selection_back":
|
||||
return {
|
||||
action: levelSelectionBack,
|
||||
|
@ -305,12 +242,9 @@ const YellowTextManager = (props: StateManagerProps) => {
|
|||
}
|
||||
},
|
||||
[
|
||||
animateMediaYellowText,
|
||||
animateYellowTextWithMove,
|
||||
animateYellowTextWithoutMove,
|
||||
initializeLevelSelection,
|
||||
initializeYellowTextForMainScene,
|
||||
initializeYellowTextForMediaScene,
|
||||
levelSelectionBack,
|
||||
toggleVisibleAfterLevelSelect,
|
||||
]
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import node_matrices from "../resources/node_matrices.json";
|
||||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import nodeSelector, { getNodeHudId, getNodeId } from "./nodeSelector";
|
||||
import { SiteType } from "../components/MainScene/Site";
|
||||
|
||||
const handleMainSceneEvent = (gameContext: any) => {
|
||||
let event;
|
||||
|
@ -12,6 +14,7 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
const activePauseComponent = gameContext.activePauseComponent;
|
||||
const gameProgress = gameContext.gameProgress;
|
||||
const activeNodeId = gameContext.activeNodeId;
|
||||
const currentSite = gameContext.currentSite;
|
||||
|
||||
let nodeMatrixIndices = gameContext.nodeMatrixIndices;
|
||||
|
||||
|
@ -41,6 +44,7 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
siteRotY: siteRotY,
|
||||
sitePosY: sitePosY,
|
||||
gameProgress: gameProgress,
|
||||
currentSite: currentSite,
|
||||
});
|
||||
|
||||
if (selectedNodeData) {
|
||||
|
@ -60,13 +64,16 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
// new active blue orb here.
|
||||
newActiveNodeId = getNodeId(level, nodeMatrixIndices);
|
||||
|
||||
const nodeType = (site_a as any)[gameContext.activeLevel][
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const nodeData = (siteData as SiteType)[gameContext.activeLevel][
|
||||
newActiveNodeId
|
||||
].type;
|
||||
];
|
||||
const nodeType = nodeData.type;
|
||||
|
||||
const eventAnimation = "throw_node_";
|
||||
|
||||
switch (parseInt(nodeType)) {
|
||||
switch (nodeType) {
|
||||
case 0:
|
||||
case 2:
|
||||
case 4:
|
||||
|
@ -76,8 +83,13 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
newScene = "media";
|
||||
break;
|
||||
case 6:
|
||||
event = eventAnimation + "tak";
|
||||
newScene = "tak";
|
||||
if (nodeData.node_name.substr(0, 3) === "TaK") {
|
||||
event = eventAnimation + "tak";
|
||||
newScene = "tak";
|
||||
} else {
|
||||
event = eventAnimation + "media";
|
||||
newScene = "media";
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
event = eventAnimation + "gate";
|
||||
|
@ -92,7 +104,7 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
case "L2":
|
||||
return { event: "toggle_level_selection" };
|
||||
case "TRIANGLE":
|
||||
return { event: "toggle_pause" };
|
||||
return { event: "pause_game" };
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -108,14 +120,22 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
} else if (subscene === "level_selection") {
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (selectedLevel + 1 <= 22)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
newSelectedLevelIdx: selectedLevel + 1,
|
||||
};
|
||||
if (currentSite === "a") {
|
||||
if (selectedLevel + 1 <= 22)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
newSelectedLevelIdx: selectedLevel + 1,
|
||||
};
|
||||
} else if (currentSite === "b") {
|
||||
if (selectedLevel + 1 <= 13)
|
||||
return {
|
||||
event: `level_selection_up`,
|
||||
newSelectedLevelIdx: selectedLevel + 1,
|
||||
};
|
||||
}
|
||||
break;
|
||||
case "DOWN":
|
||||
if (selectedLevel - 1 >= 0)
|
||||
if (selectedLevel - 1 >= 1)
|
||||
return {
|
||||
event: `level_selection_down`,
|
||||
newSelectedLevelIdx: selectedLevel - 1,
|
||||
|
@ -137,6 +157,7 @@ const handleMainSceneEvent = (gameContext: any) => {
|
|||
siteRotY: siteRotY,
|
||||
sitePosY: sitePosY,
|
||||
gameProgress: gameProgress,
|
||||
currentSite: currentSite,
|
||||
});
|
||||
|
||||
if (level === selectedLevel) break;
|
||||
|
|
|
@ -1,56 +1,68 @@
|
|||
const handleMediaSceneEvent = (gameContext: any) => {
|
||||
const keyPress = gameContext.keyPress;
|
||||
const activeMediaComponent = gameContext.activeMediaComponent;
|
||||
let newWordPosStateIdx = gameContext.wordPosStateIdx;
|
||||
let newRightSideComponentIdx = gameContext.rightSideComponentIdx;
|
||||
|
||||
const wordPosStateIdx = gameContext.wordPosStateIdx;
|
||||
const rightSideComponentIdx = gameContext.rightSideComponentIdx;
|
||||
|
||||
const rightSideComponents = ["fstWord", "sndWord", "thirdWord"];
|
||||
if (rightSideComponents.includes(activeMediaComponent)) {
|
||||
switch (keyPress) {
|
||||
case "DOWN":
|
||||
newWordPosStateIdx++;
|
||||
if (newWordPosStateIdx > 6) {
|
||||
newWordPosStateIdx = 1;
|
||||
}
|
||||
newRightSideComponentIdx++;
|
||||
if (newRightSideComponentIdx > 2) {
|
||||
newRightSideComponentIdx = 0;
|
||||
}
|
||||
return {
|
||||
event: `${activeMediaComponent}_down`,
|
||||
newWordPosStateIdx: newWordPosStateIdx,
|
||||
newRightSideComponentIdx: newRightSideComponentIdx,
|
||||
};
|
||||
case "UP":
|
||||
newWordPosStateIdx--;
|
||||
if (newWordPosStateIdx < 1) {
|
||||
newWordPosStateIdx = 6;
|
||||
}
|
||||
newRightSideComponentIdx--;
|
||||
if (newRightSideComponentIdx < 0) {
|
||||
newRightSideComponentIdx = 2;
|
||||
}
|
||||
return {
|
||||
event: `${activeMediaComponent}_up`,
|
||||
newWordPosStateIdx: newWordPosStateIdx,
|
||||
newRightSideComponentIdx: newRightSideComponentIdx,
|
||||
};
|
||||
case "RIGHT":
|
||||
case "LEFT":
|
||||
return { event: `${activeMediaComponent}_${keyPress.toLowerCase()}` };
|
||||
case "CIRCLE":
|
||||
return { event: `${activeMediaComponent}_select` };
|
||||
}
|
||||
} else {
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
case "RIGHT":
|
||||
case "LEFT":
|
||||
return { event: `${activeMediaComponent}_${keyPress.toLowerCase()}` };
|
||||
case "CIRCLE":
|
||||
return { event: `${activeMediaComponent}_select` };
|
||||
|
||||
const calculateNewRightSide = (
|
||||
direction: string,
|
||||
wordPosStateIdx: number,
|
||||
rightSideComponentIdx: number
|
||||
) => {
|
||||
if (direction === "UP") {
|
||||
wordPosStateIdx--;
|
||||
if (wordPosStateIdx < 1) {
|
||||
wordPosStateIdx = 6;
|
||||
}
|
||||
rightSideComponentIdx--;
|
||||
if (rightSideComponentIdx < 0) {
|
||||
rightSideComponentIdx = 2;
|
||||
}
|
||||
} else if (direction === "DOWN") {
|
||||
wordPosStateIdx++;
|
||||
if (wordPosStateIdx > 6) {
|
||||
wordPosStateIdx = 1;
|
||||
}
|
||||
rightSideComponentIdx++;
|
||||
if (rightSideComponentIdx > 2) {
|
||||
rightSideComponentIdx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
newWordPosStateIdx: wordPosStateIdx,
|
||||
newRightSideComponentIdx: rightSideComponentIdx,
|
||||
};
|
||||
};
|
||||
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
case "DOWN":
|
||||
case "RIGHT":
|
||||
case "LEFT":
|
||||
if (rightSideComponents.includes(activeMediaComponent)) {
|
||||
const newRightSide = calculateNewRightSide(
|
||||
keyPress,
|
||||
wordPosStateIdx,
|
||||
rightSideComponentIdx
|
||||
);
|
||||
return {
|
||||
event: `media_rightside_${keyPress.toLowerCase()}`,
|
||||
newRightSideComponentIdx: newRightSide.newRightSideComponentIdx,
|
||||
newWordPosStateIdx: newRightSide.newWordPosStateIdx,
|
||||
};
|
||||
} else {
|
||||
const newLeftSideComponentIdx = keyPress === "UP" ? 0 : 1;
|
||||
return {
|
||||
event: `media_leftside_${keyPress.toLowerCase()}`,
|
||||
newLeftSideComponentIdx: newLeftSideComponentIdx,
|
||||
};
|
||||
}
|
||||
case "CIRCLE":
|
||||
return { event: `media_${activeMediaComponent}_select` };
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import node_matrices from "../resources/node_matrices.json";
|
||||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import { SiteType } from "../components/MainScene/Site";
|
||||
import unlocked_nodes from "../resources/initial_progress.json";
|
||||
import level_y_values from "../resources/level_y_values.json";
|
||||
|
@ -12,6 +13,7 @@ type NodeSelectorContext = {
|
|||
siteRotY: number;
|
||||
sitePosY: number;
|
||||
gameProgress: typeof unlocked_nodes;
|
||||
currentSite: string;
|
||||
};
|
||||
|
||||
const hudAssocs = {
|
||||
|
@ -54,9 +56,14 @@ export const getNodeHudId = (nodeMatrixIndices: {
|
|||
`${nodeMatrixIndices.rowIdx}${nodeMatrixIndices.colIdx}` as keyof typeof hudAssocs
|
||||
];
|
||||
|
||||
export const isNodeVisible = (nodeId: string, gameProgress: typeof unlocked_nodes) => {
|
||||
export const isNodeVisible = (
|
||||
nodeId: string,
|
||||
gameProgress: typeof unlocked_nodes,
|
||||
currentSite: string
|
||||
) => {
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
const nodeLevel = nodeId.substr(0, 2);
|
||||
const nodeData = (site_a as SiteType)[nodeLevel][nodeId];
|
||||
const nodeData = (siteData as SiteType)[nodeLevel][nodeId];
|
||||
if (nodeData) {
|
||||
const unlockedBy = nodeData.unlocked_by;
|
||||
|
||||
|
@ -90,7 +97,8 @@ const tryRow = (row: number, triedRows: number[]) => {
|
|||
const findNodeAfterLevelSelection = (
|
||||
gameProgress: typeof unlocked_nodes,
|
||||
targetLevel: number,
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number }
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
currentSite: string
|
||||
) => {
|
||||
let newMatIndices = Object.assign({}, nodeMatrixIndices);
|
||||
|
||||
|
@ -100,7 +108,7 @@ const findNodeAfterLevelSelection = (
|
|||
|
||||
let newNodeId = getNodeId(targetLevel, newMatIndices);
|
||||
|
||||
while (!isNodeVisible(newNodeId, gameProgress)) {
|
||||
while (!isNodeVisible(newNodeId, gameProgress, currentSite)) {
|
||||
if (triedCols.length < 4) {
|
||||
triedCols.push(newMatIndices.colIdx);
|
||||
const colToTry = tryCol(newMatIndices.colIdx, triedCols);
|
||||
|
@ -139,7 +147,8 @@ const findNodeVertical = (
|
|||
direction: string,
|
||||
gameProgress: typeof unlocked_nodes,
|
||||
level: number,
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number }
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
currentSite: string
|
||||
) => {
|
||||
let newNodeId;
|
||||
let newLevel = level;
|
||||
|
@ -157,7 +166,7 @@ const findNodeVertical = (
|
|||
|
||||
newNodeId = getNodeId(newLevel, newMatIndices);
|
||||
|
||||
while (!isNodeVisible(newNodeId, gameProgress)) {
|
||||
while (!isNodeVisible(newNodeId, gameProgress, currentSite)) {
|
||||
if (triedCols.length < 4) {
|
||||
triedCols.push(newMatIndices.colIdx);
|
||||
const colToTry = tryCol(newMatIndices.colIdx, triedCols);
|
||||
|
@ -193,7 +202,7 @@ const findNodeVertical = (
|
|||
|
||||
newNodeId = getNodeId(newLevel, newMatIndices);
|
||||
|
||||
while (!isNodeVisible(newNodeId, gameProgress)) {
|
||||
while (!isNodeVisible(newNodeId, gameProgress, currentSite)) {
|
||||
if (triedCols.length < 4) {
|
||||
triedCols.push(newMatIndices.colIdx);
|
||||
const colToTry = tryCol(newMatIndices.colIdx, triedCols);
|
||||
|
@ -232,7 +241,8 @@ const findNodeHorizontal = (
|
|||
gameProgress: typeof unlocked_nodes,
|
||||
level: number,
|
||||
activeId: string,
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number }
|
||||
nodeMatrixIndices: { matrixIdx: number; rowIdx: number; colIdx: number },
|
||||
currentSite: string
|
||||
) => {
|
||||
let newNodeId;
|
||||
let newMatIndices = Object.assign({}, nodeMatrixIndices);
|
||||
|
@ -253,7 +263,7 @@ const findNodeHorizontal = (
|
|||
|
||||
newNodeId = getNodeId(level, newMatIndices);
|
||||
|
||||
while (!isNodeVisible(newNodeId, gameProgress)) {
|
||||
while (!isNodeVisible(newNodeId, gameProgress, currentSite)) {
|
||||
if (triedRows.length < 3) {
|
||||
triedRows.push(newMatIndices.rowIdx);
|
||||
const rowToTry = tryRow(newMatIndices.rowIdx, triedRows);
|
||||
|
@ -299,7 +309,7 @@ const findNodeHorizontal = (
|
|||
|
||||
newNodeId = getNodeId(level, newMatIndices);
|
||||
|
||||
while (!isNodeVisible(newNodeId, gameProgress)) {
|
||||
while (!isNodeVisible(newNodeId, gameProgress, currentSite)) {
|
||||
if (triedRows.length < 3) {
|
||||
triedRows.push(newMatIndices.rowIdx);
|
||||
const rowToTry = tryRow(newMatIndices.rowIdx, triedRows);
|
||||
|
@ -361,7 +371,8 @@ const nodeSelector = (context: NodeSelectorContext) => {
|
|||
context.gameProgress,
|
||||
context.level,
|
||||
context.activeId,
|
||||
context.nodeMatrixIndices
|
||||
context.nodeMatrixIndices,
|
||||
context.currentSite
|
||||
);
|
||||
|
||||
if (newNodeData) {
|
||||
|
@ -388,7 +399,8 @@ const nodeSelector = (context: NodeSelectorContext) => {
|
|||
move,
|
||||
context.gameProgress,
|
||||
context.level,
|
||||
context.nodeMatrixIndices
|
||||
context.nodeMatrixIndices,
|
||||
context.currentSite
|
||||
);
|
||||
|
||||
if (newNodeData) {
|
||||
|
@ -411,7 +423,8 @@ const nodeSelector = (context: NodeSelectorContext) => {
|
|||
newNodeData = findNodeAfterLevelSelection(
|
||||
context.gameProgress,
|
||||
context.level,
|
||||
context.nodeMatrixIndices
|
||||
context.nodeMatrixIndices,
|
||||
context.currentSite
|
||||
);
|
||||
|
||||
if (newNodeData) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,13 +1,12 @@
|
|||
import { a } from "@react-spring/three";
|
||||
import { OrbitControls } from "@react-three/drei";
|
||||
import React, { Suspense, useEffect } from "react";
|
||||
import React, { Suspense } from "react";
|
||||
import Site from "../components/MainScene/Site";
|
||||
import Lain from "../components/MainScene/Lain";
|
||||
import Preloader from "../components/Preloader";
|
||||
import MainSceneIntro from "../components/MainSceneIntro";
|
||||
import GrayPlanes from "../components/MainScene/GrayPlanes";
|
||||
import MiddleRing from "../components/MainScene/MiddleRing";
|
||||
import { useHudStore, useLainStore, useMainSceneStore } from "../store";
|
||||
import { useMainSceneStore } from "../store";
|
||||
import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer";
|
||||
import HUD from "../components/MainScene/HUD";
|
||||
import YellowOrb from "../components/MainScene/YellowOrb";
|
||||
|
@ -22,13 +21,9 @@ const MainScene = () => {
|
|||
|
||||
const isPaused = currentSubscene === "pause";
|
||||
|
||||
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
|
||||
const setActiveNodeHudId = useHudStore((state) => state.setId);
|
||||
|
||||
return (
|
||||
<perspectiveCamera position-z={3}>
|
||||
<a.perspectiveCamera position-z={3}>
|
||||
<Suspense fallback={null}>
|
||||
{/*<MainSceneIntro />*/}
|
||||
<a.group>
|
||||
<Preloader />
|
||||
<Site />
|
||||
|
@ -39,9 +34,9 @@ const MainScene = () => {
|
|||
<YellowOrb visible={!isPaused} />
|
||||
<GrayPlanes visible={!isPaused} />
|
||||
<MiddleRing />
|
||||
<LevelSelection />
|
||||
<LevelSelection visible={!isPaused} />
|
||||
<Pause visible={isPaused} />
|
||||
<Starfield visible={!isPaused}/>
|
||||
<Starfield visible={!isPaused} />
|
||||
<OrbitControls />
|
||||
<pointLight color={0xffffff} position={[0, 0, 7]} intensity={1} />
|
||||
<pointLight color={0x7f7f7f} position={[0, 10, 0]} intensity={1.5} />
|
||||
|
@ -50,7 +45,7 @@ const MainScene = () => {
|
|||
</a.group>
|
||||
<Lain />
|
||||
</Suspense>
|
||||
</perspectiveCamera>
|
||||
</a.perspectiveCamera>
|
||||
);
|
||||
};
|
||||
export default MainScene;
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import {
|
||||
useLevelSelectionStore,
|
||||
useLevelStore,
|
||||
useMediaStore,
|
||||
useNodeStore,
|
||||
} from "../store";
|
||||
import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer";
|
||||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import {useLevelStore, useMediaStore, useNodeStore, useSiteStore} from "../store";
|
||||
import LeftSide from "../components/MediaScene/Selectables/LeftSide";
|
||||
import RightSide from "../components/MediaScene/Selectables/RightSide";
|
||||
import AudioVisualizer from "../components/MediaScene/AudioVisualizer/AudioVisualizer";
|
||||
|
@ -14,13 +8,13 @@ import NodeNameContainer from "../components/MediaScene/NodeNameContainer";
|
|||
import Lof from "../components/MediaScene/Lof";
|
||||
import { OrbitControls } from "@react-three/drei";
|
||||
import Images from "../components/MediaScene/Images";
|
||||
import YellowTextRenderer from "../components/TextRenderer/YellowTextRenderer";
|
||||
import MediumLetter from "../components/TextRenderer/MediumLetter";
|
||||
import site_a from "../resources/site_a.json";
|
||||
import { SiteType } from "../components/MainScene/Site";
|
||||
import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator";
|
||||
import site_b from "../resources/site_b.json";
|
||||
|
||||
const MediaScene = () => {
|
||||
const [textVisible, setTextVisible] = useState(false);
|
||||
const mediaComponentMatrixIndices = useMediaStore(
|
||||
(state) => state.componentMatrixIndices
|
||||
);
|
||||
|
@ -28,7 +22,11 @@ const MediaScene = () => {
|
|||
const activeNodeId = useNodeStore((state) => state.activeNodeState.id);
|
||||
const activeLevel = useLevelStore((state) => state.activeLevel);
|
||||
|
||||
const activeNodeData = (site_a as SiteType)[activeLevel][activeNodeId];
|
||||
const currentSite = useSiteStore((state) => state.currentSite);
|
||||
|
||||
const siteData = currentSite === "a" ? site_a : site_b;
|
||||
|
||||
const activeNodeData = (siteData as SiteType)[activeLevel][activeNodeId];
|
||||
const activeNodeName = activeNodeData.node_name;
|
||||
const activeNodeMedia = activeNodeData.media_file;
|
||||
|
||||
|
@ -47,13 +45,6 @@ const MediaScene = () => {
|
|||
useEffect(() => {
|
||||
document.getElementsByTagName("canvas")[0].className =
|
||||
"media-scene-background";
|
||||
setTimeout(() => {
|
||||
setTextVisible(true);
|
||||
}, 800);
|
||||
|
||||
return () => {
|
||||
setTextVisible(false);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
@ -72,9 +63,7 @@ const MediaScene = () => {
|
|||
))}
|
||||
</group>
|
||||
|
||||
<group position={[0, 0, 0]} visible={textVisible}>
|
||||
<YellowTextRenderer />
|
||||
</group>
|
||||
<MediaYellowTextAnimator />
|
||||
{activeNodeMedia.includes("XA") ? (
|
||||
<>
|
||||
<AudioVisualizer />
|
||||
|
|
37
src/store.ts
37
src/store.ts
|
@ -159,13 +159,42 @@ type MainSceneState = {
|
|||
setSubscene: (to: string) => void;
|
||||
};
|
||||
|
||||
export type MediaBigTextState = {
|
||||
text: string;
|
||||
transformState: {
|
||||
posX: number;
|
||||
posY: number;
|
||||
xOffset: number;
|
||||
};
|
||||
};
|
||||
|
||||
export const useMediaBigTextStore = create(
|
||||
combine(
|
||||
{
|
||||
transformState: {
|
||||
posX: -0.8,
|
||||
posY: 0.05,
|
||||
xOffset: 0,
|
||||
},
|
||||
text: "Play",
|
||||
} as MediaBigTextState,
|
||||
(set) => ({
|
||||
setText: (to: string) => set(() => ({ text: to })),
|
||||
setTransformState: (to: number, at: string) =>
|
||||
set((state) => ({
|
||||
transformState: { ...state.transformState, [at]: to },
|
||||
})),
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
export const useBigTextStore = create(
|
||||
combine(
|
||||
{
|
||||
visible: true,
|
||||
color: "yellow",
|
||||
disableTrail: false,
|
||||
text: "Play",
|
||||
text: "",
|
||||
transformState: {
|
||||
posX: 0,
|
||||
posY: 0,
|
||||
|
@ -270,7 +299,7 @@ export const useStarfieldStore = create<StarfieldState>((set) => ({
|
|||
export const useSiteStore = create(
|
||||
combine(
|
||||
{
|
||||
currentSite: "a",
|
||||
currentSite: "b",
|
||||
transformState: {
|
||||
posY: 0,
|
||||
rotY: 0,
|
||||
|
@ -341,11 +370,11 @@ export const useMediaStore = create(
|
|||
sideIdx: Number(!state.componentMatrixIndices.sideIdx),
|
||||
},
|
||||
})),
|
||||
toggleLeftComponent: () =>
|
||||
setLeftComponentMatrixIdx: (to: number) =>
|
||||
set((state) => ({
|
||||
componentMatrixIndices: {
|
||||
...state.componentMatrixIndices,
|
||||
leftSideIdx: Number(!state.componentMatrixIndices.leftSideIdx),
|
||||
leftSideIdx: to,
|
||||
},
|
||||
})),
|
||||
setRightComponentMatrixIdx: (to: number) =>
|
||||
|
|
Loading…
Reference in a new issue