From 02cdfa5dfe0758bde37dde5da20493845517e3ca Mon Sep 17 00:00:00 2001 From: ad044 Date: Tue, 22 Dec 2020 20:55:09 +0400 Subject: [PATCH] fixed some bugs, cleaned up site --- src/components/MainScene/GrayRing.tsx | 13 ++- src/components/MainScene/PurpleRing.tsx | 40 ++++--- src/components/MainScene/Site.tsx | 100 +++++------------- .../MainScene/{ => Site}/ActiveLevelNodes.tsx | 30 ++---- .../MainScene/Site/InactiveLevelNodes.tsx | 58 ++++++++++ src/components/MainScene/Site/Rings.tsx | 35 ++++++ src/core/StateManagers/SiteManager.tsx | 91 ++++++++++++++-- src/core/mainSceneEventHandler.ts | 8 +- src/scenes/MainScene.tsx | 6 +- src/store.ts | 38 ++++++- 10 files changed, 291 insertions(+), 128 deletions(-) rename src/components/MainScene/{ => Site}/ActiveLevelNodes.tsx (62%) create mode 100644 src/components/MainScene/Site/InactiveLevelNodes.tsx create mode 100644 src/components/MainScene/Site/Rings.tsx diff --git a/src/components/MainScene/GrayRing.tsx b/src/components/MainScene/GrayRing.tsx index 9e30606..b6a9009 100644 --- a/src/components/MainScene/GrayRing.tsx +++ b/src/components/MainScene/GrayRing.tsx @@ -1,4 +1,4 @@ -import React, { memo } from "react"; +import React, { memo, useMemo } from "react"; import * as THREE from "three"; import lofTexture from "../../static/sprite/gray_ring_lof.png"; import holeTexture from "../../static/sprite/hole.png"; @@ -14,11 +14,14 @@ const GrayRing = memo((props: GrayRingProps) => { const holeTex = useLoader(THREE.TextureLoader, holeTexture); const lifeTex = useLoader(THREE.TextureLoader, lifeTexture); - const uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]); + const uniforms = useMemo(() => { + const uniform = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]); + uniform.lof = { type: "t", value: lofTex }; + uniform.hole = { type: "t", value: holeTex }; + uniform.life = { type: "t", value: lifeTex }; - uniforms.lof = { type: "t", value: lofTex }; - uniforms.hole = { type: "t", value: holeTex }; - uniforms.life = { type: "t", value: lifeTex }; + return uniform + }, [holeTex, lifeTex, lofTex]); const vertexShader = ` varying vec2 vUv; diff --git a/src/components/MainScene/PurpleRing.tsx b/src/components/MainScene/PurpleRing.tsx index 7374d66..d56f95a 100644 --- a/src/components/MainScene/PurpleRing.tsx +++ b/src/components/MainScene/PurpleRing.tsx @@ -1,14 +1,14 @@ -import React, { memo, useRef } from "react"; +import React, { memo, useEffect, useMemo, useRef } from "react"; import { useFrame, useLoader } from "react-three-fiber"; import * as THREE from "three"; import siteATex from "../../static/sprite/site_a.png"; import siteBTex from "../../static/sprite/site_b.png"; import siteLevelTex from "../../static/sprite/site_levels.png"; -import { useSiteStore } from "../../store"; type PurpleRingProps = { purpleRingPosY: number; level: string; + site: string; }; const PurpleRing = memo((props: PurpleRingProps) => { @@ -16,8 +16,6 @@ const PurpleRing = memo((props: PurpleRingProps) => { const siteB = useLoader(THREE.TextureLoader, siteBTex); const siteLevels = useLoader(THREE.TextureLoader, siteLevelTex); - const currentSite = useSiteStore((state) => state.currentSite); - const purpleRingRef = useRef(); const dispatchSiteLevelTextureOffset = (level: string) => { @@ -36,18 +34,22 @@ const PurpleRing = memo((props: PurpleRingProps) => { return siteTextures[level as keyof typeof siteTextures]; }; - const uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]); + const uniforms = useMemo(() => { + const uniform = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]); - const formattedLevel = props.level.padStart(2, "0"); + const formattedLevel = props.level.padStart(2, "0"); - uniforms.tex = { type: "t", value: currentSite === "a" ? siteA : siteB }; - uniforms.siteLevels = { type: "t", value: siteLevels }; - uniforms.siteLevelFirstCharacterOffset = { - value: dispatchSiteLevelTextureOffset(formattedLevel.charAt(0)), - }; - uniforms.siteLevelSecondCharacterOffset = { - value: dispatchSiteLevelTextureOffset(formattedLevel.charAt(1)), - }; + uniform.tex = { type: "t", value: null }; + uniform.siteLevels = { type: "t", value: siteLevels }; + uniform.siteLevelFirstCharacterOffset = { + value: dispatchSiteLevelTextureOffset(formattedLevel.charAt(0)), + }; + uniform.siteLevelSecondCharacterOffset = { + value: dispatchSiteLevelTextureOffset(formattedLevel.charAt(1)), + }; + + return uniform; + }, [props.level, siteLevels]); const vertexShader = ` varying vec2 vUv; @@ -208,14 +210,21 @@ const PurpleRing = memo((props: PurpleRingProps) => { } `; + const matRef = useRef(); useFrame(() => { purpleRingRef.current!.rotation.y += 0.005; }); + useEffect(() => { + if (matRef.current) { + matRef.current.uniforms.tex.value = props.site === "a" ? siteA : siteB; + matRef.current.uniformsNeedUpdate = true; + } + }, [props.site, siteA, siteB]); + return ( @@ -231,6 +240,7 @@ const PurpleRing = memo((props: PurpleRingProps) => { transparent={true} uniforms={uniforms} lights={true} + ref={matRef} /> ); diff --git a/src/components/MainScene/Site.tsx b/src/components/MainScene/Site.tsx index 30623b3..a396076 100644 --- a/src/components/MainScene/Site.tsx +++ b/src/components/MainScene/Site.tsx @@ -1,15 +1,9 @@ -import React, { memo, Suspense, useMemo } from "react"; -import site_a from "../../resources/site_a.json"; -import site_b from "../../resources/site_b.json"; -import level_y_values from "../../resources/level_y_values.json"; -import node_positions from "../../resources/node_positions.json"; -import Node from "./Node"; +import React, { memo, Suspense, useEffect, useState } from "react"; import { a, useSpring } from "@react-spring/three"; -import { useLevelStore, useNodeStore, useSiteStore } from "../../store"; -import PurpleRing from "./PurpleRing"; -import GrayRing from "./GrayRing"; -import CyanCrystal from "./CyanCrystal"; -import { isNodeVisible } from "../../core/nodeSelector"; +import { useSiteStore } from "../../store"; +import ActiveLevelNodes from "./Site/ActiveLevelNodes"; +import InactiveLevelNodes from "./Site/InactiveLevelNodes"; +import Rings from "./Site/Rings"; export type NodeDataType = { image_table_indices: { 1: string; 2: string; 3: string }; @@ -34,30 +28,7 @@ export type SiteType = { [key: string]: LevelType; }; -const Site = memo(() => { - const gameProgress = useNodeStore((state) => state.gameProgress); - const currentSite = useSiteStore((state) => state.currentSite); - - const siteData = currentSite === "a" ? site_a : site_b; - - const activeLevel = useLevelStore((state) => state.activeLevel); - const visibleNodes = useMemo(() => { - const obj = {}; - const activeLevelNr = parseInt(activeLevel); - const visibleLevels = [ - (activeLevelNr - 2).toString().padStart(2, "0"), - (activeLevelNr - 1).toString().padStart(2, "0"), - (activeLevelNr + 1).toString().padStart(2, "0"), - (activeLevelNr + 2).toString().padStart(2, "0"), - ]; - - visibleLevels.forEach((level) => { - Object.assign(obj, siteData[level as keyof typeof siteData]); - }); - - return obj; - }, [activeLevel, siteData]); - +const Site = () => { const siteTransformState = useSiteStore((state) => state.transformState); const siteState = useSpring({ @@ -67,51 +38,32 @@ const Site = memo(() => { config: { duration: 1200 }, }); + const introSiteState = useSpring({ + posZ: 0, + rotX: 0, + from: { posZ: -7, rotX: Math.PI / 2 }, + config: { duration: 3900 }, + }); + return ( - {Object.entries(level_y_values).map((level: [string, number]) => { - if ( - (currentSite === "b" && parseInt(level[0]) <= 13) || - currentSite === "a" - ) { - return ( - - - - - - ); - } - })} - {Object.entries(visibleNodes).map((node: [string, any]) => { - if (isNodeVisible(node[0], gameProgress, currentSite)) { - return ( - - ); - } - })} + + + {/**/} + {/**/} + + + ); -}); +}; export default Site; diff --git a/src/components/MainScene/ActiveLevelNodes.tsx b/src/components/MainScene/Site/ActiveLevelNodes.tsx similarity index 62% rename from src/components/MainScene/ActiveLevelNodes.tsx rename to src/components/MainScene/Site/ActiveLevelNodes.tsx index c02a4e1..070419a 100644 --- a/src/components/MainScene/ActiveLevelNodes.tsx +++ b/src/components/MainScene/Site/ActiveLevelNodes.tsx @@ -1,11 +1,10 @@ import React, { useMemo } from "react"; -import Node from "./Node"; -import node_positions from "../../resources/node_positions.json"; -import site_a from "../../resources/site_a.json"; -import { useNodeStore, useLevelStore, useSiteStore } from "../../store"; -import { a, useSpring } from "@react-spring/three"; -import { isNodeVisible } from "../../core/nodeSelector"; -import site_b from "../../resources/site_b.json"; +import Node from "../Node"; +import node_positions from "../../../resources/node_positions.json"; +import site_a from "../../../resources/site_a.json"; +import { useLevelStore, useNodeStore, useSiteStore } from "../../../store"; +import { isNodeVisible } from "../../../core/nodeSelector"; +import site_b from "../../../resources/site_b.json"; const ActiveLevelNodes = () => { const gameProgress = useNodeStore((state) => state.gameProgress); @@ -22,21 +21,8 @@ const ActiveLevelNodes = () => { [activeLevel, siteData] ); - const siteTransformState = useSiteStore((state) => state.transformState); - - const siteState = useSpring({ - siteRotY: siteTransformState.rotY, - sitePosY: siteTransformState.posY, - siteRotX: siteTransformState.rotX, - config: { duration: 1200 }, - }); - return ( - + <> {Object.entries(activeLevelNodes).map((node: [string, any]) => { if (isNodeVisible(node[0], gameProgress, currentSite)) { return ( @@ -57,7 +43,7 @@ const ActiveLevelNodes = () => { ); } })} - + ); }; diff --git a/src/components/MainScene/Site/InactiveLevelNodes.tsx b/src/components/MainScene/Site/InactiveLevelNodes.tsx new file mode 100644 index 0000000..454dbef --- /dev/null +++ b/src/components/MainScene/Site/InactiveLevelNodes.tsx @@ -0,0 +1,58 @@ +import React, { useMemo } from "react"; +import site_a from "../../../resources/site_a.json"; +import site_b from "../../../resources/site_b.json"; +import node_positions from "../../../resources/node_positions.json"; +import Node from "../Node"; +import { useLevelStore, useNodeStore, useSiteStore } from "../../../store"; +import { isNodeVisible } from "../../../core/nodeSelector"; + +const InactiveLevelNodes = () => { + const gameProgress = useNodeStore((state) => state.gameProgress); + const currentSite = useSiteStore((state) => state.currentSite); + + const siteData = currentSite === "a" ? site_a : site_b; + + const activeLevel = useLevelStore((state) => state.activeLevel); + const visibleNodes = useMemo(() => { + const obj = {}; + const activeLevelNr = parseInt(activeLevel); + const visibleLevels = [ + (activeLevelNr - 2).toString().padStart(2, "0"), + (activeLevelNr - 1).toString().padStart(2, "0"), + (activeLevelNr + 1).toString().padStart(2, "0"), + (activeLevelNr + 2).toString().padStart(2, "0"), + ]; + + visibleLevels.forEach((level) => { + Object.assign(obj, siteData[level as keyof typeof siteData]); + }); + + return obj; + }, [activeLevel, siteData]); + + return ( + <> + {Object.entries(visibleNodes).map((node: [string, any]) => { + if (isNodeVisible(node[0], gameProgress, currentSite)) { + return ( + + ); + } + })} + + ); +}; + +export default InactiveLevelNodes; diff --git a/src/components/MainScene/Site/Rings.tsx b/src/components/MainScene/Site/Rings.tsx new file mode 100644 index 0000000..09c5710 --- /dev/null +++ b/src/components/MainScene/Site/Rings.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import level_y_values from "../../../resources/level_y_values.json"; +import { useSiteStore } from "../../../store"; +import PurpleRing from "../PurpleRing"; +import GrayRing from "../GrayRing"; +import CyanCrystal from "../CyanCrystal"; + +const Rings = () => { + const currentSite = useSiteStore((state) => state.currentSite); + + return ( + <> + {Object.entries(level_y_values).map((level: [string, number]) => { + if ( + (currentSite === "b" && parseInt(level[0]) <= 13) || + currentSite === "a" + ) { + return ( + + + + + + ); + } + })} + + ); +}; + +export default Rings; diff --git a/src/core/StateManagers/SiteManager.tsx b/src/core/StateManagers/SiteManager.tsx index 89b1bfe..8f25714 100644 --- a/src/core/StateManagers/SiteManager.tsx +++ b/src/core/StateManagers/SiteManager.tsx @@ -1,12 +1,66 @@ import { useCallback, useEffect } from "react"; -import { useSiteStore } from "../../store"; +import { useSiteSaveStore, useSiteStore } from "../../store"; import { StateManagerProps } from "./EventManager"; const SiteManager = (props: StateManagerProps) => { const setTransformState = useSiteStore((state) => state.setTransformState); + const setCurrentSite = useSiteStore((state) => state.setCurrentSite); + + const setSiteSaveState = useSiteSaveStore((state) => state.setSiteSaveState); + const siteASaveState = useSiteSaveStore((state) => state.a); + const siteBSaveState = useSiteSaveStore((state) => state.b); + + const changeSite = useCallback( + ( + currentSite: string, + activeNodeId: string, + activeNodeMatrixIndices: { + matrixIdx: number; + rowIdx: number; + colIdx: number; + }, + siteRotY: number, + sitePosY: number, + newSite: string + ) => { + setSiteSaveState(currentSite, { + activeNodeId: activeNodeId, + nodeMatrixIndices: activeNodeMatrixIndices, + siteRotY: siteRotY, + sitePosY: sitePosY, + }); + + const siteToLoad = newSite === "a" ? siteASaveState : siteBSaveState; + + setCurrentSite(newSite); + setTransformState(siteToLoad.rotY, "rotY"); + setTransformState(siteToLoad.posY, "posY"); + + console.log(newSite) + }, + [ + setCurrentSite, + setSiteSaveState, + setTransformState, + siteASaveState, + siteBSaveState, + ] + ); const dispatchObject = useCallback( - (event: string, newSitePosY: number, newSiteRotY: number) => { + ( + event: string, + newSitePosY: number, + newSiteRotY: number, + currentSite: string, + newSite: string, + activeNodeId: string, + activeNodeMatrixIndices: { + matrixIdx: number; + rowIdx: number; + colIdx: number; + } + ) => { switch (event) { case "site_up": case "site_down": @@ -27,7 +81,7 @@ const SiteManager = (props: StateManagerProps) => { case "pause_game": return { action: setTransformState, - value: [Math.PI / 2 - 0.5, "rotX"], + value: [Math.PI / 2, "rotX"], actionDelay: 0, }; case "pause_exit_select": @@ -36,9 +90,22 @@ const SiteManager = (props: StateManagerProps) => { value: [0, "rotX"], actionDelay: 0, }; + case "pause_change_select": + return { + action: changeSite, + value: [ + currentSite, + activeNodeId, + activeNodeMatrixIndices, + newSiteRotY, + newSitePosY, + newSite, + ], + actionDelay: 0, + }; } }, - [setTransformState] + [changeSite, setTransformState] ); useEffect(() => { @@ -46,16 +113,28 @@ const SiteManager = (props: StateManagerProps) => { const eventAction = props.eventState.event; const newSiteRotY = props.eventState.newSiteRotY; const newSitePosY = props.eventState.newSitePosY; + const activeNodeId = props.eventState.activeNodeId; + const activeNodeMatrixIndices = props.eventState.activeNodeMatrixIndices; + + const currentSite = props.eventState.currentSite; + const newSite = props.eventState.newSite; const dispatchedObject = dispatchObject( eventAction, newSitePosY, - newSiteRotY + newSiteRotY, + currentSite, + newSite, + activeNodeId, + activeNodeMatrixIndices ); if (dispatchedObject) { setTimeout(() => { - dispatchedObject.action.apply(null, dispatchedObject.value as any); + (dispatchedObject.action as any).apply( + null, + dispatchedObject.value as any + ); }, dispatchedObject.actionDelay); } } diff --git a/src/core/mainSceneEventHandler.ts b/src/core/mainSceneEventHandler.ts index ecb7022..36298ff 100644 --- a/src/core/mainSceneEventHandler.ts +++ b/src/core/mainSceneEventHandler.ts @@ -22,7 +22,7 @@ const handleMainSceneEvent = (gameContext: any) => { const siteRotY = gameContext.siteTransformState.rotY; const sitePosY = gameContext.siteTransformState.posY; - let newActiveNodeId; + let newActiveNodeId = gameContext.activeNodeId; let newActiveHudId; let newLevel = parseInt(gameContext.activeLevel); let newSiteRotY = gameContext.siteTransformState.rotY; @@ -191,6 +191,12 @@ const handleMainSceneEvent = (gameContext: any) => { case "CIRCLE": return { event: `pause_${activePauseComponent}_select`, + currentSite: currentSite, + newSitePosY: newSitePosY, + newtSiteRotY: newSiteRotY, + activeNodeId: newActiveNodeId, + activeNodeMatrixIndices: nodeMatrixIndices, + newSite: currentSite === "a" ? "b" : "a", }; } } diff --git a/src/scenes/MainScene.tsx b/src/scenes/MainScene.tsx index 4767607..377eff9 100644 --- a/src/scenes/MainScene.tsx +++ b/src/scenes/MainScene.tsx @@ -10,7 +10,6 @@ import { useMainSceneStore } from "../store"; import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer"; import HUD from "../components/MainScene/HUD"; import YellowOrb from "../components/MainScene/YellowOrb"; -import ActiveLevelNodes from "../components/MainScene/ActiveLevelNodes"; import YellowTextRenderer from "../components/TextRenderer/YellowTextRenderer"; import LevelSelection from "../components/MainScene/LevelSelection"; import Pause from "../components/MainScene/PauseSubscene/Pause"; @@ -22,12 +21,11 @@ const MainScene = () => { const isPaused = currentSubscene === "pause"; return ( - + - @@ -45,7 +43,7 @@ const MainScene = () => { - + ); }; export default MainScene; diff --git a/src/store.ts b/src/store.ts index 7f185b4..f1db2b5 100644 --- a/src/store.ts +++ b/src/store.ts @@ -258,6 +258,10 @@ export const useHudStore = create((set) => ({ export const useNodeStore = create( combine( { + siteASave: { + activeNodeId: "0422", + nodeMatrixIndices: { matrixIdx: 7, rowIdx: 0, colIdx: 0 }, + }, activeNodeState: { id: "0422", posX: 0, @@ -299,7 +303,7 @@ export const useStarfieldStore = create((set) => ({ export const useSiteStore = create( combine( { - currentSite: "b", + currentSite: "a", transformState: { posY: 0, rotY: 0, @@ -311,6 +315,8 @@ export const useSiteStore = create( set((state) => ({ transformState: { ...state.transformState, [at]: to }, })), + setCurrentSite: (to: string) => + set(() => ({ currentSite: to as "a" | "b" })), }) ) ); @@ -516,3 +522,33 @@ export const usePauseStore = create((set) => ({ setComponentMatrixIdx: (to) => set(() => ({ componentMatrixIdx: to })), setExitAnimation: (to) => set(() => ({ exitAnimation: to })), })); + +export const useSiteSaveStore = create( + combine( + { + a: { + activeNodeId: "0422", + nodeMatrixIndices: { matrixIdx: 7, rowIdx: 0, colIdx: 0 }, + siteRotY: 0, + sitePosY: 0, + }, + b: { + activeNodeId: "0422", + nodeMatrixIndices: { matrixIdx: 7, rowIdx: 0, colIdx: 0 }, + siteRotY: 0, + sitePosY: 0, + }, + } as any, + (set) => ({ + setSiteSaveState: ( + site: string, + to: { + activeNodeId: string; + nodeMatrixIndices: { matrixIdx: 7; rowIdx: 0; colIdx: 0 }; + siteRotY: number; + sitePosY: number; + } + ) => set(() => ({ site: to })), + }) + ) +);