mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
added prompt, and word selection node not found handling
This commit is contained in:
parent
bc018e964d
commit
8f303e455a
19 changed files with 658 additions and 339 deletions
|
@ -14,92 +14,93 @@ type BootLoadDataProps = {
|
|||
};
|
||||
|
||||
const BootLoadData = (props: BootLoadDataProps) => {
|
||||
const loadDataUnderlineTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
loadDataUnderline
|
||||
);
|
||||
const loadDataQuestionContainerTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
loadDataQuestionContainer
|
||||
);
|
||||
const loadDataAnswerContainerTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
loadDataAnswerContainer
|
||||
);
|
||||
const areYouSureTex = useLoader(THREE.TextureLoader, areYouSure);
|
||||
const yesTex = useLoader(THREE.TextureLoader, yes);
|
||||
const noTex = useLoader(THREE.TextureLoader, no);
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.visible ? (
|
||||
<>
|
||||
<sprite scale={[4.1, 0.3, 0]} renderOrder={2} position={[0, 0.2, 0]}>
|
||||
<spriteMaterial
|
||||
map={loadDataQuestionContainerTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
opacity={0.6}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite scale={[2, 0.24, 0]} renderOrder={3} position={[0, 0.19, 0]}>
|
||||
<spriteMaterial
|
||||
map={areYouSureTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[0.5, 0.19, 0]}
|
||||
renderOrder={3}
|
||||
position={[-1.2, -0.2, 0]}
|
||||
>
|
||||
<spriteMaterial map={yesTex} attach="material" transparent={true} />
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[0.7, 0.3, 0]}
|
||||
renderOrder={2}
|
||||
position={
|
||||
props.activeBootElement === "load_data_yes"
|
||||
? [-1.2, -0.2, 0]
|
||||
: [1.2, -0.2, 0]
|
||||
}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={loadDataAnswerContainerTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[0.4, 0.19, 0]}
|
||||
renderOrder={3}
|
||||
position={[1.2, -0.2, 0]}
|
||||
>
|
||||
<spriteMaterial map={noTex} attach="material" transparent={true} />
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[3.5, 0.01, 0]}
|
||||
position={[-0.5, -1.15, 0]}
|
||||
renderOrder={2}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={loadDataUnderlineTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
/>
|
||||
</sprite>
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
// const loadDataUnderlineTex = useLoader(
|
||||
// THREE.TextureLoader,
|
||||
// loadDataUnderline
|
||||
// );
|
||||
// const loadDataQuestionContainerTex = useLoader(
|
||||
// THREE.TextureLoader,
|
||||
// loadDataQuestionContainer
|
||||
// );
|
||||
// const loadDataAnswerContainerTex = useLoader(
|
||||
// THREE.TextureLoader,
|
||||
// loadDataAnswerContainer
|
||||
// );
|
||||
// const areYouSureTex = useLoader(THREE.TextureLoader, areYouSure);
|
||||
// const yesTex = useLoader(THREE.TextureLoader, yes);
|
||||
// const noTex = useLoader(THREE.TextureLoader, no);
|
||||
//
|
||||
// return (
|
||||
// <>
|
||||
// {props.visible ? (
|
||||
// <>
|
||||
// <sprite scale={[4.1, 0.3, 0]} renderOrder={2} position={[0, 0.2, 0]}>
|
||||
// <spriteMaterial
|
||||
// map={loadDataQuestionContainerTex}
|
||||
// attach="material"
|
||||
// transparent={true}
|
||||
// opacity={0.6}
|
||||
// />
|
||||
// </sprite>
|
||||
//
|
||||
// <sprite scale={[2, 0.24, 0]} renderOrder={3} position={[0, 0.19, 0]}>
|
||||
// <spriteMaterial
|
||||
// map={areYouSureTex}
|
||||
// attach="material"
|
||||
// transparent={true}
|
||||
// />
|
||||
// </sprite>
|
||||
//
|
||||
// <sprite
|
||||
// scale={[0.5, 0.19, 0]}
|
||||
// renderOrder={3}
|
||||
// position={[-1.2, -0.2, 0]}
|
||||
// >
|
||||
// <spriteMaterial map={yesTex} attach="material" transparent={true} />
|
||||
// </sprite>
|
||||
//
|
||||
// <sprite
|
||||
// scale={[0.7, 0.3, 0]}
|
||||
// renderOrder={2}
|
||||
// position={
|
||||
// props.activeBootElement === "load_data_yes"
|
||||
// ? [-1.2, -0.2, 0]
|
||||
// : [1.2, -0.2, 0]
|
||||
// }
|
||||
// >
|
||||
// <spriteMaterial
|
||||
// map={loadDataAnswerContainerTex}
|
||||
// attach="material"
|
||||
// transparent={true}
|
||||
// />
|
||||
// </sprite>
|
||||
//
|
||||
// <sprite
|
||||
// scale={[0.4, 0.19, 0]}
|
||||
// renderOrder={3}
|
||||
// position={[1.2, -0.2, 0]}
|
||||
// >
|
||||
// <spriteMaterial map={noTex} attach="material" transparent={true} />
|
||||
// </sprite>
|
||||
//
|
||||
// <sprite
|
||||
// scale={[3.5, 0.01, 0]}
|
||||
// position={[-0.5, -1.15, 0]}
|
||||
// renderOrder={2}
|
||||
// >
|
||||
// <spriteMaterial
|
||||
// map={loadDataUnderlineTex}
|
||||
// attach="material"
|
||||
// transparent={true}
|
||||
// />
|
||||
// </sprite>
|
||||
// </>
|
||||
// ) : (
|
||||
// <></>
|
||||
// )}
|
||||
// </>
|
||||
// );
|
||||
return <></>;
|
||||
};
|
||||
|
||||
export default BootLoadData;
|
||||
|
|
|
@ -22,6 +22,7 @@ import handleMainSceneEvent from "../core/scene-keypress-handlers/handleMainKeyP
|
|||
import gameLoader from "../core/setters/gameLoader";
|
||||
import gameSaver from "../core/setters/gameSaver";
|
||||
import progressManager from "../core/setters/progressManager";
|
||||
import promptManager from "../core/setters/promptManager";
|
||||
|
||||
const KeyPressHandler = () => {
|
||||
const mediaSceneSetters = useMemo(
|
||||
|
@ -32,6 +33,7 @@ const KeyPressHandler = () => {
|
|||
levelManager,
|
||||
siteManager,
|
||||
progressManager,
|
||||
mainSubsceneManager,
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
@ -52,6 +54,7 @@ const KeyPressHandler = () => {
|
|||
gameLoader,
|
||||
gameSaver,
|
||||
progressManager,
|
||||
promptManager,
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
@ -92,6 +95,7 @@ const KeyPressHandler = () => {
|
|||
};
|
||||
case "gate":
|
||||
case "polytan":
|
||||
case "about":
|
||||
return {
|
||||
action: () => useStore.setState({ currentScene: "main" }),
|
||||
};
|
||||
|
|
|
@ -130,6 +130,7 @@ const HUD = memo(() => {
|
|||
if (
|
||||
!(scene === "main" && prevData?.scene === "main") ||
|
||||
(subscene === "site" && prevData?.subscene === "pause") ||
|
||||
(subscene === "site" && prevData?.subscene === "not_found") ||
|
||||
subscene === "pause"
|
||||
) {
|
||||
// set to final pos instantly
|
||||
|
|
48
src/components/MainScene/NotFound.tsx
Normal file
48
src/components/MainScene/NotFound.tsx
Normal file
|
@ -0,0 +1,48 @@
|
|||
import React from "react";
|
||||
import notFound from "../../static/sprite/not_found.png";
|
||||
import notFoundLof from "../../static/sprite/not_found_lof.png";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
type NotFoundProps = {
|
||||
visible: boolean;
|
||||
};
|
||||
|
||||
const NotFound = (props: NotFoundProps) => {
|
||||
const notFoundTex = useLoader(THREE.TextureLoader, notFound);
|
||||
const notFoundLofTex = useLoader(THREE.TextureLoader, notFoundLof);
|
||||
|
||||
return (
|
||||
<>
|
||||
{props.visible && (
|
||||
<>
|
||||
<sprite
|
||||
scale={[1, 0.25, 0]}
|
||||
renderOrder={106}
|
||||
position={[-1, -0.05, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={notFoundLofTex}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[4.1, 0.6, 0]}
|
||||
renderOrder={105}
|
||||
position={[0, -0.15, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={notFoundTex}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default NotFound;
|
41
src/components/MainScene/PauseSubscene/About.tsx
Normal file
41
src/components/MainScene/PauseSubscene/About.tsx
Normal file
|
@ -0,0 +1,41 @@
|
|||
import React, { useRef } from "react";
|
||||
import aboutBg from "../../../static/sprite/about_background.png";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { useStore } from "../../../store";
|
||||
|
||||
const About = () => {
|
||||
const setShowingAbout = useStore((state) => state.setShowingAbout);
|
||||
const aboutBgTex = useLoader(THREE.TextureLoader, aboutBg);
|
||||
|
||||
const bgRef = useRef<THREE.Sprite>();
|
||||
// todo im not sure where the other bg file is located,
|
||||
// the one here is just the text, in the original game there's another one
|
||||
|
||||
useFrame(() => {
|
||||
if (bgRef.current) {
|
||||
bgRef.current.position.y += 0.03;
|
||||
if (Math.round(bgRef.current.position.y) === 14) {
|
||||
setShowingAbout(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<sprite renderOrder={199} scale={[100, 100, 0]}>
|
||||
<spriteMaterial attach="material" color={0x000000} depthTest={false} />
|
||||
</sprite>
|
||||
<sprite
|
||||
ref={bgRef}
|
||||
scale={[10.5 / 2.5, 52.8 / 2.5, 0]}
|
||||
position={[1.1, -13, 0]}
|
||||
renderOrder={200}
|
||||
>
|
||||
<spriteMaterial attach="material" map={aboutBgTex} depthTest={false} />
|
||||
</sprite>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default About;
|
|
@ -4,9 +4,12 @@ import PauseSquare from "./PauseSquare";
|
|||
import StaticBigLetter from "../../TextRenderer/StaticBigLetter";
|
||||
import { useStore } from "../../../store";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import About from "./About";
|
||||
import Prompt from "../../Prompt";
|
||||
|
||||
const Pause = () => {
|
||||
const exit = useStore((state) => state.pauseExitAnimation);
|
||||
const showingAbout = useStore((state) => state.showingAbout);
|
||||
const [showActiveComponent, setShowActiveComponent] = useState(false);
|
||||
const [animation, setAnimation] = useState(false);
|
||||
const [intro, setIntro] = useState(true);
|
||||
|
@ -274,7 +277,6 @@ const Pause = () => {
|
|||
active={activeComponent === "load"}
|
||||
/>
|
||||
))}
|
||||
|
||||
{"About".split("").map((letter, idx) => (
|
||||
<StaticBigLetter
|
||||
color={idx > 0 ? "yellow" : "orange"}
|
||||
|
@ -286,7 +288,6 @@ const Pause = () => {
|
|||
key={idx}
|
||||
/>
|
||||
))}
|
||||
|
||||
{"Change".split("").map((letter, idx) => (
|
||||
<StaticBigLetter
|
||||
color={idx > 0 ? "yellow" : "orange"}
|
||||
|
@ -298,7 +299,6 @@ const Pause = () => {
|
|||
key={idx}
|
||||
/>
|
||||
))}
|
||||
|
||||
{"Save".split("").map((letter, idx) => (
|
||||
<StaticBigLetter
|
||||
color={idx > 0 ? "yellow" : "orange"}
|
||||
|
@ -310,7 +310,6 @@ const Pause = () => {
|
|||
key={idx}
|
||||
/>
|
||||
))}
|
||||
|
||||
{"Exit".split("").map((letter, idx) => (
|
||||
<StaticBigLetter
|
||||
color={idx > 0 ? "yellow" : "orange"}
|
||||
|
@ -322,7 +321,6 @@ const Pause = () => {
|
|||
active={activeComponent === "exit"}
|
||||
/>
|
||||
))}
|
||||
|
||||
<group visible={!exit}>
|
||||
<sprite
|
||||
position={[0.5, -0.8, 0]}
|
||||
|
@ -353,6 +351,10 @@ const Pause = () => {
|
|||
/>
|
||||
</mesh>
|
||||
</group>
|
||||
{showingAbout && <About />}
|
||||
<group position={[1, 0.6, 0]} scale={[1.2, 1.2, 0]}>
|
||||
<Prompt />
|
||||
</group>
|
||||
</group>
|
||||
)}
|
||||
</>
|
||||
|
|
110
src/components/Prompt.tsx
Normal file
110
src/components/Prompt.tsx
Normal file
|
@ -0,0 +1,110 @@
|
|||
import React, { useCallback, useEffect } from "react";
|
||||
import answerContainer from "../static/sprite/prompt_answer_container.png";
|
||||
import questionContainer from "../static/sprite/prompt_question_container.png";
|
||||
import yes from "../static/sprite/prompt_yes.png";
|
||||
import no from "../static/sprite/prompt_no.png";
|
||||
import question from "../static/sprite/prompt_question.png";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { useStore } from "../store";
|
||||
|
||||
const Prompt = () => {
|
||||
const promptVisible = useStore((state) => state.promptVisible);
|
||||
|
||||
const questionContainerTex = useLoader(
|
||||
THREE.TextureLoader,
|
||||
questionContainer
|
||||
);
|
||||
const answerContainerTex = useLoader(THREE.TextureLoader, answerContainer);
|
||||
const questionTex = useLoader(THREE.TextureLoader, question);
|
||||
const yesTex = useLoader(THREE.TextureLoader, yes);
|
||||
const noTex = useLoader(THREE.TextureLoader, no);
|
||||
|
||||
const activeComponent = useStore(
|
||||
useCallback(
|
||||
(state) => state.promptComponentMatrix[state.promptComponentMatrixIdx],
|
||||
[]
|
||||
)
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
console.log(promptVisible);
|
||||
}, [promptVisible]);
|
||||
return (
|
||||
<>
|
||||
{promptVisible && (
|
||||
<>
|
||||
<sprite
|
||||
scale={[4.1, 0.3, 0]}
|
||||
renderOrder={200}
|
||||
position={[0, 0.2, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={questionContainerTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
opacity={0.6}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[2, 0.24, 0]}
|
||||
renderOrder={200}
|
||||
position={[0, 0.19, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={questionTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[0.5, 0.19, 0]}
|
||||
renderOrder={200}
|
||||
position={[-1.2, -0.2, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={yesTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[0.7, 0.3, 0]}
|
||||
renderOrder={199}
|
||||
position={
|
||||
activeComponent === "yes" ? [-1.2, -0.2, 0] : [1.2, -0.2, 0]
|
||||
}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={answerContainerTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
|
||||
<sprite
|
||||
scale={[0.4, 0.19, 0]}
|
||||
renderOrder={200}
|
||||
position={[1.2, -0.2, 0]}
|
||||
>
|
||||
<spriteMaterial
|
||||
map={noTex}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</sprite>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Prompt;
|
|
@ -100,6 +100,7 @@ const BigLetter = memo((props: { letter: string; letterIdx: number }) => {
|
|||
useEffect(() => {
|
||||
if (
|
||||
subscene === "pause" ||
|
||||
(subscene === "site" && prevData?.subscene === "not_found") ||
|
||||
(subscene === "site" && prevData?.subscene === "pause")
|
||||
)
|
||||
return;
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useStore } from "../../store";
|
|||
import { a, useTrail } from "@react-spring/three";
|
||||
import BigLetter from "./BigLetter";
|
||||
import usePrevious from "../../hooks/usePrevious";
|
||||
import {getNodeHud} from "../../utils/node-utils";
|
||||
import { getNodeHud } from "../../utils/node-utils";
|
||||
|
||||
const YellowTextRenderer = (props: { visible?: boolean }) => {
|
||||
const activeNode = useStore((state) => state.activeNode);
|
||||
|
@ -22,6 +22,7 @@ const YellowTextRenderer = (props: { visible?: boolean }) => {
|
|||
|
||||
useEffect(() => {
|
||||
const hud = getNodeHud(activeNode.matrixIndices!);
|
||||
|
||||
if (subscene === "level_selection") {
|
||||
setTimeout(() => {
|
||||
set({ posX: -0.02, posY: 0.005 });
|
||||
|
|
|
@ -18,8 +18,29 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
|
|||
level,
|
||||
keyPress,
|
||||
ssknLvl,
|
||||
showingAbout,
|
||||
promptVisible,
|
||||
activePromptComponent,
|
||||
} = mainSceneContext;
|
||||
|
||||
if (promptVisible) {
|
||||
switch (keyPress) {
|
||||
case "LEFT":
|
||||
return { event: "prompt_left" };
|
||||
case "RIGHT":
|
||||
return { event: "prompt_right" };
|
||||
case "CIRCLE":
|
||||
switch (activePromptComponent) {
|
||||
case "no":
|
||||
return { event: "exit_prompt" };
|
||||
case "yes":
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
site: currentSite,
|
||||
};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (subscene) {
|
||||
case "site":
|
||||
switch (keyPress) {
|
||||
|
@ -108,7 +129,10 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
|
|||
|
||||
const nodeType = activeNode.type;
|
||||
|
||||
if (activeNode.id === "" || !isNodeVisible(activeNode, gameProgress))
|
||||
if (
|
||||
activeNode.id === "" ||
|
||||
!isNodeVisible(activeNode, gameProgress)
|
||||
)
|
||||
return;
|
||||
|
||||
if (activeNode.upgrade_requirement > ssknLvl) {
|
||||
|
@ -266,6 +290,11 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
|
|||
}
|
||||
break;
|
||||
case "pause":
|
||||
if (showingAbout)
|
||||
return {
|
||||
event: "exit_about",
|
||||
};
|
||||
else {
|
||||
switch (keyPress) {
|
||||
case "UP":
|
||||
if (pauseMatrixIdx - 1 < 0) break;
|
||||
|
@ -280,12 +309,18 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
|
|||
pauseMatrixIdx: pauseMatrixIdx + 1,
|
||||
};
|
||||
case "CIRCLE":
|
||||
if (activePauseComponent === "change") {
|
||||
return {
|
||||
event: `pause_${activePauseComponent}_select`,
|
||||
site: currentSite,
|
||||
event: "display_prompt",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "not_found":
|
||||
return { event: "exit_not_found" };
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default handleMainSceneEvent;
|
||||
|
|
|
@ -8,6 +8,7 @@ const handleMediaKeyPress = (mediaSceneContext: any) => {
|
|||
rightSideComponentIdx,
|
||||
activeNode,
|
||||
activeSite,
|
||||
gameProgress,
|
||||
} = mediaSceneContext;
|
||||
|
||||
const calculateNewRightSide = (
|
||||
|
@ -72,14 +73,14 @@ const handleMediaKeyPress = (mediaSceneContext: any) => {
|
|||
const data = findNodeFromWord(
|
||||
activeMediaComponent,
|
||||
activeNode,
|
||||
activeSite
|
||||
activeSite,
|
||||
gameProgress
|
||||
);
|
||||
|
||||
if (data) {
|
||||
return { event: `media_${activeMediaComponent}_select`, ...data };
|
||||
} else {
|
||||
// todo in case node isnt unlocked yet
|
||||
return;
|
||||
return { event: `word_node_not_found` };
|
||||
}
|
||||
default:
|
||||
if (activeMediaComponent === "play") {
|
||||
|
|
|
@ -5,9 +5,15 @@ const mainSubsceneManager = (eventState: any) => {
|
|||
|
||||
const dispatchAction = (eventState: { event: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "word_node_not_found":
|
||||
return {
|
||||
action: () => setMainSubscene("not_found"),
|
||||
delay: 0,
|
||||
};
|
||||
case "level_selection_back":
|
||||
case "select_level_up":
|
||||
case "select_level_down":
|
||||
case "exit_not_found":
|
||||
return {
|
||||
action: () => setMainSubscene("site"),
|
||||
delay: 0,
|
||||
|
|
|
@ -5,6 +5,7 @@ type PauseManagerProps = { event: string; pauseMatrixIdx: number };
|
|||
const pauseManager = (eventState: any) => {
|
||||
const setComponentMatrixIdx = useStore.getState().setPauseComponentMatrixIdx;
|
||||
const setExitAnimation = useStore.getState().setPauseExitAnimation;
|
||||
const setShowingAbout = useStore.getState().setShowingAbout;
|
||||
|
||||
const dispatchAction = (eventState: PauseManagerProps) => {
|
||||
switch (eventState.event) {
|
||||
|
@ -17,6 +18,14 @@ const pauseManager = (eventState: any) => {
|
|||
return {
|
||||
action: () => setExitAnimation(true),
|
||||
};
|
||||
case "pause_about_select":
|
||||
return {
|
||||
action: () => setShowingAbout(true),
|
||||
};
|
||||
case "exit_about":
|
||||
return {
|
||||
action: () => setShowingAbout(false),
|
||||
};
|
||||
case "pause_game":
|
||||
return { action: () => setExitAnimation(false) };
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { useStore } from "../../../store";
|
||||
import { useCallback } from "react";
|
||||
import * as THREE from "three";
|
||||
|
||||
const mediaManager = (eventState: any) => {
|
||||
|
|
32
src/core/setters/promptManager.ts
Normal file
32
src/core/setters/promptManager.ts
Normal file
|
@ -0,0 +1,32 @@
|
|||
import { useStore } from "../../store";
|
||||
|
||||
const promptManager = (eventState: any) => {
|
||||
const setComponentMatrixIdx = useStore.getState().setPromptComponentMatrixIdx;
|
||||
const setPromptVisible = useStore.getState().setPromptVisible;
|
||||
|
||||
const dispatchAction = (eventState: { event: string; scene: string }) => {
|
||||
switch (eventState.event) {
|
||||
case "display_prompt": {
|
||||
return { action: () => setPromptVisible(true) };
|
||||
}
|
||||
case "prompt_right":
|
||||
return {
|
||||
action: () => setComponentMatrixIdx(1),
|
||||
};
|
||||
case "prompt_left":
|
||||
return { action: () => setComponentMatrixIdx(0) };
|
||||
case "pause_change_select":
|
||||
return { action: () => setPromptVisible(false) };
|
||||
case "exit_prompt":
|
||||
return { action: () => setPromptVisible(false) };
|
||||
}
|
||||
};
|
||||
|
||||
const { action } = { ...dispatchAction(eventState) };
|
||||
|
||||
if (action) {
|
||||
action();
|
||||
}
|
||||
};
|
||||
|
||||
export default promptManager;
|
|
@ -52,6 +52,7 @@ const sceneManager = (eventState: any) => {
|
|||
case "media_fstWord_select":
|
||||
case "media_sndWord_select":
|
||||
case "media_thirdWord_select":
|
||||
case "word_node_not_found":
|
||||
return {
|
||||
action: () =>
|
||||
useStore.setState({ currentScene: "main", intro: false }),
|
||||
|
|
|
@ -13,6 +13,7 @@ import Site from "../components/MainScene/Site";
|
|||
import Lain from "../components/MainScene/Lain";
|
||||
import * as THREE from "three";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import NotFound from "../components/MainScene/NotFound";
|
||||
|
||||
const MainScene = () => {
|
||||
const intro = useStore((state) => state.intro);
|
||||
|
@ -94,10 +95,13 @@ const MainScene = () => {
|
|||
<Suspense fallback={null}>
|
||||
<LevelSelection />
|
||||
<Pause />
|
||||
<NotFound visible={subscene === "not_found"} />
|
||||
<group visible={!paused}>
|
||||
<group visible={!wordSelected && (intro ? introFinished : true)}>
|
||||
<group visible={subscene !== "not_found"}>
|
||||
<HUD />
|
||||
<YellowTextRenderer />
|
||||
</group>
|
||||
<MiddleRing />
|
||||
<GrayPlanes />
|
||||
</group>
|
||||
|
|
23
src/store.ts
23
src/store.ts
|
@ -44,6 +44,7 @@ type State = {
|
|||
pauseComponentMatrix: ["load", "about", "change", "save", "exit"];
|
||||
pauseComponentMatrixIdx: number;
|
||||
pauseExitAnimation: boolean;
|
||||
showingAbout: boolean;
|
||||
|
||||
// media/media scene
|
||||
audioAnalyser: undefined | THREE.AudioAnalyser;
|
||||
|
@ -98,6 +99,11 @@ type State = {
|
|||
// end scene
|
||||
endMediaPlayedCount: number;
|
||||
|
||||
// prompt
|
||||
promptVisible: boolean;
|
||||
promptComponentMatrix: ["yes", "no"];
|
||||
promptComponentMatrixIdx: 1 | 0;
|
||||
|
||||
// save state
|
||||
siteSaveState: {
|
||||
a: {
|
||||
|
@ -188,6 +194,7 @@ export const useStore = create(
|
|||
pauseComponentMatrix: ["load", "about", "change", "save", "exit"],
|
||||
pauseComponentMatrixIdx: 2,
|
||||
pauseExitAnimation: false,
|
||||
showingAbout: false,
|
||||
|
||||
// media / media scene
|
||||
audioAnalyser: undefined,
|
||||
|
@ -249,6 +256,11 @@ export const useStore = create(
|
|||
// end scene
|
||||
endMediaPlayedCount: 0,
|
||||
|
||||
// prompt
|
||||
promptVisible: false,
|
||||
promptComponentMatrix: ["yes", "no"],
|
||||
promptComponentMatrixIdx: 1,
|
||||
|
||||
// save states for loading the game/changing sites
|
||||
siteSaveState: {
|
||||
a: {
|
||||
|
@ -325,6 +337,7 @@ export const useStore = create(
|
|||
set(() => ({ pauseComponentMatrixIdx: to })),
|
||||
setPauseExitAnimation: (to: boolean) =>
|
||||
set(() => ({ pauseExitAnimation: to })),
|
||||
setShowingAbout: (to: boolean) => set(() => ({ showingAbout: to })),
|
||||
|
||||
// media/media scene setters
|
||||
toggleMediaSide: () =>
|
||||
|
@ -404,6 +417,11 @@ export const useStore = create(
|
|||
})),
|
||||
resetEndMediaPlayedCount: () => set(() => ({ endMediaPlayedCount: 0 })),
|
||||
|
||||
// prompt setters
|
||||
setPromptVisible: (to: boolean) => set(() => ({ promptVisible: to })),
|
||||
setPromptComponentMatrixIdx: (to: 1 | 0) =>
|
||||
set(() => ({ promptComponentMatrixIdx: to })),
|
||||
|
||||
// site state setters
|
||||
setSiteSaveState: (
|
||||
site: string,
|
||||
|
@ -467,6 +485,10 @@ export const getMainSceneContext = () => {
|
|||
activeNode: state.activeNode,
|
||||
level: parseInt(state.activeLevel),
|
||||
ssknLvl: state.ssknLvl,
|
||||
showingAbout: state.showingAbout,
|
||||
promptVisible: state.promptVisible,
|
||||
activePromptComponent:
|
||||
state.promptComponentMatrix[state.promptComponentMatrixIdx],
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -493,5 +515,6 @@ export const getMediaSceneContext = () => {
|
|||
wordPosStateIdx: state.mediaWordPosStateIdx,
|
||||
activeNode: state.activeNode,
|
||||
activeSite: state.activeSite,
|
||||
gameProgress: state.gameProgress,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import site_a from "../resources/site_a.json";
|
||||
import site_b from "../resources/site_b.json";
|
||||
import node_matrices from "../resources/node_matrices.json";
|
||||
import {
|
||||
NodeDataType,
|
||||
SiteType,
|
||||
} from "../components/MainScene/Site";
|
||||
import { NodeDataType, SiteType } from "../components/MainScene/Site";
|
||||
import { isNodeVisible } from "./node-utils";
|
||||
|
||||
export const findNodeFromWord = (
|
||||
wordLabel: string,
|
||||
activeNode: NodeDataType,
|
||||
site: "a" | "b"
|
||||
site: "a" | "b",
|
||||
gameProgress: any
|
||||
) => {
|
||||
const labelToIdx = (() => {
|
||||
switch (wordLabel) {
|
||||
|
@ -41,7 +40,8 @@ export const findNodeFromWord = (
|
|||
) + 1
|
||||
] ?? nodesWithSameWords[0];
|
||||
|
||||
//todo check if visible
|
||||
if (!isNodeVisible(chosenNode, gameProgress)) return;
|
||||
|
||||
const pos = chosenNode.id.substr(2);
|
||||
|
||||
const matrixIndices = Object.entries(node_matrices).flatMap((matrixData) =>
|
||||
|
|
Loading…
Reference in a new issue