diff --git a/src/components/MainScene/PauseSubscene/Pause.tsx b/src/components/MainScene/PauseSubscene/Pause.tsx index 319b9df..4624751 100644 --- a/src/components/MainScene/PauseSubscene/Pause.tsx +++ b/src/components/MainScene/PauseSubscene/Pause.tsx @@ -1,15 +1,18 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import * as THREE from "three"; import PauseSquare from "./PauseSquare"; -import StaticBigLetter from "../../TextRenderer/StaticBigLetter"; +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); @@ -85,7 +88,7 @@ const Pause = () => { if (rowIdx === 5 && col > 0 && col < 5) { return col === 1 ? ( - { } 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 ? ( - { }) )} {"Load".split("").map((letter, idx) => ( - 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} @@ -278,7 +281,7 @@ const Pause = () => { /> ))} {"About".split("").map((letter, idx) => ( - 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} @@ -289,7 +292,7 @@ const Pause = () => { /> ))} {"Change".split("").map((letter, idx) => ( - 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} @@ -300,7 +303,7 @@ const Pause = () => { /> ))} {"Save".split("").map((letter, idx) => ( - 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} @@ -311,7 +314,7 @@ const Pause = () => { /> ))} {"Exit".split("").map((letter, idx) => ( - 0 ? "yellow" : "orange"} letter={letter} letterIdx={idx} @@ -352,9 +355,16 @@ const Pause = () => { {showingAbout && } - - - + {promptVisible && ( + + + + )} + {permissionDenied && ( + + + + )} )} diff --git a/src/components/MainScene/PauseSubscene/PermissionDenied.tsx b/src/components/MainScene/PauseSubscene/PermissionDenied.tsx new file mode 100644 index 0000000..d5274c4 --- /dev/null +++ b/src/components/MainScene/PauseSubscene/PermissionDenied.tsx @@ -0,0 +1,36 @@ +import React, { memo } from "react"; +import headerContainer from "../../../static/sprite/prompt_question_container.png"; +import { useLoader } from "react-three-fiber"; +import * as THREE from "three"; +import StaticOrangeLetter from "../../TextRenderer/StaticOrangeLetter"; + +const PermissionDenied = memo(() => { + const headerContainerTex = useLoader(THREE.TextureLoader, headerContainer); + + return ( + <> + + + + + {"Permission denied".split("").map((letter, idx) => ( + + ))} + + + ); +}); + +export default PermissionDenied; diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index 86f3ed5..9b04843 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -9,8 +9,6 @@ import * as THREE from "three"; import { useStore } from "../store"; const Prompt = () => { - const promptVisible = useStore((state) => state.promptVisible); - const questionContainerTex = useLoader( THREE.TextureLoader, questionContainer @@ -27,82 +25,65 @@ const Prompt = () => { ) ); - useEffect(() => { - console.log(promptVisible); - }, [promptVisible]); return ( <> - {promptVisible && ( - <> - - - + + + - - - + + + - - - + + + - - - + + + - - - - - )} + + + ); }; diff --git a/src/components/TextRenderer/MediaYellowTextAnimator.tsx b/src/components/TextRenderer/MediaYellowTextAnimator.tsx index 860ea90..dc9db00 100644 --- a/src/components/TextRenderer/MediaYellowTextAnimator.tsx +++ b/src/components/TextRenderer/MediaYellowTextAnimator.tsx @@ -1,7 +1,7 @@ import React, { memo, useCallback, useEffect, useState } from "react"; import { useStore } from "../../store"; import { a, useTrail } from "@react-spring/three"; -import BigLetter from "./BigLetter"; +import SiteBigLetter from "./SiteBigLetter"; const MediaYellowTextAnimator = memo(() => { const [lastLeftComponent, setLastLeftComponent] = useState("play"); @@ -66,7 +66,7 @@ const MediaYellowTextAnimator = memo(() => { position-z={-8.7} scale={[0.04, 0.06, 0.04]} > - + ))} diff --git a/src/components/TextRenderer/StaticBigLetter.tsx b/src/components/TextRenderer/PauseBigLetter.tsx similarity index 98% rename from src/components/TextRenderer/StaticBigLetter.tsx rename to src/components/TextRenderer/PauseBigLetter.tsx index c1e3ee9..347ee8f 100644 --- a/src/components/TextRenderer/StaticBigLetter.tsx +++ b/src/components/TextRenderer/PauseBigLetter.tsx @@ -8,14 +8,14 @@ import { a, useSpring } from "@react-spring/three"; import React, { useMemo, memo } from "react"; import { useStore } from "../../store"; -const StaticBigLetter = memo( +const PauseBigLetter = memo( (props: { color: string; letter: string; letterIdx: number; position: number[]; scale: number[]; - active: boolean; + active?: boolean; rowIdx?: number; colIdx?: number; intro?: boolean; @@ -155,4 +155,4 @@ const StaticBigLetter = memo( } ); -export default StaticBigLetter; +export default PauseBigLetter; diff --git a/src/components/TextRenderer/BigLetter.tsx b/src/components/TextRenderer/SiteBigLetter.tsx similarity index 97% rename from src/components/TextRenderer/BigLetter.tsx rename to src/components/TextRenderer/SiteBigLetter.tsx index 470b2c2..847392c 100644 --- a/src/components/TextRenderer/BigLetter.tsx +++ b/src/components/TextRenderer/SiteBigLetter.tsx @@ -8,7 +8,7 @@ import React, { memo, useCallback, useEffect, useMemo, useState } from "react"; import { useStore } from "../../store"; import usePrevious from "../../hooks/usePrevious"; -const BigLetter = memo((props: { letter: string; letterIdx: number }) => { +const SiteBigLetter = memo((props: { letter: string; letterIdx: number }) => { const [color, setColor] = useState("yellow"); const tex = useMemo( @@ -158,4 +158,4 @@ const BigLetter = memo((props: { letter: string; letterIdx: number }) => { ); }); -export default BigLetter; +export default SiteBigLetter; diff --git a/src/components/TextRenderer/StaticOrangeLetter.tsx b/src/components/TextRenderer/StaticOrangeLetter.tsx new file mode 100644 index 0000000..2e22332 --- /dev/null +++ b/src/components/TextRenderer/StaticOrangeLetter.tsx @@ -0,0 +1,94 @@ +import orangeFont from "../../static/sprite/orange_font_texture.png"; +import * as THREE from "three"; +import { useLoader } from "react-three-fiber"; +import orange_font_json from "../../resources/font_data/big_font.json"; +import React, { memo, useMemo } from "react"; + +const StaticOrangeLetter = memo( + (props: { + color: string; + letter: string; + letterIdx: number; + scale: number[]; + }) => { + const colorTexture: THREE.Texture = useLoader( + THREE.TextureLoader, + orangeFont + ); + + const lineYOffset = useMemo(() => { + const lineOne = "ABCDEFGHIJKLMNOPQ"; + const lineTwo = "RSTUVWXYZ01234567"; + const lineThree = "89abcdefghijklmnopqrs"; + + let lineNum: number; + if (props.letter === " ") { + lineNum = 5; + } else { + if (lineOne.includes(props.letter)) { + lineNum = 1; + } else if (lineTwo.includes(props.letter)) { + lineNum = 2; + } else if (lineThree.includes(props.letter)) { + lineNum = 3; + } else { + lineNum = 4; + } + } + + const offsets = { + 1: 0.884, + 2: 0.765, + 3: 0.648, + 4: 0.47, + 5: 1, + }; + return offsets[lineNum as keyof typeof offsets]; + }, [props.letter]); + + const letterData = useMemo( + () => + orange_font_json.glyphs[ + props.letter as keyof typeof orange_font_json.glyphs + ], + [props.letter] + ); + + const geom = useMemo(() => { + const geometry = new THREE.PlaneBufferGeometry(); + + const uvAttribute = geometry.attributes.uv; + + for (let i = 0; i < uvAttribute.count; i++) { + let u = uvAttribute.getX(i); + let v = uvAttribute.getY(i); + + u = (u * letterData[2]) / 256 + letterData[0] / 256; + + v = (v * letterData[3]) / 136 + lineYOffset - letterData[4] / 136; + + uvAttribute.setXY(i, u, v); + } + return geometry; + }, [letterData, lineYOffset]); + + return ( + + + + ); + } +); + +export default StaticOrangeLetter; diff --git a/src/components/TextRenderer/YellowTextRenderer.tsx b/src/components/TextRenderer/YellowTextRenderer.tsx index 030adf1..f638812 100644 --- a/src/components/TextRenderer/YellowTextRenderer.tsx +++ b/src/components/TextRenderer/YellowTextRenderer.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from "react"; import { useStore } from "../../store"; import { a, useTrail } from "@react-spring/three"; -import BigLetter from "./BigLetter"; +import SiteBigLetter from "./SiteBigLetter"; import usePrevious from "../../hooks/usePrevious"; import { getNodeHud } from "../../utils/node-utils"; @@ -52,7 +52,7 @@ const YellowTextRenderer = (props: { visible?: boolean }) => { position-z={-8.7} scale={[0.04, 0.06, 0.04]} > - + ))} diff --git a/src/core/scene-keypress-handlers/handleMainKeyPress.ts b/src/core/scene-keypress-handlers/handleMainKeyPress.ts index a9fab40..3f39fc3 100644 --- a/src/core/scene-keypress-handlers/handleMainKeyPress.ts +++ b/src/core/scene-keypress-handlers/handleMainKeyPress.ts @@ -21,6 +21,7 @@ const handleMainSceneEvent = (mainSceneContext: any) => { showingAbout, promptVisible, activePromptComponent, + gateLvl, } = mainSceneContext; if (promptVisible) { @@ -310,9 +311,24 @@ const handleMainSceneEvent = (mainSceneContext: any) => { }; case "CIRCLE": if (activePauseComponent === "change") { + if (gateLvl < 4) { + return { event: "show_permission_denied" }; + } else { + return { + event: "display_prompt", + }; + } + } else if ( + activePauseComponent === "save" || + activePauseComponent === "load" + ) { return { event: "display_prompt", }; + } else { + return { + event: `pause_${activePauseComponent}_select`, + }; } } } diff --git a/src/core/setters/main/pause/pauseManager.ts b/src/core/setters/main/pause/pauseManager.ts index fe5b59a..d131d41 100644 --- a/src/core/setters/main/pause/pauseManager.ts +++ b/src/core/setters/main/pause/pauseManager.ts @@ -6,6 +6,7 @@ const pauseManager = (eventState: any) => { const setComponentMatrixIdx = useStore.getState().setPauseComponentMatrixIdx; const setExitAnimation = useStore.getState().setPauseExitAnimation; const setShowingAbout = useStore.getState().setShowingAbout; + const setPermissionDenied = useStore.getState().setPermissionDenied; const dispatchAction = (eventState: PauseManagerProps) => { switch (eventState.event) { @@ -16,7 +17,19 @@ const pauseManager = (eventState: any) => { }; case "pause_exit_select": return { - action: () => setExitAnimation(true), + action: () => { + setExitAnimation(true); + setComponentMatrixIdx(2); + }, + }; + case "show_permission_denied": + return { + action: () => { + setPermissionDenied(true); + setTimeout(() => { + setPermissionDenied(false); + }, 1200); + }, }; case "pause_about_select": return { diff --git a/src/core/setters/promptManager.ts b/src/core/setters/promptManager.ts index 323df44..a23d4fb 100644 --- a/src/core/setters/promptManager.ts +++ b/src/core/setters/promptManager.ts @@ -4,6 +4,11 @@ const promptManager = (eventState: any) => { const setComponentMatrixIdx = useStore.getState().setPromptComponentMatrixIdx; const setPromptVisible = useStore.getState().setPromptVisible; + const exitAndResetPrompt = () => { + setPromptVisible(false); + setComponentMatrixIdx(1); + }; + const dispatchAction = (eventState: { event: string; scene: string }) => { switch (eventState.event) { case "display_prompt": { @@ -16,9 +21,9 @@ const promptManager = (eventState: any) => { case "prompt_left": return { action: () => setComponentMatrixIdx(0) }; case "pause_change_select": - return { action: () => setPromptVisible(false) }; + return { action: () => exitAndResetPrompt() }; case "exit_prompt": - return { action: () => setPromptVisible(false) }; + return { action: () => exitAndResetPrompt() }; } }; diff --git a/src/store.ts b/src/store.ts index 5196456..d8ee41c 100644 --- a/src/store.ts +++ b/src/store.ts @@ -45,6 +45,7 @@ type State = { pauseComponentMatrixIdx: number; pauseExitAnimation: boolean; showingAbout: boolean; + permissionDenied: boolean; // media/media scene audioAnalyser: undefined | THREE.AudioAnalyser; @@ -195,6 +196,7 @@ export const useStore = create( pauseComponentMatrixIdx: 2, pauseExitAnimation: false, showingAbout: false, + permissionDenied: false, // media / media scene audioAnalyser: undefined, @@ -338,6 +340,8 @@ export const useStore = create( setPauseExitAnimation: (to: boolean) => set(() => ({ pauseExitAnimation: to })), setShowingAbout: (to: boolean) => set(() => ({ showingAbout: to })), + setPermissionDenied: (to: boolean) => + set(() => ({ permissionDenied: to })), // media/media scene setters toggleMediaSide: () => @@ -489,6 +493,7 @@ export const getMainSceneContext = () => { promptVisible: state.promptVisible, activePromptComponent: state.promptComponentMatrix[state.promptComponentMatrixIdx], + gateLvl: state.gateLvl, }; };