added site b

This commit is contained in:
ad044 2020-12-21 20:56:06 +04:00
parent 07cc48ae49
commit ac5edb303f
27 changed files with 7096 additions and 6654 deletions

View file

@ -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}

View file

@ -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>
);
};

View file

@ -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) {

View file

@ -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)) ;
}
}

View file

@ -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}

View file

@ -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]) {

View file

@ -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

View file

@ -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

View 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;

View file

@ -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";

View file

@ -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!} />
</>
);
};

View file

@ -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(

View file

@ -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) {

View file

@ -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;

View 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;

View file

@ -22,7 +22,7 @@ const PauseComponentManager = (props: StateManagerProps) => {
action: setExitAnimation,
value: true,
};
case "toggle_pause":
case "pause_game":
return {
action: setExitAnimation,
value: false,

View file

@ -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 {

View file

@ -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":

View file

@ -23,7 +23,7 @@ const SubsceneManager = (props: StateManagerProps) => {
value: "level_selection",
delay: 0,
};
case "toggle_pause":
case "pause_game":
return {
action: setMainSubscene,
value: "pause",

View file

@ -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,
]

View file

@ -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;

View file

@ -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` };
}
};

View file

@ -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

View file

@ -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;

View file

@ -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 />

View file

@ -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) =>