end scene done + replacing some settimeouts with sleeps

This commit is contained in:
ad044 2021-02-14 20:14:41 +04:00
parent fcc029fc56
commit d63d11585b
14 changed files with 261 additions and 151 deletions

View file

@ -8,6 +8,7 @@ import { useFrame, useLoader } from "react-three-fiber";
import * as THREE from "three"; import * as THREE from "three";
import { PlainAnimator } from "three-plain-animator/lib/plain-animator"; import { PlainAnimator } from "three-plain-animator/lib/plain-animator";
import { a, useSpring } from "@react-spring/three"; import { a, useSpring } from "@react-spring/three";
import { useStore } from "../../store";
const EndSelectionScreen = () => { const EndSelectionScreen = () => {
const middleSpritesheetTex: any = useLoader( const middleSpritesheetTex: any = useLoader(
@ -22,6 +23,8 @@ const EndSelectionScreen = () => {
const continueTextTex = useLoader(THREE.TextureLoader, continueText); const continueTextTex = useLoader(THREE.TextureLoader, continueText);
const middleLainTex = useLoader(THREE.TextureLoader, middleLain); const middleLainTex = useLoader(THREE.TextureLoader, middleLain);
const componentMatrixIdx = useStore((state) => state.endComponentMatrixIdx);
const [middleSpritesheetAnimator] = useState(() => { const [middleSpritesheetAnimator] = useState(() => {
const anim = new PlainAnimator(middleSpritesheetTex, 1, 4, 4, 24); const anim = new PlainAnimator(middleSpritesheetTex, 1, 4, 4, 24);
anim.init(0); anim.init(0);
@ -71,7 +74,10 @@ const EndSelectionScreen = () => {
<boxBufferGeometry attach="geometry" /> <boxBufferGeometry attach="geometry" />
<meshBasicMaterial attach="material" color={0x000000} /> <meshBasicMaterial attach="material" color={0x000000} />
</mesh> </mesh>
<sprite position={[0, 1, 0]} scale={[0.5, 0.5, 0]}> <sprite
position={componentMatrixIdx === 0 ? [0, 1, 0] : [0, -1.5, 0]}
scale={[0.5, 0.5, 0]}
>
<spriteMaterial attach="material" map={circleSpritesheetTex} /> <spriteMaterial attach="material" map={circleSpritesheetTex} />
</sprite> </sprite>
<sprite position={[0, 1.6, 0]} scale={[1.5, 0.5, 0]}> <sprite position={[0, 1.6, 0]} scale={[1.5, 0.5, 0]}>

View file

@ -1,15 +1,13 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useStore } from "../../store"; import { useStore } from "../store";
import { a, useSpring } from "@react-spring/three"; import { a, useSpring } from "@react-spring/three";
import dummy from "../../static/sprite/dummy.png"; import dummy from "../static/sprite/dummy.png";
import * as THREE from "three"; import * as THREE from "three";
import { useLoader } from "react-three-fiber"; import { useLoader } from "react-three-fiber";
const Images = () => { const Images = () => {
const idleNodeImages = useStore((state) => state.idleImages); const idleNodeImages = useStore((state) => state.idleImages);
const nodeImages = useStore( const nodeImages = useStore((state) => state.activeNode.image_table_indices);
(state) => state.activeNode.image_table_indices
);
const currentScene = useStore((state) => state.currentScene); const currentScene = useStore((state) => state.currentScene);
@ -49,7 +47,7 @@ const Images = () => {
imgTries++; imgTries++;
if (img[1] !== "-1") { if (img[1] !== "-1") {
import( import(
"../../static/media_images/" + currentSite + "/" + img[1] + ".png" "../static/media_images/" + currentSite + "/" + img[1] + ".png"
).then((imageSrc: { default: string }) => { ).then((imageSrc: { default: string }) => {
imgArr.splice(parseInt(img[0]), 0, imageSrc); imgArr.splice(parseInt(img[0]), 0, imageSrc);
if (imgTries === 3) { if (imgTries === 3) {

View file

@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo, useRef } from "react"; import { useCallback, useEffect, useMemo, useRef } from "react";
import { import {
getBootSceneContext, getBootSceneContext,
getEndSceneContext,
getMainSceneContext, getMainSceneContext,
getMediaSceneContext, getMediaSceneContext,
getSSknSceneContext, getSSknSceneContext,
@ -33,6 +34,8 @@ import { useFrame } from "react-three-fiber";
import { getRandomIdleLainAnim, getRandomIdleMedia } from "../utils/idle-utils"; import { getRandomIdleLainAnim, getRandomIdleMedia } from "../utils/idle-utils";
import idleManager from "../core/setters/main/idleManager"; import idleManager from "../core/setters/main/idleManager";
import * as audio from "../static/sfx"; import * as audio from "../static/sfx";
import handleEndSceneKeyPress from "../core/scene-keypress-handlers/handleEndSceneKeyPress";
import endManager from "../core/setters/end/endManager";
const KeyPressHandler = () => { const KeyPressHandler = () => {
const mediaSceneSetters = useMemo( const mediaSceneSetters = useMemo(
@ -83,6 +86,11 @@ const KeyPressHandler = () => {
[] []
); );
const endSceneSetters = useMemo(
() => [sceneManager, soundManager, endManager],
[]
);
const scene = useStore((state) => state.currentScene); const scene = useStore((state) => state.currentScene);
const mainSubscene = useStore((state) => state.mainSubscene); const mainSubscene = useStore((state) => state.mainSubscene);
@ -157,6 +165,12 @@ const KeyPressHandler = () => {
handler: handleBootSceneKeyPress, handler: handleBootSceneKeyPress,
setters: bootSceneSetters, setters: bootSceneSetters,
}; };
case "end":
return {
contextProvider: getEndSceneContext,
handler: handleEndSceneKeyPress,
setters: endSceneSetters,
};
case "gate": case "gate":
case "polytan": case "polytan":
return { return {
@ -191,6 +205,7 @@ const KeyPressHandler = () => {
}, },
[ [
bootSceneSetters, bootSceneSetters,
endSceneSetters,
mainSceneSetters, mainSceneSetters,
mediaSceneSetters, mediaSceneSetters,
scene, scene,

View file

@ -7,6 +7,7 @@ import { useStore } from "../../store";
import MiddleRingPart from "./MiddleRing/MiddleRingPart"; import MiddleRingPart from "./MiddleRing/MiddleRingPart";
import usePrevious from "../../hooks/usePrevious"; import usePrevious from "../../hooks/usePrevious";
import lerp from "../../utils/lerp"; import lerp from "../../utils/lerp";
import sleep from "../../utils/sleep";
const MiddleRing = () => { const MiddleRing = () => {
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture); const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
@ -216,94 +217,79 @@ const MiddleRing = () => {
const prevData = usePrevious({ siteRotY, activeLevel, subscene }); const prevData = usePrevious({ siteRotY, activeLevel, subscene });
useEffect(() => { useEffect(() => {
const rotate = (rotValues: [number, number]) => { const rotate = async (rotValues: [number, number]) => {
setTimeout(() => { await sleep(2300);
setRot({ rotZ: rotValues[0] }); setRot({ rotZ: rotValues[0] });
}, 2300);
setTimeout(() => { await sleep(1200);
setRot({ rotZ: rotValues[1] }); setRot({ rotZ: rotValues[1] });
}, 3500);
setTimeout(() => { await sleep(1000);
setRot({ rotZ: 0 }); setRot({ rotZ: 0 });
}, 4500);
}; };
const moveDown = () => { const moveDown = async () => {
setTimeout(() => { await sleep(800);
setNoiseAmp(0.06); setNoiseAmp(0.06);
setRotating(false); setRotating(false);
}, 800);
setTimeout(() => { await sleep(400);
setPos({ posY: 1.39 }); setPos({ posY: 1.39 });
}, 1200);
// set ring rotation on x axis to craete motion effect // set ring rotation on x axis to craete motion effect
setTimeout(() => { await sleep(300);
setRot({ rotX: 0.3 }); setRot({ rotX: 0.3 });
}, 1500);
setTimeout(() => { await sleep(1500);
setPos({ posY: -0.31 }); setPos({ posY: -0.31 });
}, 3000);
setTimeout(() => { await sleep(150);
setPos({ posY: -0.11 }); setPos({ posY: -0.11 });
}, 3150);
// rotate it again, set ring noise to 0 // rotate it again, set ring noise to 0
setTimeout(() => { await sleep(350);
setRot({ rotX: -0.1 }); setRot({ rotX: -0.1 });
setNoiseAmp(0); setNoiseAmp(0);
}, 3500);
// rotate it back AGAIN (holy fuk psx game) // rotate it back AGAIN (holy fuk psx game)
setTimeout(() => { await sleep(1000);
setRot({ rotX: 0.05 }); setRot({ rotX: 0.05 });
}, 4500);
// reset value, set noise to 0 // reset value, set noise to 0
setTimeout(() => { await sleep(300);
setRot({ rotX: 0, rotZ: 0 }); setRot({ rotX: 0, rotZ: 0 });
setRotating(true); setRotating(true);
}, 4800);
// enable noise again in about 11-12 secs // enable noise again
setTimeout(() => { await sleep(6000);
setNoiseAmp(0.03); setNoiseAmp(0.03);
}, 11600);
}; };
const moveUp = () => { const moveUp = async () => {
// change noise to 0, make the ring bend downwards // change noise to 0, make the ring bend downwards
setTimeout(() => {
await sleep(300);
setNoiseAmp(0); setNoiseAmp(0);
setWobbleAmp(0.2); setWobbleAmp(0.2);
}, 300);
// disable rotation of the ring // disable rotation of the ring
setTimeout(() => { await sleep(400);
setRotating(false); setRotating(false);
}, 700);
// make the ring bend upwards // make the ring bend upwards
setTimeout(() => { await sleep(500);
setWobbleAmp(-0.3); setWobbleAmp(-0.3);
// the middle ring stays in place, therefore we animate it // the middle ring stays in place, therefore we animate it
// in the same direction as the site, creating that illusion. // in the same direction as the site, creating that illusion.
setPos({ posY: -1.39 }); setPos({ posY: -1.39 });
}, 1200);
await sleep(300);
// reset the ring bend, set the rotation to slightly curve // reset the ring bend, set the rotation to slightly curve
// to replicate a motion effect (since its moving upwards) // to replicate a motion effect (since its moving upwards)
// and enable rotation again // and enable rotation again
setTimeout(() => {
setWobbleAmp(0); setWobbleAmp(0);
setRot({ rotX: -0.2 }); setRot({ rotX: -0.2 });
setRotating(true); setRotating(true);
}, 1500);
setTimeout(() => { setTimeout(() => {
setPos({ posY: 0.09 }); setPos({ posY: 0.09 });

View file

@ -3,7 +3,7 @@ import * as THREE from "three";
import greenFont from "../../static/sprite/white_and_green_texture.png"; import greenFont from "../../static/sprite/white_and_green_texture.png";
import medium_font_json from "../../resources/font_data/medium_font.json"; import medium_font_json from "../../resources/font_data/medium_font.json";
import { a } from "@react-spring/three"; import { a } from "@react-spring/three";
import React, { memo, useCallback, useMemo } from "react"; import React, { memo, useCallback, useEffect, useMemo } from "react";
import { useStore } from "../../store"; import { useStore } from "../../store";
const GreenTextRenderer = memo(() => { const GreenTextRenderer = memo(() => {

View file

@ -0,0 +1,15 @@
const handleEndSceneKeyPress = (endSceneContext: any) => {
const { keyPress, selectionVisible, activeEndComponent } = endSceneContext;
if (selectionVisible) {
switch (keyPress) {
case "UP":
case "DOWN":
return { event: `end_selection_${keyPress.toLowerCase()}` };
case "CIRCLE":
return { event: `end_${activeEndComponent}_select` };
}
}
};
export default handleEndSceneKeyPress;

View file

@ -0,0 +1,26 @@
import { useStore } from "../../../store";
const endManager = (eventState: any) => {
const setComponentMatrixIdx = useStore.getState().setEndComponentMatrixIdx;
const dispatchAction = (eventState: { event: string }) => {
switch (eventState.event) {
case "end_selection_up":
return {
action: () => setComponentMatrixIdx(0),
};
case "end_selection_down":
return {
action: () => setComponentMatrixIdx(1),
};
}
};
const { action } = { ...dispatchAction(eventState) };
if (action) {
action();
}
};
export default endManager;

View file

@ -65,6 +65,7 @@ const sceneManager = (eventState: any) => {
delay: 6000, delay: 6000,
}; };
case "pause_change_select": case "pause_change_select":
case "end_continue_select":
return { return {
action: () => action: () =>
useStore.setState({ currentScene: "change_disc", intro: true }), useStore.setState({ currentScene: "change_disc", intro: true }),
@ -81,6 +82,11 @@ const sceneManager = (eventState: any) => {
action: () => useStore.setState({ currentScene: "main" }), action: () => useStore.setState({ currentScene: "main" }),
delay: 0, delay: 0,
}; };
case "end_end_select":
return {
action: () => useStore.setState({ currentScene: "boot" }),
delay: 0,
};
} }
}; };

View file

@ -1,42 +1,39 @@
import { playAudio } from "../../store"; import { playAudio } from "../../store";
import * as audio from "../../static/sfx"; import * as audio from "../../static/sfx";
import sleep from "../../utils/sleep";
const soundManager = (eventState: any) => { const soundManager = (eventState: any) => {
const dispatchAction = (eventState: { event: string; scene: string }) => { const dispatchAction = (eventState: { event: string; scene: string }) => {
switch (eventState.event) { switch (eventState.event) {
case "knock_and_fall": case "knock_and_fall":
return { return {
action: () => { action: async () => {
setTimeout(() => { await sleep(1200);
playAudio(audio.sound14); playAudio(audio.sound14);
}, 1200);
setTimeout(() => { await sleep(1100);
playAudio(audio.sound19); playAudio(audio.sound19);
}, 2300);
setTimeout(() => { await sleep(850);
playAudio(audio.sound33); playAudio(audio.sound33);
}, 3150);
}, },
}; };
case "knock": case "knock":
return { return {
action: () => { action: async () => {
setTimeout(() => { await sleep(1200);
playAudio(audio.sound18); playAudio(audio.sound18);
}, 1200);
}, },
}; };
case "touch_and_scare": case "touch_and_scare":
return { return {
action: () => { action: async () => {
setTimeout(() => { await sleep(2400);
playAudio(audio.sound17); playAudio(audio.sound17);
}, 2400);
setTimeout(() => { await sleep(750);
playAudio(audio.sound33); playAudio(audio.sound33);
}, 3150);
}, },
}; };
case "throw_node_media": case "throw_node_media":
@ -45,17 +42,15 @@ const soundManager = (eventState: any) => {
case "throw_node_tak": case "throw_node_tak":
case "throw_node_polytan": case "throw_node_polytan":
return { return {
action: () => { action: async () => {
playAudio(audio.sound0); playAudio(audio.sound0);
setTimeout(() => { await sleep(1600);
playAudio(audio.sound12); playAudio(audio.sound12);
}, 1600);
setTimeout(() => { await sleep(1200);
playAudio(audio.sound13); playAudio(audio.sound13);
playAudio(audio.sound14); playAudio(audio.sound14);
}, 2800);
}, },
}; };
case "rip_node_media": case "rip_node_media":
@ -64,17 +59,15 @@ const soundManager = (eventState: any) => {
case "rip_node_tak": case "rip_node_tak":
case "rip_node_polytan": case "rip_node_polytan":
return { return {
action: () => { action: async () => {
playAudio(audio.sound0); playAudio(audio.sound0);
setTimeout(() => { await sleep(1600);
playAudio(audio.sound12); playAudio(audio.sound12);
}, 1600);
setTimeout(() => { await sleep(2400);
playAudio(audio.sound15); playAudio(audio.sound15);
playAudio(audio.sound13); playAudio(audio.sound13);
}, 4000);
}, },
}; };
@ -86,55 +79,53 @@ const soundManager = (eventState: any) => {
case "pause_about_select": case "pause_about_select":
case "display_prompt": case "display_prompt":
case "pause_exit_select": case "pause_exit_select":
case "end_continue_select":
case "end_end_select":
return { return {
action: () => playAudio(audio.sound0), action: () => playAudio(audio.sound0),
}; };
case "site_left": case "site_left":
case "site_right": case "site_right":
return { return {
action: () => { action: async () => {
setTimeout(() => { await sleep(1100);
playAudio(audio.sound6); playAudio(audio.sound6);
playAudio(audio.sound34); playAudio(audio.sound34);
}, 1100);
}, },
}; };
case "pause_game": case "pause_game":
return { return {
action: () => { action: async () => {
playAudio(audio.sound7); playAudio(audio.sound7);
setTimeout(() => {
await sleep(3400);
playAudio(audio.sound23); playAudio(audio.sound23);
}, 3400);
}, },
}; };
case "select_level_up": case "select_level_up":
case "select_level_down": case "select_level_down":
return { return {
action: () => { action: async () => {
setTimeout(() => { await sleep(1300);
playAudio(audio.sound10); playAudio(audio.sound10);
playAudio(audio.sound9); playAudio(audio.sound9);
}, 1300);
setTimeout(() => { await sleep(1400);
playAudio(audio.sound8); playAudio(audio.sound8);
}, 2700);
}, },
}; };
case "site_up": case "site_up":
case "site_down": case "site_down":
return { return {
action: () => { action: async () => {
playAudio(audio.sound13); playAudio(audio.sound13);
setTimeout(() => {
await sleep(1300);
playAudio(audio.sound10); playAudio(audio.sound10);
playAudio(audio.sound9); playAudio(audio.sound9);
}, 1300);
setTimeout(() => { await sleep(1400);
playAudio(audio.sound8); playAudio(audio.sound8);
}, 2700);
}, },
}; };
case "main_menu_down": case "main_menu_down":
@ -150,6 +141,8 @@ const soundManager = (eventState: any) => {
case "media_leftside_up": case "media_leftside_up":
case "media_rightside_down": case "media_rightside_down":
case "media_rightside_up": case "media_rightside_up":
case "end_selection_up":
case "end_selection_down":
return { return {
action: () => playAudio(audio.sound1), action: () => playAudio(audio.sound1),
}; };

View file

@ -1,4 +1,10 @@
import React, { useEffect, useMemo, useRef, useState } from "react"; import React, {
useCallback,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import * as THREE from "three"; import * as THREE from "three";
import { useFrame } from "react-three-fiber"; import { useFrame } from "react-three-fiber";
import { createAudioAnalyser, useStore } from "../store"; import { createAudioAnalyser, useStore } from "../store";
@ -15,6 +21,9 @@ const EndScene = () => {
const mainCylinderRef = useRef<THREE.Object3D>(); const mainCylinderRef = useRef<THREE.Object3D>();
const setAudioAnalyser = useStore((state) => state.setAudioAnalyser); const setAudioAnalyser = useStore((state) => state.setAudioAnalyser);
const setSelectionVisible = useStore(
(state) => state.setEndSceneSelectionVisible
);
useFrame(() => { useFrame(() => {
if (mainCylinderRef.current) { if (mainCylinderRef.current) {
@ -33,10 +42,12 @@ const EndScene = () => {
const [isIntro, setIsIntro] = useState(false); const [isIntro, setIsIntro] = useState(false);
const [isOutro, setIsOutro] = useState(false); const [isOutro, setIsOutro] = useState(false);
const [sceneOutro, setSceneOutro] = useState(false); const [sceneOutro, setSceneOutro] = useState(false);
const [showSelectionScreen, setShowSelectionScreen] = useState(false);
const playedMediaCountRef = useRef(0); const playedMediaCountRef = useRef(0);
const mediaList = useMemo(() => [Xa0001, Xa0006], []); const playerName = useStore((state) => state.playerName);
const playerNameVoices = useMemo(() => playerName.split(""), [playerName]);
useEffect(() => { useEffect(() => {
const mediaElement = document.getElementById("media") as HTMLMediaElement; const mediaElement = document.getElementById("media") as HTMLMediaElement;
@ -57,7 +68,22 @@ const EndScene = () => {
}, 3800); }, 3800);
} }
if (playedMediaCountRef.current === mediaList.length) { if (
playedMediaCountRef.current > 1 &&
playedMediaCountRef.current < playerNameVoices.length + 1
) {
import(
"../static/voice/" +
playerNameVoices[playedMediaCountRef.current - 1] +
".WAV"
).then((media) => {
mediaElement.src = media.default;
mediaElement.load();
mediaElement.play();
});
}
if (playedMediaCountRef.current === playerNameVoices.length + 1) {
mediaElement.src = Xa0006; mediaElement.src = Xa0006;
mediaElement.load(); mediaElement.load();
@ -66,11 +92,17 @@ const EndScene = () => {
setTimeout(() => { setTimeout(() => {
setSceneOutro(true); setSceneOutro(true);
}, 4000); }, 4000);
setTimeout(() => {
setObjectsVisible(false);
setShowSelectionScreen(true);
setSelectionVisible(true);
}, 7000);
} }
}; };
mediaElement.addEventListener("ended", playNextMedia); mediaElement.addEventListener("ended", playNextMedia);
}, [mediaList]); }, [playerNameVoices, setSelectionVisible]);
useEffect(() => { useEffect(() => {
const mediaElement = document.getElementById("media") as HTMLMediaElement; const mediaElement = document.getElementById("media") as HTMLMediaElement;
@ -89,6 +121,7 @@ const EndScene = () => {
}, [setAudioAnalyser]); }, [setAudioAnalyser]);
return ( return (
<>
<group visible={objectsVisible}> <group visible={objectsVisible}>
<pointLight position={[0, 0, 5]} intensity={0.9} /> <pointLight position={[0, 0, 5]} intensity={0.9} />
<pointLight position={[0, 0, -5]} intensity={0.9} /> <pointLight position={[0, 0, -5]} intensity={0.9} />
@ -103,6 +136,10 @@ const EndScene = () => {
<EndSphere position={[2, 1.7, -0.5]} outroAnim={sceneOutro} /> <EndSphere position={[2, 1.7, -0.5]} outroAnim={sceneOutro} />
<LainSpeak intro={isIntro} outro={isOutro} /> <LainSpeak intro={isIntro} outro={isOutro} />
</group> </group>
<group visible={showSelectionScreen}>
<EndSelectionScreen />
</group>
</>
); );
}; };

View file

@ -1,6 +1,6 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { useStore } from "../store"; import { useStore } from "../store";
import Images from "../components/MediaScene/Images"; import Images from "../components/Images";
const IdleMediaScene = () => { const IdleMediaScene = () => {
const mediaPercentageElapsed = useStore( const mediaPercentageElapsed = useStore(

View file

@ -5,7 +5,7 @@ import RightSide from "../components/MediaScene/Selectables/RightSide";
import AudioVisualizer from "../components/MediaScene/AudioVisualizer/AudioVisualizer"; import AudioVisualizer from "../components/MediaScene/AudioVisualizer/AudioVisualizer";
import MediaLoadingBar from "../components/MediaScene/MediaLoadingBar"; import MediaLoadingBar from "../components/MediaScene/MediaLoadingBar";
import NodeNameContainer from "../components/MediaScene/NodeNameContainer"; import NodeNameContainer from "../components/MediaScene/NodeNameContainer";
import Images from "../components/MediaScene/Images"; import Images from "../components/Images";
import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer"; import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer";
import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator"; import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator";

View file

@ -40,6 +40,11 @@ type State = {
// level selection // level selection
selectedLevel: number; selectedLevel: number;
// end scene
endComponentMatrix: ["end", "continue"];
endComponentMatrixIdx: 0 | 1;
endSceneSelectionVisible: boolean;
// pause // pause
pauseComponentMatrix: ["load", "about", "change", "save", "exit"]; pauseComponentMatrix: ["load", "about", "change", "save", "exit"];
pauseComponentMatrixIdx: number; pauseComponentMatrixIdx: number;
@ -121,7 +126,7 @@ export const useStore = create(
combine( combine(
{ {
// scene data // scene data
currentScene: "media", currentScene: "boot",
// game progress // game progress
gameProgress: game_progress, gameProgress: game_progress,
@ -163,6 +168,11 @@ export const useStore = create(
// level selection // level selection
selectedLevel: 4, selectedLevel: 4,
// end scene
endComponentMatrix: ["end", "continue"],
endComponentMatrixIdx: 0,
endSceneSelectionVisible: false,
// pause // pause
pauseComponentMatrix: ["load", "about", "change", "save", "exit"], pauseComponentMatrix: ["load", "about", "change", "save", "exit"],
pauseComponentMatrixIdx: 2, pauseComponentMatrixIdx: 2,
@ -215,7 +225,7 @@ export const useStore = create(
gateLvl: 0, gateLvl: 0,
// player name // player name
playerName: "", playerName: "アイウエオ",
// boot scene // boot scene
mainMenuComponentMatrix: ["authorize_user", "load_data"], mainMenuComponentMatrix: ["authorize_user", "load_data"],
@ -303,6 +313,12 @@ export const useStore = create(
// level selection setters // level selection setters
setSelectedLevel: (to: number) => set(() => ({ selectedLevel: to })), setSelectedLevel: (to: number) => set(() => ({ selectedLevel: to })),
// end scene setters
setEndComponentMatrixIdx: (to: 0 | 1) =>
set(() => ({ endComponentMatrixIdx: to })),
setEndSceneSelectionVisible: (to: boolean) =>
set(() => ({ endSceneSelectionVisible: to })),
// pause setters // pause setters
setPauseComponentMatrixIdx: (to: number) => setPauseComponentMatrixIdx: (to: number) =>
set(() => ({ pauseComponentMatrixIdx: to })), set(() => ({ pauseComponentMatrixIdx: to })),
@ -519,6 +535,15 @@ export const getBootSceneContext = () => {
}; };
}; };
export const getEndSceneContext = () => {
const state = useStore.getState();
return {
activeEndComponent: state.endComponentMatrix[state.endComponentMatrixIdx],
selectionVisible: state.endSceneSelectionVisible,
};
};
export const playAudio = (audio: HTMLAudioElement) => { export const playAudio = (audio: HTMLAudioElement) => {
audio.currentTime = 0; audio.currentTime = 0;
audio.currentTime = 0; audio.currentTime = 0;

3
src/utils/sleep.ts Normal file
View file

@ -0,0 +1,3 @@
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export default sleep;