pop ups/prompts done, fixed the boot scene

This commit is contained in:
ad044 2021-02-08 21:53:28 +04:00
parent 8a1eedb63d
commit ef3b4ce367
21 changed files with 712 additions and 477 deletions

View file

@ -1,4 +1,4 @@
import React, { useMemo } from "react"; import React, { Suspense, useEffect, useMemo, useRef } from "react";
import authorizeHeaderUnderline from "../../static/sprite/authorize_header_underline.png"; import authorizeHeaderUnderline from "../../static/sprite/authorize_header_underline.png";
import authorizeGlass from "../../static/sprite/authorize_glass.png"; import authorizeGlass from "../../static/sprite/authorize_glass.png";
import authorizeGlassUnderline from "../../static/sprite/authorize_glass_underline.png"; import authorizeGlassUnderline from "../../static/sprite/authorize_glass_underline.png";
@ -9,6 +9,8 @@ import authorizeActiveLetters from "../../static/sprite/authorize_active_letters
import { useLoader } from "react-three-fiber"; import { useLoader } from "react-three-fiber";
import * as THREE from "three"; import * as THREE from "three";
import { OrbitControls } from "@react-three/drei"; import { OrbitControls } from "@react-three/drei";
import { useStore } from "../../store";
import usePrevious from "../../hooks/usePrevious";
type BootAuthorizeUserProps = { type BootAuthorizeUserProps = {
visible: boolean; visible: boolean;
@ -36,28 +38,65 @@ const BootAuthorizeUser = (props: BootAuthorizeUserProps) => {
THREE.TextureLoader, THREE.TextureLoader,
authorizeInactiveLetters authorizeInactiveLetters
); );
const authorizeActiveLettersTex = useLoader( const activeLettersTex = useLoader(
THREE.TextureLoader, THREE.TextureLoader,
authorizeActiveLetters authorizeActiveLetters
); );
const backgroundLettersPos = 1; const letterIdx = useStore((state) => state.authorizeUserLetterIdx);
const activeLetterTextureOffset = 2; const subscene = useStore((state) => state.bootSubscene);
const prevData = usePrevious({ letterIdx, subscene });
const authorizeActiveLettersMap = useMemo(() => { const bgLettersRef = useRef<THREE.Object3D>();
authorizeActiveLettersTex.wrapT = authorizeActiveLettersTex.wrapS = const activeLetterRef = useRef<THREE.Mesh>();
THREE.RepeatWrapping;
authorizeActiveLettersTex.repeat.set(0.06, 0.2);
authorizeActiveLettersTex.offset.x = 1;
authorizeActiveLettersTex.offset.y = 2;
return authorizeActiveLettersTex; const activeLetterMap = useMemo(() => {
}, [activeLetterTextureOffset, authorizeActiveLettersTex]); activeLettersTex.wrapT = activeLettersTex.wrapS = THREE.RepeatWrapping;
activeLettersTex.repeat.set(0.06, 0.2);
activeLettersTex.offset.x = 0;
activeLettersTex.offset.y = -0.2;
return activeLettersTex;
}, [activeLettersTex]);
useEffect(() => {
if (
prevData?.subscene === "main_menu" &&
subscene === "authorize_user" &&
activeLetterRef
) {
activeLetterMap.offset.x = 0;
activeLetterMap.offset.y = -0.2;
}
}, [subscene, prevData?.subscene, activeLetterMap.offset]);
useEffect(() => {
if (bgLettersRef.current) {
//down
if (letterIdx === prevData!.letterIdx + 13) {
bgLettersRef.current.position.y += 0.25;
activeLetterMap.offset.y -= 0.2;
}
// up
else if (letterIdx === prevData!.letterIdx - 13) {
bgLettersRef.current.position.y -= 0.25;
activeLetterMap.offset.y += 0.2;
}
// left
else if (letterIdx === prevData!.letterIdx - 1) {
bgLettersRef.current.position.x += 0.3;
activeLetterMap.offset.x -= 0.0775;
}
// right
else if (letterIdx === prevData!.letterIdx + 1) {
bgLettersRef.current.position.x -= 0.3;
activeLetterMap.offset.x += 0.0775;
}
}
}, [activeLetterMap.offset, letterIdx, prevData]);
return ( return (
<> <>
<OrbitControls /> {props.visible && (
{props.visible ? (
<> <>
<sprite <sprite
scale={[3.5, 0.01, 0]} scale={[3.5, 0.01, 0]}
@ -120,17 +159,19 @@ const BootAuthorizeUser = (props: BootAuthorizeUserProps) => {
/> />
</sprite> </sprite>
<OrbitControls />
<group position={[-1.15, 0.4, 0.3]} rotation={[-0.8, 0, -0.3]}> <group position={[-1.15, 0.4, 0.3]} rotation={[-0.8, 0, -0.3]}>
<mesh <mesh
scale={[4, 1.28, 0]} scale={[4, 1.28, 0]}
renderOrder={-1} position={[3.35, -0.7, 0]}
position={[1, 2, 0]} ref={bgLettersRef}
> >
<planeBufferGeometry attach="geometry" /> <planeBufferGeometry attach="geometry" />
<meshBasicMaterial <meshBasicMaterial
map={authorizeInactiveLettersTex} map={authorizeInactiveLettersTex}
attach="material" attach="material"
transparent={true} transparent={true}
side={THREE.DoubleSide}
/> />
</mesh> </mesh>
<mesh <mesh
@ -140,7 +181,7 @@ const BootAuthorizeUser = (props: BootAuthorizeUserProps) => {
> >
<planeBufferGeometry attach="geometry" /> <planeBufferGeometry attach="geometry" />
<meshBasicMaterial <meshBasicMaterial
map={authorizeActiveLettersMap} map={activeLetterMap}
attach="material" attach="material"
transparent={true} transparent={true}
depthTest={false} depthTest={false}
@ -157,8 +198,6 @@ const BootAuthorizeUser = (props: BootAuthorizeUserProps) => {
</mesh> </mesh>
</group> </group>
</> </>
) : (
<></>
)} )}
</> </>
); );

View file

@ -1,106 +1,48 @@
import React from "react"; import React from "react";
import loadDataUnderline from "../../static/sprite/load_data_header_underline.png"; import loadDataUnderline from "../../static/sprite/load_data_header_underline.png";
import loadDataQuestionContainer from "../../static/sprite/load_data_question_container.png";
import loadDataAnswerContainer from "../../static/sprite/load_data_answer_container.png";
import areYouSure from "../../static/sprite/are_you_sure.png";
import yes from "../../static/sprite/Yes.png";
import no from "../../static/sprite/No.png";
import * as THREE from "three"; import * as THREE from "three";
import { useLoader } from "react-three-fiber"; import { useLoader } from "react-three-fiber";
import Prompt from "../Prompt";
import { useStore } from "../../store";
import Status from "../Status";
type BootLoadDataProps = { type BootLoadDataProps = {
visible: boolean; visible: boolean;
activeBootElement: any;
}; };
const BootLoadData = (props: BootLoadDataProps) => { const BootLoadData = (props: BootLoadDataProps) => {
// const loadDataUnderlineTex = useLoader( const promptVisible = useStore((state) => state.promptVisible);
// THREE.TextureLoader,
// loadDataUnderline const loadDataUnderlineTex = useLoader(
// ); THREE.TextureLoader,
// const loadDataQuestionContainerTex = useLoader( loadDataUnderline
// THREE.TextureLoader, );
// loadDataQuestionContainer
// ); return (
// const loadDataAnswerContainerTex = useLoader( <>
// THREE.TextureLoader, {props.visible && (
// loadDataAnswerContainer <>
// ); <sprite
// const areYouSureTex = useLoader(THREE.TextureLoader, areYouSure); scale={[3.5, 0.01, 0]}
// const yesTex = useLoader(THREE.TextureLoader, yes); position={[-0.5, -1.15, 0]}
// const noTex = useLoader(THREE.TextureLoader, no); renderOrder={2}
// >
// return ( <spriteMaterial
// <> map={loadDataUnderlineTex}
// {props.visible ? ( attach="material"
// <> transparent={true}
// <sprite scale={[4.1, 0.3, 0]} renderOrder={2} position={[0, 0.2, 0]}> />
// <spriteMaterial </sprite>
// map={loadDataQuestionContainerTex} <group visible={promptVisible}>
// attach="material" <Prompt />
// transparent={true} </group>
// opacity={0.6} <group position={[-0.8, -0.8, 0]} scale={[0.8, 0.6, 0]}>
// /> <Status />
// </sprite> </group>
// </>
// <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; export default BootLoadData;

View file

@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from "react"; import React, { useCallback, useMemo } from "react";
import { a, useSpring } from "@react-spring/three"; import { a, useSpring } from "@react-spring/three";
import authorizeActive from "../../static/sprite/authorize_user_active.png"; import authorizeActive from "../../static/sprite/authorize_user_active.png";
import authorizeInactive from "../../static/sprite/authorize_user_inactive.png"; import authorizeInactive from "../../static/sprite/authorize_user_inactive.png";
@ -8,11 +8,11 @@ import { useLoader } from "react-three-fiber";
import * as THREE from "three"; import * as THREE from "three";
import authorizeUserHeader from "../../static/sprite/authorize_user_scene_header.png"; import authorizeUserHeader from "../../static/sprite/authorize_user_scene_header.png";
import loadDataHeader from "../../static/sprite/load_data_header.png"; import loadDataHeader from "../../static/sprite/load_data_header.png";
import { useStore } from "../../store";
type BootMainMenuProps = { type BootMainMenuProps = {
visible: boolean; visible: boolean;
activeSubScene: string; activeSubScene: string;
activeBootElement: any;
}; };
const BootMainMenuComponents = (props: BootMainMenuProps) => { const BootMainMenuComponents = (props: BootMainMenuProps) => {
@ -26,6 +26,14 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
authorizeUserHeader authorizeUserHeader
); );
const activeMainMenuElement = useStore(
useCallback(
(state) =>
state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx],
[]
)
);
const loadDataActiveTex = useLoader(THREE.TextureLoader, loadDataActive); const loadDataActiveTex = useLoader(THREE.TextureLoader, loadDataActive);
const loadDataInactiveTex = useLoader(THREE.TextureLoader, loadDataInactive); const loadDataInactiveTex = useLoader(THREE.TextureLoader, loadDataInactive);
const loadDataHeaderTex = useLoader(THREE.TextureLoader, loadDataHeader); const loadDataHeaderTex = useLoader(THREE.TextureLoader, loadDataHeader);
@ -39,7 +47,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
} else { } else {
return { return {
texture: texture:
props.activeBootElement === "load_data" activeMainMenuElement === "load_data"
? loadDataActiveTex ? loadDataActiveTex
: loadDataInactiveTex, : loadDataInactiveTex,
position: { x: 0, y: -0.5 }, position: { x: 0, y: -0.5 },
@ -49,7 +57,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
loadDataActiveTex, loadDataActiveTex,
loadDataHeaderTex, loadDataHeaderTex,
loadDataInactiveTex, loadDataInactiveTex,
props.activeBootElement, activeMainMenuElement,
props.activeSubScene, props.activeSubScene,
]); ]);
@ -64,7 +72,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
return { return {
scale: [1.8, 0.3, 0], scale: [1.8, 0.3, 0],
texture: texture:
props.activeBootElement === "authorize_user" activeMainMenuElement === "authorize_user"
? authorizeActiveTex ? authorizeActiveTex
: authorizeInactiveTex, : authorizeInactiveTex,
position: { x: 0, y: 0.5 }, position: { x: 0, y: 0.5 },
@ -74,7 +82,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
authorizeActiveTex, authorizeActiveTex,
authorizeInactiveTex, authorizeInactiveTex,
authorizeUserHeaderTex, authorizeUserHeaderTex,
props.activeBootElement, activeMainMenuElement,
props.activeSubScene, props.activeSubScene,
]); ]);
@ -90,7 +98,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
return ( return (
<> <>
{props.visible ? ( {props.visible && (
<> <>
<a.sprite <a.sprite
scale={authorizeUserTextState.scale as [number, number, number]} scale={authorizeUserTextState.scale as [number, number, number]}
@ -120,8 +128,6 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
/> />
</a.sprite> </a.sprite>
</> </>
) : (
<></>
)} )}
</> </>
); );

View file

@ -1,5 +1,6 @@
import { useCallback, useEffect, useMemo, useRef } from "react"; import { useCallback, useEffect, useMemo, useRef } from "react";
import { import {
getBootSceneContext,
getMainSceneContext, getMainSceneContext,
getMediaSceneContext, getMediaSceneContext,
getSSknSceneContext, getSSknSceneContext,
@ -7,7 +8,7 @@ import {
} from "../store"; } from "../store";
import { getKeyCodeAssociation } from "../utils/keyPressUtils"; import { getKeyCodeAssociation } from "../utils/keyPressUtils";
import mediaManager from "../core/setters/media/mediaManager"; import mediaManager from "../core/setters/media/mediaManager";
import handleMediaSceneEvent from "../core/scene-keypress-handlers/handleMediaKeyPress"; import handleMediaSceneKeyPress from "../core/scene-keypress-handlers/handleMediaSceneKeyPress";
import sceneManager from "../core/setters/sceneManager"; import sceneManager from "../core/setters/sceneManager";
import levelSelectionManager from "../core/setters/main/level_selection/levelSelectionManager"; import levelSelectionManager from "../core/setters/main/level_selection/levelSelectionManager";
import nodeManager from "../core/setters/main/site/nodeManager"; import nodeManager from "../core/setters/main/site/nodeManager";
@ -17,12 +18,15 @@ import siteManager from "../core/setters/main/site/siteManager";
import pauseManager from "../core/setters/main/pause/pauseManager"; import pauseManager from "../core/setters/main/pause/pauseManager";
import mainSubsceneManager from "../core/setters/main/mainSubsceneManager"; import mainSubsceneManager from "../core/setters/main/mainSubsceneManager";
import ssknManager from "../core/setters/sskn/ssknManager"; import ssknManager from "../core/setters/sskn/ssknManager";
import handleSSknSceneEvent from "../core/scene-keypress-handlers/handleSSknKeyPress"; import handleSSknSceneKeyPress from "../core/scene-keypress-handlers/handleSSknSceneKeyPress";
import handleMainSceneEvent from "../core/scene-keypress-handlers/handleMainKeyPress"; import handleMainSceneKeyPress from "../core/scene-keypress-handlers/handleMainSceneKeyPress";
import gameLoader from "../core/setters/gameLoader"; import gameLoader from "../core/setters/gameLoader";
import gameSaver from "../core/setters/gameSaver"; import gameSaver from "../core/setters/gameSaver";
import progressManager from "../core/setters/progressManager"; import progressManager from "../core/setters/progressManager";
import promptManager from "../core/setters/promptManager"; import promptManager from "../core/setters/promptManager";
import bootSubsceneManager from "../core/setters/boot/bootSubsceneManager";
import bootManager from "../core/setters/boot/bootManager";
import handleBootSceneKeyPress from "../core/scene-keypress-handlers/handleBootSceneKeyPress";
const KeyPressHandler = () => { const KeyPressHandler = () => {
const mediaSceneSetters = useMemo( const mediaSceneSetters = useMemo(
@ -59,6 +63,11 @@ const KeyPressHandler = () => {
[] []
); );
const bootSceneSetters = useMemo(
() => [bootSubsceneManager, bootManager, promptManager, gameLoader],
[]
);
const scene = useStore((state) => state.currentScene); const scene = useStore((state) => state.currentScene);
const timePassedSinceLastKeyPress = useRef(-1); const timePassedSinceLastKeyPress = useRef(-1);
@ -78,21 +87,27 @@ const KeyPressHandler = () => {
case "main": case "main":
return { return {
contextProvider: getMainSceneContext, contextProvider: getMainSceneContext,
handler: handleMainSceneEvent, handler: handleMainSceneKeyPress,
setters: mainSceneSetters, setters: mainSceneSetters,
}; };
case "media": case "media":
return { return {
contextProvider: getMediaSceneContext, contextProvider: getMediaSceneContext,
handler: handleMediaSceneEvent, handler: handleMediaSceneKeyPress,
setters: mediaSceneSetters, setters: mediaSceneSetters,
}; };
case "sskn": case "sskn":
return { return {
contextProvider: getSSknSceneContext, contextProvider: getSSknSceneContext,
handler: handleSSknSceneEvent, handler: handleSSknSceneKeyPress,
setters: ssknSceneSetters, setters: ssknSceneSetters,
}; };
case "boot":
return {
contextProvider: getBootSceneContext,
handler: handleBootSceneKeyPress,
setters: bootSceneSetters,
};
case "gate": case "gate":
case "polytan": case "polytan":
case "about": case "about":
@ -118,7 +133,13 @@ const KeyPressHandler = () => {
} }
} }
}, },
[mainSceneSetters, mediaSceneSetters, scene, ssknSceneSetters] [
bootSceneSetters,
mainSceneSetters,
mediaSceneSetters,
scene,
ssknSceneSetters,
]
); );
useEffect(() => { useEffect(() => {

View file

@ -29,7 +29,7 @@ const About = () => {
<sprite <sprite
ref={bgRef} ref={bgRef}
scale={[10.5 / 2.5, 52.8 / 2.5, 0]} scale={[10.5 / 2.5, 52.8 / 2.5, 0]}
position={[1.1, -13, 0]} position={[1.1, -13, 0.1]}
renderOrder={200} renderOrder={200}
> >
<spriteMaterial attach="material" map={aboutBgTex} depthTest={false} /> <spriteMaterial attach="material" map={aboutBgTex} depthTest={false} />

View file

@ -4,15 +4,9 @@ import PauseSquare from "./PauseSquare";
import PauseBigLetter from "../../TextRenderer/PauseBigLetter"; import PauseBigLetter from "../../TextRenderer/PauseBigLetter";
import { useStore } from "../../../store"; import { useStore } from "../../../store";
import { useLoader } from "react-three-fiber"; import { useLoader } from "react-three-fiber";
import About from "./About";
import Prompt from "../../Prompt";
import PermissionDenied from "./PermissionDenied";
const Pause = () => { const Pause = () => {
const exit = useStore((state) => state.pauseExitAnimation); const exit = useStore((state) => state.pauseExitAnimation);
const showingAbout = useStore((state) => state.showingAbout);
const promptVisible = useStore((state) => state.promptVisible);
const permissionDenied = useStore((state) => state.permissionDenied);
const [showActiveComponent, setShowActiveComponent] = useState(false); const [showActiveComponent, setShowActiveComponent] = useState(false);
const [animation, setAnimation] = useState(false); const [animation, setAnimation] = useState(false);
const [intro, setIntro] = useState(true); const [intro, setIntro] = useState(true);
@ -82,290 +76,281 @@ const Pause = () => {
return ( return (
<> <>
{animation && ( {animation && (
<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) => <group position={[-0.85, -0.7, 0]} scale={[0.85, 0.85, 0]}>
[0, 1, 2, 3, 4, 5, 6].map((col: number) => { {[0, 1, 2, 3, 2, 1, 0].map((row: number, rowIdx: number) =>
if (rowIdx === 5 && col > 0 && col < 5) { [0, 1, 2, 3, 4, 5, 6].map((col: number) => {
return col === 1 ? ( if (rowIdx === 5 && col > 0 && col < 5) {
<React.Fragment key={`Lfragment`}> return col === 1 ? (
<PauseBigLetter <React.Fragment key={`Lfragment`}>
color={"white"} <PauseBigLetter
letter={"L"} color={"white"}
letterIdx={col} letter={"L"}
position={[0.35, 1.8, 0]} letterIdx={col}
scale={[0.25, 0.25, 0.25]} position={[0.35, 1.8, 0]}
scale={[0.25, 0.25, 0.25]}
active={!(activeComponent === "load")}
key={"whiteL"}
rowIdx={rowIdx}
colIdx={col}
intro={intro}
/>
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={"whiteLsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
active={!(activeComponent === "load")} active={!(activeComponent === "load")}
key={"whiteL"} key={`${rowIdx}${col}L`}
rowIdx={rowIdx}
colIdx={col}
intro={intro} intro={intro}
/> />
);
} else if (rowIdx === 4 && col > 4 && col < 7) {
return col === 5 ? (
<React.Fragment key={"AFragment"}>
<PauseBigLetter
color={"white"}
letter={"A"}
letterIdx={col}
position={[1.78, 1.43, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "about")}
key={"whiteA"}
rowIdx={rowIdx}
colIdx={col}
intro={intro}
/>
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={"whiteAsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare <PauseSquare
geometry={squareGeoms[row][col]} geometry={squareGeoms[row][col]}
rowIdx={rowIdx} rowIdx={rowIdx}
colIdx={col} colIdx={col}
key={"whiteLsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
active={!(activeComponent === "load")}
key={`${rowIdx}${col}L`}
intro={intro}
/>
);
} else if (rowIdx === 4 && col > 4 && col < 7) {
return col === 5 ? (
<React.Fragment key={"AFragment"}>
<PauseBigLetter
color={"white"}
letter={"A"}
letterIdx={col}
position={[1.78, 1.43, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "about")} active={!(activeComponent === "about")}
key={"whiteA"} key={`${rowIdx}${col}A`}
rowIdx={rowIdx}
colIdx={col}
intro={intro} intro={intro}
/> />
);
} else if (rowIdx === 3 && col > 2 && col < 7) {
return col === 3 ? (
<React.Fragment key={"CFragment"}>
<PauseBigLetter
color={"white"}
letter={"C"}
letterIdx={col}
position={[1.05, 1.07, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "change")}
key={"whiteC"}
rowIdx={rowIdx}
colIdx={col}
intro={intro}
/>
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={"whiteCsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare <PauseSquare
geometry={squareGeoms[row][col]} geometry={squareGeoms[row][col]}
rowIdx={rowIdx} rowIdx={rowIdx}
colIdx={col} colIdx={col}
key={"whiteAsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
active={!(activeComponent === "about")}
key={`${rowIdx}${col}A`}
intro={intro}
/>
);
} else if (rowIdx === 3 && col > 2 && col < 7) {
return col === 3 ? (
<React.Fragment key={"CFragment"}>
<PauseBigLetter
color={"white"}
letter={"C"}
letterIdx={col}
position={[1.05, 1.07, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "change")} active={!(activeComponent === "change")}
key={"whiteC"} key={`${rowIdx}${col}C`}
rowIdx={rowIdx}
colIdx={col}
intro={intro} intro={intro}
/> />
);
} else if (rowIdx === 1 && col > 0 && col < 5) {
return col === 1 ? (
<React.Fragment key={"Sfragment"}>
<PauseBigLetter
color={"white"}
letter={"S"}
letterIdx={col}
position={[0.35, 0.35, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "save")}
key={"whiteS"}
rowIdx={rowIdx}
colIdx={col}
intro={intro}
/>
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={"whiteSsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare <PauseSquare
geometry={squareGeoms[row][col]} geometry={squareGeoms[row][col]}
rowIdx={rowIdx} rowIdx={rowIdx}
colIdx={col} colIdx={col}
key={"whiteCsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
active={!(activeComponent === "change")}
key={`${rowIdx}${col}C`}
intro={intro}
/>
);
} else if (rowIdx === 1 && col > 0 && col < 5) {
return col === 1 ? (
<React.Fragment key={"Sfragment"}>
<PauseBigLetter
color={"white"}
letter={"S"}
letterIdx={col}
position={[0.35, 0.35, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "save")} active={!(activeComponent === "save")}
key={"whiteS"} key={`${rowIdx}${col}S`}
rowIdx={rowIdx}
colIdx={col}
intro={intro} intro={intro}
/> />
);
} else if (rowIdx === 0 && col > 4 && col < 7) {
return col === 5 ? (
<React.Fragment key={"Efragment"}>
<PauseBigLetter
color={"white"}
letter={"E"}
letterIdx={col}
position={[1.78, 0, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "exit")}
key={"whiteE"}
rowIdx={1}
colIdx={col}
intro={intro}
/>
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={"whiteEsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare <PauseSquare
geometry={squareGeoms[row][col]} geometry={squareGeoms[row][col]}
rowIdx={rowIdx} rowIdx={rowIdx}
colIdx={col} colIdx={col}
key={"whiteSsquare"}
shouldDisappear={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
active={!(activeComponent === "save")}
key={`${rowIdx}${col}S`}
intro={intro}
/>
);
} else if (rowIdx === 0 && col > 4 && col < 7) {
return col === 5 ? (
<React.Fragment key={"Efragment"}>
<PauseBigLetter
color={"white"}
letter={"E"}
letterIdx={col}
position={[1.78, 0, 0]}
scale={[0.25, 0.25, 0]}
active={!(activeComponent === "exit")} active={!(activeComponent === "exit")}
key={"whiteE"} key={`${rowIdx}${col}E`}
rowIdx={1}
colIdx={col}
intro={intro} intro={intro}
/> />
);
} else {
return (
<PauseSquare <PauseSquare
geometry={squareGeoms[row][col]} geometry={squareGeoms[row][col]}
rowIdx={rowIdx} rowIdx={rowIdx}
colIdx={col} colIdx={col}
key={"whiteEsquare"} key={`${rowIdx}${col}r`}
shouldDisappear={true} active={true}
intro={intro} intro={intro}
/> />
</React.Fragment> );
) : ( }
<PauseSquare })
geometry={squareGeoms[row][col]} )}
rowIdx={rowIdx} {"Load".split("").map((letter, idx) => (
colIdx={col} <PauseBigLetter
active={!(activeComponent === "exit")} color={idx > 0 ? "yellow" : "orange"}
key={`${rowIdx}${col}E`} letter={letter}
intro={intro} letterIdx={idx}
/> key={idx}
); position={[0.35 + idx / 2.8, 1.8, 0]}
} else { scale={[0.25, 0.25, 0.25]}
return ( active={activeComponent === "load"}
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={`${rowIdx}${col}r`}
active={true}
intro={intro}
/>
);
}
})
)}
{"Load".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
key={idx}
position={[0.35 + idx / 2.8, 1.8, 0]}
scale={[0.25, 0.25, 0.25]}
active={activeComponent === "load"}
/>
))}
{"About".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
position={[1.78 + idx / 2.8, 1.43, 0]}
scale={[0.25, 0.25, 0]}
active={activeComponent === "about"}
key={idx}
/>
))}
{"Change".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
position={[1.05 + idx / 2.8, 1.07, 0]}
scale={[0.25, 0.25, 0]}
active={activeComponent === "change"}
key={idx}
/>
))}
{"Save".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
position={[0.35 + idx / 2.8, 0.35, 0]}
scale={[0.25, 0.25, 0]}
active={activeComponent === "save"}
key={idx}
/>
))}
{"Exit".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
position={[1.78 + idx / 2.8, 0, 0]}
scale={[0.25, 0.25, 0]}
key={idx}
active={activeComponent === "exit"}
/>
))}
<group visible={!exit}>
<sprite
position={[0.5, -0.8, 0]}
scale={[3, 1, 0]}
renderOrder={100}
>
<spriteMaterial
attach="material"
color={0x000000}
opacity={0.8}
depthTest={false}
/> />
</sprite> ))}
<mesh {"About".split("").map((letter, idx) => (
scale={[0.08, 0.07, 0]} <PauseBigLetter
position={[-0.2, -0.6, 0]} color={idx > 0 ? "yellow" : "orange"}
renderOrder={101} letter={letter}
> letterIdx={idx}
<textGeometry position={[1.78 + idx / 2.8, 1.43, 0]}
attach="geometry" scale={[0.25, 0.25, 0]}
args={["Application Version 1.0", config]} active={activeComponent === "about"}
key={idx}
/> />
<meshBasicMaterial ))}
attach="material" {"Change".split("").map((letter, idx) => (
color={0x00ba7c} <PauseBigLetter
transparent={true} color={idx > 0 ? "yellow" : "orange"}
depthTest={false} letter={letter}
letterIdx={idx}
position={[1.05 + idx / 2.8, 1.07, 0]}
scale={[0.25, 0.25, 0]}
active={activeComponent === "change"}
key={idx}
/> />
</mesh> ))}
{"Save".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
position={[0.35 + idx / 2.8, 0.35, 0]}
scale={[0.25, 0.25, 0]}
active={activeComponent === "save"}
key={idx}
/>
))}
{"Exit".split("").map((letter, idx) => (
<PauseBigLetter
color={idx > 0 ? "yellow" : "orange"}
letter={letter}
letterIdx={idx}
position={[1.78 + idx / 2.8, 0, 0]}
scale={[0.25, 0.25, 0]}
key={idx}
active={activeComponent === "exit"}
/>
))}
<group visible={!exit}>
<sprite
position={[0.5, -0.8, 0]}
scale={[3, 1, 0]}
renderOrder={100}
>
<spriteMaterial
attach="material"
color={0x000000}
opacity={0.8}
depthTest={false}
/>
</sprite>
<mesh
scale={[0.08, 0.07, 0]}
position={[-0.2, -0.6, 0]}
renderOrder={101}
>
<textGeometry
attach="geometry"
args={["Application Version 1.0", config]}
/>
<meshBasicMaterial
attach="material"
color={0x00ba7c}
transparent={true}
depthTest={false}
/>
</mesh>
</group>
</group> </group>
{showingAbout && <About />} </>
{promptVisible && (
<group position={[1, 0.6, 0]} scale={[1.2, 1.2, 0]}>
<Prompt />
</group>
)}
{permissionDenied && (
<group position={[1, 0.6, 0]} scale={[1.2, 1.2, 0]}>
<PermissionDenied />
</group>
)}
</group>
)} )}
</> </>
); );

View file

@ -0,0 +1,42 @@
import React from "react";
import About from "./About";
import Prompt from "../../Prompt";
import PermissionDenied from "./PermissionDenied";
import { useStore } from "../../../store";
import Status from "../../Status";
const PausePopUps = () => {
const subscene = useStore((state) => state.mainSubscene);
const showingAbout = useStore((state) => state.showingAbout);
const promptVisible = useStore((state) => state.promptVisible);
const permissionDenied = useStore((state) => state.permissionDenied);
return (
<group
position={[-0.85, -0.7, 0]}
scale={[0.85, 0.85, 0]}
visible={subscene === "pause"}
>
{showingAbout && <About />}
<group
position={[1, 0.6, 0]}
scale={[1.2, 1.2, 0]}
visible={promptVisible}
>
<Prompt />
</group>
<group
position={[1, 0.6, 0]}
scale={[1.2, 1.2, 0]}
visible={permissionDenied}
>
<PermissionDenied />
</group>
<Status />
</group>
);
};
export default PausePopUps;

67
src/components/Status.tsx Normal file
View file

@ -0,0 +1,67 @@
import React, { useEffect } from "react";
import statusContainer from "../static/sprite/status_container.png";
import loadSuccessfulImg from "../static/sprite/load_successful.png";
import loadFailImg from "../static/sprite/load_fail.png";
import saveSuccessfulImg from "../static/sprite/save_successful.png";
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import { useStore } from "../store";
const Status = () => {
const loadSuccessful = useStore((state) => state.loadSuccessful);
const saveSuccessful = useStore((state) => state.saveSuccessful);
const statusContainerTex = useLoader(THREE.TextureLoader, statusContainer);
const loadSuccessfulTex = useLoader(THREE.TextureLoader, loadSuccessfulImg);
const loadFailTex = useLoader(THREE.TextureLoader, loadFailImg);
const saveSuccessfulTex = useLoader(THREE.TextureLoader, saveSuccessfulImg);
return (
<group
visible={loadSuccessful !== undefined || saveSuccessful !== undefined}
>
<sprite scale={[4, 0.3, 2]} renderOrder={200} position={[1, 0.2, 0]}>
<spriteMaterial
map={statusContainerTex}
attach="material"
depthTest={false}
/>
</sprite>
<sprite
scale={[2, 0.17, 2]}
renderOrder={200}
position={[1, 0.2, 0]}
visible={saveSuccessful === true}
>
<spriteMaterial
map={saveSuccessfulTex}
attach="material"
depthTest={false}
/>
</sprite>
<sprite
scale={[2, 0.17, 2]}
renderOrder={200}
position={[1, 0.2, 0]}
visible={loadSuccessful === true}
>
<spriteMaterial
map={loadSuccessfulTex}
attach="material"
depthTest={false}
/>
</sprite>
<sprite
scale={[2, 0.17, 2]}
renderOrder={200}
position={[1, 0.2, 0]}
visible={loadSuccessful === false}
>
<spriteMaterial map={loadFailTex} attach="material" depthTest={false} />
</sprite>
</group>
);
};
export default Status;

View file

@ -1,33 +0,0 @@
const handleBootKeyPress = (gameContext: any) => {
const keyPress = gameContext.keyPress;
const activeBootElement = gameContext.activeBootElement;
const currentSubscene = gameContext.bootSubscene;
const authorizeUserBgLettersPos = gameContext.authorizeUserBgLettersPos;
const authorizeUserActiveLetterTexOffset =
gameContext.authorizeUserActiveLetterTexOffset;
const authorizeUserMatrixIdx = gameContext.authorizeUserMatrixIdx;
switch (keyPress) {
case "DOWN":
case "UP":
case "LEFT":
case "RIGHT":
return {
event: `${currentSubscene}_${keyPress.toLowerCase()}`,
subscene: currentSubscene,
};
case "X":
return {
event: `${currentSubscene}_back`,
subscene: currentSubscene,
};
case "CIRCLE":
return {
event: `${activeBootElement}_select`,
subscene: currentSubscene,
};
}
};
export default handleBootKeyPress;

View file

@ -0,0 +1,93 @@
const handleBootSceneKeyPress = (bootSceneContext: any) => {
const {
keyPress,
subscene,
activeMainMenuComponent,
activePromptComponent,
promptVisible,
authorizeUserLetterIdx,
} = bootSceneContext;
if (promptVisible) {
switch (keyPress) {
case "LEFT":
return { event: "prompt_left" };
case "RIGHT":
return { event: "prompt_right" };
case "CIRCLE":
switch (activePromptComponent) {
case "no":
return { event: "load_data_no" };
case "yes":
return {
event: "load_data_yes",
};
}
}
} else {
switch (subscene) {
case "main_menu":
switch (keyPress) {
case "UP":
case "DOWN":
return { event: `main_menu_${keyPress.toLowerCase()}` };
case "CIRCLE":
return { event: `main_menu_${activeMainMenuComponent}_select` };
}
break;
case "authorize_user":
switch (keyPress) {
case "X":
return { event: "authorize_user_back" };
case "LEFT":
// if utmost left, break
if ([0, 13, 26, 39, 52].includes(authorizeUserLetterIdx)) break;
else {
return {
event: "authorize_user_left",
authorizeUserLetterIdx: authorizeUserLetterIdx - 1,
};
}
case "RIGHT":
// if utmost right, break
if ([12, 25, 38, 51, 64].includes(authorizeUserLetterIdx)) break;
else {
return {
event: "authorize_user_right",
authorizeUserLetterIdx: authorizeUserLetterIdx + 1,
};
}
case "DOWN":
// if utmost down, break
if (
Array.from(new Array(13), (x, i) => i + 52).includes(
authorizeUserLetterIdx
)
)
break;
else {
return {
event: "authorize_user_down",
authorizeUserLetterIdx: authorizeUserLetterIdx + 13,
};
}
case "UP":
// if utmost up, break
if (
Array.from(new Array(13), (x, i) => i).includes(
authorizeUserLetterIdx
)
)
break;
else {
return {
event: "authorize_user_up",
authorizeUserLetterIdx: authorizeUserLetterIdx - 13,
};
}
}
}
}
};
export default handleBootSceneKeyPress;

View file

@ -5,7 +5,7 @@ import {
unknownNodeTemplate, unknownNodeTemplate,
} from "../../utils/node-utils"; } from "../../utils/node-utils";
const handleMainSceneEvent = (mainSceneContext: any) => { const handleMainSceneKeyPress = (mainSceneContext: any) => {
const { const {
subscene, subscene,
selectedLevel, selectedLevel,
@ -339,4 +339,4 @@ const handleMainSceneEvent = (mainSceneContext: any) => {
} }
}; };
export default handleMainSceneEvent; export default handleMainSceneKeyPress;

View file

@ -1,6 +1,6 @@
import { findNodeFromWord } from "../../utils/media-utils"; import { findNodeFromWord } from "../../utils/media-utils";
const handleMediaKeyPress = (mediaSceneContext: any) => { const handleMediaSceneKeyPress = (mediaSceneContext: any) => {
const { const {
keyPress, keyPress,
activeMediaComponent, activeMediaComponent,
@ -97,4 +97,4 @@ const handleMediaKeyPress = (mediaSceneContext: any) => {
} }
}; };
export default handleMediaKeyPress; export default handleMediaSceneKeyPress;

View file

@ -1,4 +1,4 @@
const handleSSknSceneEvent = (ssknSceneContext: any) => { const handleSSknSceneKeyPress = (ssknSceneContext: any) => {
const { keyPress, activeSSknComponent, activeNode } = ssknSceneContext; const { keyPress, activeSSknComponent, activeNode } = ssknSceneContext;
switch (keyPress) { switch (keyPress) {
@ -21,4 +21,4 @@ const handleSSknSceneEvent = (ssknSceneContext: any) => {
} }
}; };
export default handleSSknSceneEvent; export default handleSSknSceneKeyPress;

View file

@ -0,0 +1,43 @@
import { useStore } from "../../../store";
const bootManager = (eventState: any) => {
const setMainMenuComponentMatrixIdx = useStore.getState()
.setMainMenuComponentMatrixIdx;
const setAuthorizeUserLetterIdx = useStore.getState()
.setAuthorizeUserLetterIdx;
const dispatchAction = (eventState: {
event: string;
authorizeUserLetterIdx: number;
}) => {
switch (eventState.event) {
case "main_menu_up":
return {
action: () => setMainMenuComponentMatrixIdx(0),
};
case "main_menu_down":
return {
action: () => setMainMenuComponentMatrixIdx(1),
};
case "main_menu_authorize_user_select":
return { action: () => setAuthorizeUserLetterIdx(0) };
case "authorize_user_up":
case "authorize_user_down":
case "authorize_user_left":
case "authorize_user_right":
return {
action: () =>
setAuthorizeUserLetterIdx(eventState.authorizeUserLetterIdx),
};
}
};
const { action } = { ...dispatchAction(eventState) };
if (action) {
action();
}
};
export default bootManager;

View file

@ -6,15 +6,15 @@ const bootSubsceneManager = (eventState: any) => {
const dispatchAction = (eventState: { event: string }) => { const dispatchAction = (eventState: { event: string }) => {
switch (eventState.event) { switch (eventState.event) {
case "authorize_user_back": case "authorize_user_back":
case "load_data_no_select": case "load_data_no":
return { return {
action: () => setBootSubscene("main_menu"), action: () => setBootSubscene("main_menu"),
}; };
case "authorize_user_select": case "main_menu_authorize_user_select":
return { return {
action: () => setBootSubscene("authorize_user"), action: () => setBootSubscene("authorize_user"),
}; };
case "load_data_select": case "main_menu_load_data_select":
return { action: () => setBootSubscene("load_data") }; return { action: () => setBootSubscene("load_data") };
} }
}; };

View file

@ -2,6 +2,7 @@ import { useStore } from "../../store";
const gameLoader = (eventState: any) => { const gameLoader = (eventState: any) => {
const loadSiteSaveState = useStore.getState().loadSiteSaveState; const loadSiteSaveState = useStore.getState().loadSiteSaveState;
const setLoadSuccessful = useStore.getState().setLoadSuccessful;
const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => { const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => {
switch (eventState.event) { switch (eventState.event) {
@ -9,6 +10,19 @@ const gameLoader = (eventState: any) => {
return { return {
action: () => loadSiteSaveState(eventState.site === "a" ? "b" : "a"), action: () => loadSiteSaveState(eventState.site === "a" ? "b" : "a"),
}; };
case "pause_load_select":
case "load_data_yes":
return {
action: () => {
// todo check if data exists
setLoadSuccessful(true);
setTimeout(() => {
//todo actually load
setLoadSuccessful(undefined);
}, 1200);
},
};
} }
}; };

View file

@ -2,6 +2,7 @@ import { getSiteState, useStore } from "../../store";
const gameSaver = (eventState: any) => { const gameSaver = (eventState: any) => {
const setSiteSaveState = useStore.getState().setSiteSaveState; const setSiteSaveState = useStore.getState().setSiteSaveState;
const setSaveSuccessful = useStore.getState().setSaveSuccessful;
const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => { const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => {
switch (eventState.event) { switch (eventState.event) {
@ -10,6 +11,17 @@ const gameSaver = (eventState: any) => {
action: () => action: () =>
setSiteSaveState(eventState.site, getSiteState(eventState.site)), setSiteSaveState(eventState.site, getSiteState(eventState.site)),
}; };
case "pause_save_select":
return {
action: () => {
setSaveSuccessful(true);
setTimeout(() => {
//todo actually save
setSaveSuccessful(undefined);
}, 1200);
},
};
} }
}; };

View file

@ -23,7 +23,16 @@ const promptManager = (eventState: any) => {
case "pause_change_select": case "pause_change_select":
return { action: () => exitAndResetPrompt() }; return { action: () => exitAndResetPrompt() };
case "exit_prompt": case "exit_prompt":
case "load_data_no":
return { action: () => exitAndResetPrompt() }; return { action: () => exitAndResetPrompt() };
case "main_menu_load_data_select":
return {
action: () => {
setTimeout(() => {
setPromptVisible(true);
}, 500);
},
};
} }
}; };

View file

@ -9,20 +9,6 @@ import BootLoadData from "../components/BootScene/BootLoadData";
const BootScene = () => { const BootScene = () => {
const activeSubscene = useStore((state) => state.bootSubscene); const activeSubscene = useStore((state) => state.bootSubscene);
const activeBootElement = useStore(
useCallback(
(state) =>
state.bootComponentMatrix[
activeSubscene as keyof typeof state.bootComponentMatrix
][
state.bootComponentMatrixIndices[
activeSubscene as keyof typeof state.bootComponentMatrixIndices
]
],
[activeSubscene]
)
);
const [accelaVisible, setAccelaVisible] = useState(true); const [accelaVisible, setAccelaVisible] = useState(true);
const [mainMenuVisible, setMainMenuVisible] = useState(false); const [mainMenuVisible, setMainMenuVisible] = useState(false);
@ -44,13 +30,9 @@ const BootScene = () => {
<BootMainMenuComponents <BootMainMenuComponents
visible={mainMenuVisible} visible={mainMenuVisible}
activeSubScene={activeSubscene} activeSubScene={activeSubscene}
activeBootElement={activeBootElement}
/> />
<BootAuthorizeUser visible={activeSubscene === "authorize_user"} /> <BootAuthorizeUser visible={activeSubscene === "authorize_user"} />
<BootLoadData <BootLoadData visible={activeSubscene === "load_data"} />
visible={activeSubscene === "load_data"}
activeBootElement={activeBootElement}
/>
</perspectiveCamera> </perspectiveCamera>
); );
}; };

View file

@ -14,6 +14,7 @@ import Lain from "../components/MainScene/Lain";
import * as THREE from "three"; import * as THREE from "three";
import { useFrame } from "react-three-fiber"; import { useFrame } from "react-three-fiber";
import NotFound from "../components/MainScene/NotFound"; import NotFound from "../components/MainScene/NotFound";
import PausePopUps from "../components/MainScene/PauseSubscene/PausePopUps";
const MainScene = () => { const MainScene = () => {
const intro = useStore((state) => state.intro); const intro = useStore((state) => state.intro);
@ -94,6 +95,7 @@ const MainScene = () => {
<perspectiveCamera position-z={3}> <perspectiveCamera position-z={3}>
<Suspense fallback={null}> <Suspense fallback={null}>
<LevelSelection /> <LevelSelection />
<PausePopUps />
<Pause /> <Pause />
<NotFound visible={subscene === "not_found"} /> <NotFound visible={subscene === "not_found"} />
<group visible={!paused}> <group visible={!paused}>

View file

@ -83,18 +83,9 @@ type State = {
gateLvl: number; gateLvl: number;
// boot scene // boot scene
bootComponentMatrix: { mainMenuComponentMatrix: ["authorize_user", "load_data"];
main_menu: ["authorize_user", "load_data"]; mainMenuComponentMatrixIdx: 0 | 1;
load_data: ["load_data_yes", "load_data_no"]; authorizeUserLetterIdx: number;
authorize_user: typeof authorize_user_letters.letters;
};
bootComponentMatrixIndices: {
// 0 or 1
main_menu: 0 | 1;
// 0 or 1
load_data: 0 | 1;
authorize_user: 0;
};
bootSubscene: "main_menu" | "load_data" | "authorize_user"; bootSubscene: "main_menu" | "load_data" | "authorize_user";
// end scene // end scene
@ -105,6 +96,10 @@ type State = {
promptComponentMatrix: ["yes", "no"]; promptComponentMatrix: ["yes", "no"];
promptComponentMatrixIdx: 1 | 0; promptComponentMatrixIdx: 1 | 0;
// status notifiers
loadSuccessful: boolean | undefined;
saveSuccessful: boolean | undefined;
// save state // save state
siteSaveState: { siteSaveState: {
a: { a: {
@ -124,7 +119,7 @@ export const useStore = create(
combine( combine(
{ {
// scene data // scene data
currentScene: "main", currentScene: "boot",
// game progress // game progress
gameProgress: game_progress, gameProgress: game_progress,
@ -241,18 +236,9 @@ export const useStore = create(
gateLvl: 0, gateLvl: 0,
// boot scene // boot scene
bootComponentMatrix: { mainMenuComponentMatrix: ["authorize_user", "load_data"],
main_menu: ["authorize_user", "load_data"], mainMenuComponentMatrixIdx: 0,
load_data: ["load_data_yes", "load_data_no"], authorizeUserLetterIdx: 0,
authorize_user: authorize_user_letters.letters,
},
bootComponentMatrixIndices: {
// 0 or 1
main_menu: 0,
// 0 or 1
load_data: 0,
authorize_user: 0,
},
bootSubscene: "main_menu", bootSubscene: "main_menu",
// end scene // end scene
@ -263,6 +249,10 @@ export const useStore = create(
promptComponentMatrix: ["yes", "no"], promptComponentMatrix: ["yes", "no"],
promptComponentMatrixIdx: 1, promptComponentMatrixIdx: 1,
// status notifiers
loadSuccessful: undefined,
saveSuccessful: undefined,
// save states for loading the game/changing sites // save states for loading the game/changing sites
siteSaveState: { siteSaveState: {
a: { a: {
@ -402,17 +392,12 @@ export const useStore = create(
// boot scene setters // boot scene setters
setBootSubscene: (to: "load_data" | "authorize_user" | "main_menu") => setBootSubscene: (to: "load_data" | "authorize_user" | "main_menu") =>
set(() => ({ bootSubscene: to })), set(() => ({ bootSubscene: to })),
toggleBootComponentMatrixIdx: (subscene: "load_data" | "main_menu") => setMainMenuComponentMatrixIdx: (to: 0 | 1) =>
set((state) => ({ set(() => ({
bootComponentMatrixIndices: { mainMenuComponentMatrixIdx: to,
...state.bootComponentMatrixIndices,
[subscene]: Number(
!state.bootComponentMatrixIndices[
subscene as keyof typeof state.bootComponentMatrixIndices
]
),
},
})), })),
setAuthorizeUserLetterIdx: (to: number) =>
set(() => ({ authorizeUserLetterIdx: to })),
// end scene setters // end scene setters
incrementEndMediaPlayedCount: () => incrementEndMediaPlayedCount: () =>
@ -449,6 +434,12 @@ export const useStore = create(
}; };
}), }),
// status notifier setters
setSaveSuccessful: (to: boolean | undefined) =>
set(() => ({ saveSuccessful: to })),
setLoadSuccessful: (to: boolean | undefined) =>
set(() => ({ loadSuccessful: to })),
// progress setters // progress setters
setNodeViewed: ( setNodeViewed: (
nodeName: string, nodeName: string,
@ -474,10 +465,21 @@ export const getSiteState = (site: "a" | "b") => {
}; };
}; };
const getPromptContext = () => {
const state = useStore.getState();
return {
promptVisible: state.promptVisible,
activePromptComponent:
state.promptComponentMatrix[state.promptComponentMatrixIdx],
};
};
export const getMainSceneContext = () => { export const getMainSceneContext = () => {
const state = useStore.getState(); const state = useStore.getState();
return { return {
...getPromptContext(),
subscene: state.mainSubscene, subscene: state.mainSubscene,
selectedLevel: state.selectedLevel, selectedLevel: state.selectedLevel,
pauseMatrixIdx: state.pauseComponentMatrixIdx, pauseMatrixIdx: state.pauseComponentMatrixIdx,
@ -490,9 +492,6 @@ export const getMainSceneContext = () => {
level: parseInt(state.activeLevel), level: parseInt(state.activeLevel),
ssknLvl: state.ssknLvl, ssknLvl: state.ssknLvl,
showingAbout: state.showingAbout, showingAbout: state.showingAbout,
promptVisible: state.promptVisible,
activePromptComponent:
state.promptComponentMatrix[state.promptComponentMatrixIdx],
gateLvl: state.gateLvl, gateLvl: state.gateLvl,
}; };
}; };
@ -523,3 +522,15 @@ export const getMediaSceneContext = () => {
gameProgress: state.gameProgress, gameProgress: state.gameProgress,
}; };
}; };
export const getBootSceneContext = () => {
const state = useStore.getState();
return {
...getPromptContext(),
subscene: state.bootSubscene,
activeMainMenuComponent:
state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx],
authorizeUserLetterIdx: state.authorizeUserLetterIdx,
};
};