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

View file

@ -1,106 +1,48 @@
import React from "react";
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 { useLoader } from "react-three-fiber";
import Prompt from "../Prompt";
import { useStore } from "../../store";
import Status from "../Status";
type BootLoadDataProps = {
visible: boolean;
activeBootElement: any;
};
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>
// </>
// ) : (
// <></>
// )}
// </>
// );
return <></>;
const promptVisible = useStore((state) => state.promptVisible);
const loadDataUnderlineTex = useLoader(
THREE.TextureLoader,
loadDataUnderline
);
return (
<>
{props.visible && (
<>
<sprite
scale={[3.5, 0.01, 0]}
position={[-0.5, -1.15, 0]}
renderOrder={2}
>
<spriteMaterial
map={loadDataUnderlineTex}
attach="material"
transparent={true}
/>
</sprite>
<group visible={promptVisible}>
<Prompt />
</group>
<group position={[-0.8, -0.8, 0]} scale={[0.8, 0.6, 0]}>
<Status />
</group>
</>
)}
</>
);
};
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 authorizeActive from "../../static/sprite/authorize_user_active.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 authorizeUserHeader from "../../static/sprite/authorize_user_scene_header.png";
import loadDataHeader from "../../static/sprite/load_data_header.png";
import { useStore } from "../../store";
type BootMainMenuProps = {
visible: boolean;
activeSubScene: string;
activeBootElement: any;
};
const BootMainMenuComponents = (props: BootMainMenuProps) => {
@ -26,6 +26,14 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
authorizeUserHeader
);
const activeMainMenuElement = useStore(
useCallback(
(state) =>
state.mainMenuComponentMatrix[state.mainMenuComponentMatrixIdx],
[]
)
);
const loadDataActiveTex = useLoader(THREE.TextureLoader, loadDataActive);
const loadDataInactiveTex = useLoader(THREE.TextureLoader, loadDataInactive);
const loadDataHeaderTex = useLoader(THREE.TextureLoader, loadDataHeader);
@ -39,7 +47,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
} else {
return {
texture:
props.activeBootElement === "load_data"
activeMainMenuElement === "load_data"
? loadDataActiveTex
: loadDataInactiveTex,
position: { x: 0, y: -0.5 },
@ -49,7 +57,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
loadDataActiveTex,
loadDataHeaderTex,
loadDataInactiveTex,
props.activeBootElement,
activeMainMenuElement,
props.activeSubScene,
]);
@ -64,7 +72,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
return {
scale: [1.8, 0.3, 0],
texture:
props.activeBootElement === "authorize_user"
activeMainMenuElement === "authorize_user"
? authorizeActiveTex
: authorizeInactiveTex,
position: { x: 0, y: 0.5 },
@ -74,7 +82,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
authorizeActiveTex,
authorizeInactiveTex,
authorizeUserHeaderTex,
props.activeBootElement,
activeMainMenuElement,
props.activeSubScene,
]);
@ -90,7 +98,7 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
return (
<>
{props.visible ? (
{props.visible && (
<>
<a.sprite
scale={authorizeUserTextState.scale as [number, number, number]}
@ -120,8 +128,6 @@ const BootMainMenuComponents = (props: BootMainMenuProps) => {
/>
</a.sprite>
</>
) : (
<></>
)}
</>
);

View file

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

View file

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

View file

@ -4,15 +4,9 @@ import PauseSquare from "./PauseSquare";
import PauseBigLetter from "../../TextRenderer/PauseBigLetter";
import { useStore } from "../../../store";
import { useLoader } from "react-three-fiber";
import About from "./About";
import Prompt from "../../Prompt";
import PermissionDenied from "./PermissionDenied";
const Pause = () => {
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 [animation, setAnimation] = useState(false);
const [intro, setIntro] = useState(true);
@ -82,290 +76,281 @@ const Pause = () => {
return (
<>
{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) =>
[0, 1, 2, 3, 4, 5, 6].map((col: number) => {
if (rowIdx === 5 && col > 0 && col < 5) {
return col === 1 ? (
<React.Fragment key={`Lfragment`}>
<PauseBigLetter
color={"white"}
letter={"L"}
letterIdx={col}
position={[0.35, 1.8, 0]}
scale={[0.25, 0.25, 0.25]}
<>
<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) {
return col === 1 ? (
<React.Fragment key={`Lfragment`}>
<PauseBigLetter
color={"white"}
letter={"L"}
letterIdx={col}
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")}
key={"whiteL"}
rowIdx={rowIdx}
colIdx={col}
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")}
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
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")}
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")}
key={"whiteA"}
rowIdx={rowIdx}
colIdx={col}
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")}
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
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
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")}
key={"whiteC"}
rowIdx={rowIdx}
colIdx={col}
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")}
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
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
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")}
key={"whiteS"}
rowIdx={rowIdx}
colIdx={col}
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")}
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
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
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")}
key={"whiteE"}
rowIdx={1}
colIdx={col}
key={`${rowIdx}${col}E`}
intro={intro}
/>
);
} else {
return (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
key={"whiteEsquare"}
shouldDisappear={true}
key={`${rowIdx}${col}r`}
active={true}
intro={intro}
/>
</React.Fragment>
) : (
<PauseSquare
geometry={squareGeoms[row][col]}
rowIdx={rowIdx}
colIdx={col}
active={!(activeComponent === "exit")}
key={`${rowIdx}${col}E`}
intro={intro}
/>
);
} else {
return (
<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}
);
}
})
)}
{"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"}
/>
</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]}
))}
{"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}
/>
<meshBasicMaterial
attach="material"
color={0x00ba7c}
transparent={true}
depthTest={false}
))}
{"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}
/>
</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>
{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,
} from "../../utils/node-utils";
const handleMainSceneEvent = (mainSceneContext: any) => {
const handleMainSceneKeyPress = (mainSceneContext: any) => {
const {
subscene,
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";
const handleMediaKeyPress = (mediaSceneContext: any) => {
const handleMediaSceneKeyPress = (mediaSceneContext: any) => {
const {
keyPress,
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;
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 }) => {
switch (eventState.event) {
case "authorize_user_back":
case "load_data_no_select":
case "load_data_no":
return {
action: () => setBootSubscene("main_menu"),
};
case "authorize_user_select":
case "main_menu_authorize_user_select":
return {
action: () => setBootSubscene("authorize_user"),
};
case "load_data_select":
case "main_menu_load_data_select":
return { action: () => setBootSubscene("load_data") };
}
};

View file

@ -2,6 +2,7 @@ import { useStore } from "../../store";
const gameLoader = (eventState: any) => {
const loadSiteSaveState = useStore.getState().loadSiteSaveState;
const setLoadSuccessful = useStore.getState().setLoadSuccessful;
const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => {
switch (eventState.event) {
@ -9,6 +10,19 @@ const gameLoader = (eventState: any) => {
return {
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 setSiteSaveState = useStore.getState().setSiteSaveState;
const setSaveSuccessful = useStore.getState().setSaveSuccessful;
const dispatchAction = (eventState: { event: string; site: "a" | "b" }) => {
switch (eventState.event) {
@ -10,6 +11,17 @@ const gameSaver = (eventState: any) => {
action: () =>
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":
return { action: () => exitAndResetPrompt() };
case "exit_prompt":
case "load_data_no":
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 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 [mainMenuVisible, setMainMenuVisible] = useState(false);
@ -44,13 +30,9 @@ const BootScene = () => {
<BootMainMenuComponents
visible={mainMenuVisible}
activeSubScene={activeSubscene}
activeBootElement={activeBootElement}
/>
<BootAuthorizeUser visible={activeSubscene === "authorize_user"} />
<BootLoadData
visible={activeSubscene === "load_data"}
activeBootElement={activeBootElement}
/>
<BootLoadData visible={activeSubscene === "load_data"} />
</perspectiveCamera>
);
};

View file

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

View file

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