From 851b3ff597418eda7771f31b7a27cb9b82675095 Mon Sep 17 00:00:00 2001 From: ad044 Date: Thu, 25 Feb 2021 18:51:19 +0400 Subject: [PATCH] rewrote pause --- src/components/MainScene/Pause/Pause.tsx | 382 +++++------------- .../MainScene/Pause/PauseSquare.tsx | 150 +++---- .../MainScene/Site/MainSceneBackground.tsx | 6 +- .../TextRenderer/PauseBigLetter.tsx | 201 +++++---- src/core/eventTemplates.ts | 6 +- src/scenes/MainScene.tsx | 5 +- src/scenes/PolytanScene.tsx | 8 +- src/store.ts | 1 - src/types/types.ts | 3 +- 9 files changed, 323 insertions(+), 439 deletions(-) diff --git a/src/components/MainScene/Pause/Pause.tsx b/src/components/MainScene/Pause/Pause.tsx index d8b6f8b..7688cb7 100644 --- a/src/components/MainScene/Pause/Pause.tsx +++ b/src/components/MainScene/Pause/Pause.tsx @@ -3,28 +3,8 @@ import * as THREE from "three"; import PauseSquare from "./PauseSquare"; import PauseBigLetter from "../../TextRenderer/PauseBigLetter"; import { useStore } from "../../../store"; -import { useLoader } from "react-three-fiber"; const Pause = () => { - const exit = useStore((state) => state.pauseExitAnimation); - const [showActiveComponent, setShowActiveComponent] = useState(false); - const [animation, setAnimation] = useState(false); - const [intro, setIntro] = useState(true); - - const wordFont = useLoader(THREE.FontLoader, "/3d_fonts/MediaWord.blob"); - - const config = useMemo( - () => ({ - font: wordFont, - size: 2.5, - }), - [wordFont] - ); - - const activeComponent = useStore((state) => - showActiveComponent ? state.activePauseComponent : "" - ); - const generateSqaureGeom = useCallback((row: number, square: number) => { const geometry = new THREE.PlaneBufferGeometry(); const uvAttribute = geometry.attributes.uv; @@ -48,306 +28,168 @@ const Pause = () => { [generateSqaureGeom] ); - const subscene = useStore((state) => state.mainSubscene); + const letterLocs = useMemo( + () => ({ + "05": { letter: "E" }, + "11": { letter: "S" }, + "33": { letter: "C" }, + "45": { letter: "A" }, + "51": { letter: "L" }, + }), + [] + ); + const subscene = useStore((state) => state.mainSubscene); const setInputCooldown = useStore((state) => state.setInputCooldown); + const [visible, setVisible] = useState(false); + const [finished, setFinished] = useState(false); + const [exit, setExit] = useState(false); + + const activeComponent = useStore( + useCallback((state) => (finished ? state.activePauseComponent : ""), [ + finished, + ]) + ); + useEffect(() => { - setAnimation(false); - setIntro(true); - setShowActiveComponent(false); if (subscene === "pause") { - setTimeout(() => { - setTimeout(() => { - setAnimation(true); - }, 1000); - setTimeout(() => { - setShowActiveComponent(true); - setIntro(false); - setInputCooldown(1000); - }, 3500); - }, 3400); + setTimeout(() => setVisible(true), 4400); + setTimeout(() => setFinished(true), 7300); + setTimeout(() => setInputCooldown(1000), 7600); } + + return () => { + setExit(true); + setTimeout(() => { + setVisible(false); + setFinished(false); + setExit(false); + }, 1200); + }; }, [setInputCooldown, subscene]); + const whenActive = useCallback((rowIdx: number, colIdx: number) => { + switch (rowIdx) { + case 5: + if (colIdx > 1 && colIdx < 5) return "load"; + break; + case 4: + if (colIdx > 5 && colIdx < 7) return "about"; + break; + case 3: + if (colIdx > 3 && colIdx < 7) return "change"; + break; + case 1: + if (colIdx > 1 && colIdx < 5) return "save"; + break; + case 0: + if (colIdx > 4 && colIdx < 7) return "exit"; + break; + } + }, []); + return ( <> - {animation && ( - <> - - {[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 ? ( - - - - - ) : ( - + {[0, 1, 2, 3, 2, 1, 0].map((r: number, rowIdx: number) => + [0, 1, 2, 3, 4, 5, 6].map((c: number, colIdx: number) => { + const key = `${rowIdx}${colIdx}`; + + const letter = letterLocs[key as keyof typeof letterLocs]; + if (letter) + return ( + + - ); - } else if (rowIdx === 4 && col > 4 && col < 7) { - return col === 5 ? ( - - - - - ) : ( - ); - } else if (rowIdx === 3 && col > 2 && col < 7) { - return col === 3 ? ( - - - - - ) : ( - - ); - } else if (rowIdx === 1 && col > 0 && col < 5) { - return col === 1 ? ( - - - - - ) : ( - - ); - } else if (rowIdx === 0 && col > 4 && col < 7) { - return col === 5 ? ( - - - - - ) : ( - - ); - } else { - return ( - - ); - } - }) - )} - {"Load".split("").map((letter, idx) => ( + + ); + else + return ( + + ); + }) + )} + + <> + {"oad".split("").map((letter, 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]} + position={[2 / 2.8 + idx / 2.8, 5 / 2.8, 0]} active={activeComponent === "load"} /> ))} - {"About".split("").map((letter, idx) => ( + {"bout".split("").map((letter, idx) => ( 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} - position={[1.78 + idx / 2.8, 1.43, 0]} - scale={[0.25, 0.25, 0]} + position={[6 / 2.8 + idx / 2.8, 4 / 2.8, 0]} active={activeComponent === "about"} key={idx} /> ))} - {"Change".split("").map((letter, idx) => ( + + {"hange".split("").map((letter, idx) => ( 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} - position={[1.05 + idx / 2.8, 1.07, 0]} - scale={[0.25, 0.25, 0]} + position={[4 / 2.8 + idx / 2.8, 3 / 2.8, 0]} active={activeComponent === "change"} key={idx} /> ))} - {"Save".split("").map((letter, idx) => ( + + {"ave".split("").map((letter, idx) => ( 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} - position={[0.35 + idx / 2.8, 0.35, 0]} - scale={[0.25, 0.25, 0]} + position={[2 / 2.8 + idx / 2.8, 1 / 2.8, 0]} active={activeComponent === "save"} key={idx} /> ))} - {"Exit".split("").map((letter, idx) => ( + {"xit".split("").map((letter, idx) => ( 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} - position={[1.78 + idx / 2.8, 0, 0]} - scale={[0.25, 0.25, 0]} + position={[6 / 2.8 + idx / 2.8, 0, 0]} key={idx} active={activeComponent === "exit"} /> ))} - - - - - - - - - - - + + )} ); diff --git a/src/components/MainScene/Pause/PauseSquare.tsx b/src/components/MainScene/Pause/PauseSquare.tsx index 2cf9466..f0017ea 100644 --- a/src/components/MainScene/Pause/PauseSquare.tsx +++ b/src/components/MainScene/Pause/PauseSquare.tsx @@ -1,25 +1,47 @@ -import React, { useMemo, memo } from "react"; -import * as THREE from "three"; -import { useLoader } from "react-three-fiber"; +import React, { memo, useMemo } from "react"; import pauseGrayBoxes from "../../../static/sprite/pause_gray_boxes.png"; +import { useLoader } from "react-three-fiber"; +import * as THREE from "three"; import { a, useSpring } from "@react-spring/three"; -import { useStore } from "../../../store"; type PauseSquareProps = { + geometry: THREE.PlaneBufferGeometry; colIdx: number; rowIdx: number; - geometry: THREE.PlaneBufferGeometry; + letter?: string; active?: boolean; - shouldDisappear?: boolean; - intro?: boolean; + introFinished?: boolean; + exit?: boolean; }; const PauseSquare = memo((props: PauseSquareProps) => { - const exitAnimation = useStore((state) => state.pauseExitAnimation); + const squareTex = useLoader(THREE.TextureLoader, pauseGrayBoxes); - const grayBoxesTex = useLoader(THREE.TextureLoader, pauseGrayBoxes); + const introSpring = useSpring({ + from: { + posX: 1.05, + posY: 1.07, + rotZ: -1, + rotX: Math.PI, + rotY: Math.PI, + }, + to: async (next) => { + await next({ + posX: props.colIdx / 2.8, + posY: props.rowIdx / 2.8, + rotZ: 0, + config: { duration: 500 }, + }); + await next({ + rotX: 0, + rotY: props.letter ? Math.PI / 2 : 0, + delay: (props.rowIdx + props.colIdx) * 100, + config: { duration: 200 }, + }); + }, + }); - const getExitAnimValue = useMemo(() => { + const exitAnimValue = useMemo(() => { let col, row; if (props.colIdx < 3) col = -1; else if (props.colIdx > 3) col = 1; @@ -29,85 +51,47 @@ const PauseSquare = memo((props: PauseSquareProps) => { else if (props.rowIdx > 3) row = 1; else row = 0; - return { row, col }; + return { row: row * 2.2, col: col * 2.2 }; }, [props.colIdx, props.rowIdx]); - const initialState = useSpring({ - posX: props.colIdx / 2.8 + getExitAnimValue.col * (exitAnimation ? 2.2 : 0), - posY: props.rowIdx / 2.8 + getExitAnimValue.row * (exitAnimation ? 2.2 : 0), - rotX: props.active ? (exitAnimation ? Math.PI / 2 : 0) : -Math.PI, - rotY: props.active ? (exitAnimation ? Math.PI / 2 : 0) : Math.PI / 2, - rotZ: 0, - from: { posX: 1.05, posY: 1.07, rotZ: -1 }, + const spring = useSpring({ + posX: props.colIdx / 2.8 + (props.exit ? exitAnimValue.col : 0), + posY: props.rowIdx / 2.8 + (props.exit ? exitAnimValue.row : 0), + rotY: props.active || props.exit ? Math.PI / 2 : 0, + rotX: props.active ? Math.PI : 0, config: { duration: 500 }, }); - const shadowState = useSpring({ - posX: props.colIdx / 2.8 + getExitAnimValue.col * (exitAnimation ? 2.2 : 0), - posY: props.rowIdx / 2.8 + getExitAnimValue.row * (exitAnimation ? 2.2 : 0), - rotX: exitAnimation ? Math.PI / 2 : 0, - rotY: exitAnimation ? Math.PI / 2 : 0, - from: { posX: 1.05, posY: 1.07, rotZ: -1 }, - config: { duration: 500 }, - }); - - const introState = useSpring({ - rotX: 0, - rotY: props.shouldDisappear ? Math.PI / 2 : 0, - from: { rotX: Math.PI, rotY: Math.PI }, - delay: (props.rowIdx + props.colIdx) * 100 + 500, - config: { duration: 200 }, - }); - return ( - <> - 3 ? -0.25 : 0.25, - props.rowIdx <= 3 ? -0.25 : 0.25, - 0, - ]} - rotation-x={props.intro ? introState.rotX : initialState.rotX} - rotation-y={props.intro ? introState.rotY : initialState.rotY} - rotation-z={initialState.rotZ} - renderOrder={100} - > - 3 && props.rowIdx <= 3) || - (props.colIdx <= 3 && props.rowIdx > 3) - ? THREE.FrontSide - : THREE.BackSide - } - transparent={true} - depthTest={false} - /> - - - - - - - + 3 ? -0.25 : 0.25, + props.rowIdx <= 3 ? -0.25 : 0.25, + 0, + ]} + renderOrder={100} + > + 3 && props.rowIdx <= 3) || + (props.colIdx <= 3 && props.rowIdx > 3) + ? THREE.FrontSide + : THREE.BackSide + } + transparent={true} + depthTest={false} + /> + ); }); diff --git a/src/components/MainScene/Site/MainSceneBackground.tsx b/src/components/MainScene/Site/MainSceneBackground.tsx index e40b4ac..6bca867 100644 --- a/src/components/MainScene/Site/MainSceneBackground.tsx +++ b/src/components/MainScene/Site/MainSceneBackground.tsx @@ -1,9 +1,9 @@ -import React from "react"; +import React, { memo } from "react"; import mainSceneBg from "../../../static/sprite/main_scene_background.png"; import { useLoader } from "react-three-fiber"; import * as THREE from "three"; -const MainSceneBackground = () => { +const MainSceneBackground = memo(() => { const mainSceneBgTex = useLoader(THREE.TextureLoader, mainSceneBg); return ( @@ -16,6 +16,6 @@ const MainSceneBackground = () => { /> ); -}; +}); export default MainSceneBackground; diff --git a/src/components/TextRenderer/PauseBigLetter.tsx b/src/components/TextRenderer/PauseBigLetter.tsx index 347ee8f..48c229c 100644 --- a/src/components/TextRenderer/PauseBigLetter.tsx +++ b/src/components/TextRenderer/PauseBigLetter.tsx @@ -6,36 +6,22 @@ import { useLoader } from "react-three-fiber"; import orange_font_json from "../../resources/font_data/big_font.json"; import { a, useSpring } from "@react-spring/three"; import React, { useMemo, memo } from "react"; -import { useStore } from "../../store"; const PauseBigLetter = memo( (props: { - color: string; letter: string; letterIdx: number; position: number[]; - scale: number[]; - active?: boolean; rowIdx?: number; colIdx?: number; - intro?: boolean; + mainLetter?: boolean; + active?: boolean; + introFinished?: boolean; + exit?: boolean; }) => { - const exitAnimation = useStore( - (state) => state.pauseExitAnimation - ); - - const tex = useMemo(() => { - switch (props.color) { - case "white": - return whiteFont; - case "yellow": - return yellowFont; - default: - return orangeFont; - } - }, [props.color]); - - const colorTexture: THREE.Texture = useLoader(THREE.TextureLoader, tex); + const whiteFontTex = useLoader(THREE.TextureLoader, whiteFont); + const orangeFontTex = useLoader(THREE.TextureLoader, orangeFont); + const yellowFontTex = useLoader(THREE.TextureLoader, yellowFont); const lineYOffset = useMemo(() => { const lineOne = "ABCDEFGHIJKLMNOPQ"; @@ -93,64 +79,133 @@ const PauseBigLetter = memo( return geometry; }, [letterData, lineYOffset]); - const exitAnimValue = useMemo(() => { - let col = 0; - let row = 0; - if (props.colIdx && props.rowIdx) { - if (props.colIdx < 3) col = -1; - else if (props.colIdx > 3) col = 1; - - if (props.rowIdx < 3) row = -1; - else if (props.rowIdx > 3) row = 1; - - return { row, col }; - } - }, [props.colIdx, props.rowIdx]); - - const initialState = useSpring({ - posX: - props.position[0] + - (exitAnimValue ? exitAnimValue.col * (exitAnimation ? 2.2 : 0) : 0), - posY: - -letterData[4] / 50 + - props.position[1] + - (exitAnimValue ? exitAnimValue.row * (exitAnimation ? 2.2 : 0) : 0), - rotX: props.active ? (exitAnimation ? Math.PI / 2 : 0) : -Math.PI, - rotY: props.active ? (exitAnimation ? Math.PI / 2 : 0) : Math.PI / 2, + const mainLetterIntroSpring = useSpring({ + from: { + rotX: Math.PI, + rotY: Math.PI / 2, + }, + to: { rotY: 0, rotX: 0 }, + delay: (props.rowIdx! + props.colIdx!) * 100 + 500, config: { duration: 500 }, }); - const introState = useSpring({ - rotX: 0, - rotY: 0, - from: { rotX: Math.PI, rotY: Math.PI * 2 }, - delay: (props.rowIdx! + props.colIdx!) * 100 + 500, - config: { duration: 200 }, + const exitAnimValue = useMemo(() => { + let col, row; + if (props.colIdx! < 3) col = -1; + else if (props.colIdx! > 3) col = 1; + else col = 0; + + if (props.rowIdx! < 3) row = -1; + else if (props.rowIdx! > 3) row = 1; + else row = 0; + + return { row: row * 2.2, col: col * 2.2 }; + }, [props.colIdx, props.rowIdx]); + + const mainLetterSpring = useSpring({ + orangeRotY: props.active ? 0 : Math.PI / 2, + orangeRotX: props.active ? 0 : Math.PI, + whiteRotY: props.active || props.exit ? Math.PI / 2 : 0, + whiteRotX: props.active || props.exit ? Math.PI : 0, + posX: props.colIdx + ? props.colIdx / 2.8 + (props.exit ? exitAnimValue.col : 0) + : props.position[0], + posY: props.rowIdx + ? props.rowIdx / 2.8 + (props.exit ? exitAnimValue.row : 0) + : -letterData[4] / 50 + props.position[1], + config: { duration: 500 }, + }); + + const nonMainLetterSpring = useSpring({ + rotY: props.active ? 0 : Math.PI / 2, + rotX: props.active ? 0 : Math.PI, + config: { duration: 500 }, }); return ( - - - + <> + {props.mainLetter ? ( + <> + + + + + + + + ) : ( + + + + )} + ); } ); diff --git a/src/core/eventTemplates.ts b/src/core/eventTemplates.ts index 59674c2..c9bacc0 100644 --- a/src/core/eventTemplates.ts +++ b/src/core/eventTemplates.ts @@ -293,14 +293,14 @@ export const exitPause = (calculatedState: { siteRot: number[] }) => ({ { mutation: { siteRot: calculatedState.siteRot, - pauseExitAnimation: true, - activePauseComponent: "change", inputCooldown: 1400, + mainSubscene: "site", + activePauseComponent: "", }, }, { mutation: { - mainSubscene: "site", + activePauseComponent: "change", inputCooldown: false, lainMoveState: "standing", }, diff --git a/src/scenes/MainScene.tsx b/src/scenes/MainScene.tsx index 922a9f6..d49423e 100644 --- a/src/scenes/MainScene.tsx +++ b/src/scenes/MainScene.tsx @@ -1,7 +1,6 @@ import { OrbitControls } from "@react-three/drei"; import React, { Suspense, useEffect, useRef, useState } from "react"; import { playAudio, useStore } from "../store"; -import Pause from "../components/MainScene/Pause/Pause"; import LevelSelection from "../components/MainScene/LevelSelection"; import HUD from "../components/MainScene/HUD"; import MainYellowTextAnimator from "../components/TextRenderer/MainYellowTextAnimator"; @@ -19,6 +18,7 @@ import Loading from "../components/Loading"; import usePrevious from "../hooks/usePrevious"; import MainSceneBackground from "../components/MainScene/Site/MainSceneBackground"; import { useSpring, a } from "@react-spring/three"; +import Pause from "../components/MainScene/Pause/Pause"; const MainScene = () => { const intro = useStore((state) => state.intro); @@ -42,11 +42,10 @@ const MainScene = () => { setTimeout(() => setPaused(true), 3400); } else if (prevData?.subscene === "pause" && subscene === "site") { setBgState({ posY: 0 }); - setPaused(false); + setTimeout(() => setPaused(false), 1200); } }, [prevData?.subscene, setBgState, subscene]); - // move up instead of rotate todo useEffect(() => { if (wordSelected) { setTimeout(() => setWordSelected(false), 3100); diff --git a/src/scenes/PolytanScene.tsx b/src/scenes/PolytanScene.tsx index 7a72725..f87ed7d 100644 --- a/src/scenes/PolytanScene.tsx +++ b/src/scenes/PolytanScene.tsx @@ -5,10 +5,14 @@ import { useStore } from "../store"; const PolytanScene = () => { const setNodeViewed = useStore((state) => state.setNodeViewed); - const setPolytanPartUnlocked = useStore.getState().setPolytanPartUnlocked; + const setPolytanPartUnlocked = useStore( + (state) => state.setPolytanPartUnlocked + ); + const setInputCooldown = useStore((state) => state.setInputCooldown); const activeNodeName = useStore((state) => state.activeNode.node_name); useEffect(() => { + setTimeout(() => setInputCooldown(0), 1000); setNodeViewed(activeNodeName, { is_viewed: 1, is_visible: 0, @@ -30,7 +34,7 @@ const PolytanScene = () => { } })(); if (bodyPart) setPolytanPartUnlocked(bodyPart); - }, [activeNodeName, setNodeViewed, setPolytanPartUnlocked]); + }, [activeNodeName, setInputCooldown, setNodeViewed, setPolytanPartUnlocked]); return ( <> diff --git a/src/store.ts b/src/store.ts index 0d832bc..420b839 100644 --- a/src/store.ts +++ b/src/store.ts @@ -174,7 +174,6 @@ export const useStore = create( // pause activePauseComponent: "change", - pauseExitAnimation: false, showingAbout: false, permissionDenied: false, diff --git a/src/types/types.ts b/src/types/types.ts index 62f19c2..77766f5 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -20,7 +20,8 @@ export type GameScene = | "boot" | "change_disc" | "end" - | "null"; + | "null" + | "test"; export type MainSubscene = "site" | "pause" | "level_selection";