mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
fixed bugs, optimized node generation
This commit is contained in:
parent
acceaa149a
commit
51cbd41c93
10 changed files with 294 additions and 108 deletions
|
@ -1,14 +1,17 @@
|
||||||
import React, { useCallback } from "react";
|
import React, { useEffect, useRef } from "react";
|
||||||
import level_selection_font from "../../../static/sprite/select_level_font.png";
|
import level_selection_font from "../../../static/sprite/select_level_font.png";
|
||||||
import verticalHud from "../../../static/sprite/select_level_hud_vertical.png";
|
import verticalHud from "../../../static/sprite/select_level_hud_vertical.png";
|
||||||
import horizontalHud from "../../../static/sprite/select_level_hud_horizontal.png";
|
import horizontalHud from "../../../static/sprite/select_level_hud_horizontal.png";
|
||||||
import levelSelectionText from "../../../static/sprite/select_level_text.png";
|
import levelSelectionText from "../../../static/sprite/select_level_text.png";
|
||||||
import upArrow from "../../../static/sprite/select_level_up_arrow.png";
|
import upArrow from "../../../static/sprite/select_level_up_arrow.png";
|
||||||
import downArrow from "../../../static/sprite/select_level_down_arrow.png";
|
import downArrow from "../../../static/sprite/select_level_down_arrow.png";
|
||||||
|
import upArrowActive from "../../../static/sprite/select_level_up_arrow_active.png";
|
||||||
|
import downArrowActive from "../../../static/sprite/select_level_down_arrow_active.png";
|
||||||
import { useStore } from "../../../store";
|
import { useStore } from "../../../store";
|
||||||
import { useLoader } from "react-three-fiber";
|
import { useLoader } from "react-three-fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { a, useSpring } from "@react-spring/three";
|
import { a, useSpring } from "@react-spring/three";
|
||||||
|
import usePrevious from "../../../hooks/usePrevious";
|
||||||
|
|
||||||
const LevelSelection = () => {
|
const LevelSelection = () => {
|
||||||
const levelSelectionFontTex = useLoader(
|
const levelSelectionFontTex = useLoader(
|
||||||
|
@ -23,47 +26,108 @@ const LevelSelection = () => {
|
||||||
);
|
);
|
||||||
const upArrowTex = useLoader(THREE.TextureLoader, upArrow);
|
const upArrowTex = useLoader(THREE.TextureLoader, upArrow);
|
||||||
const downArrowTex = useLoader(THREE.TextureLoader, downArrow);
|
const downArrowTex = useLoader(THREE.TextureLoader, downArrow);
|
||||||
|
const upArrowActiveTex = useLoader(THREE.TextureLoader, upArrowActive);
|
||||||
const toggled = useStore(
|
const downArrowActiveTex = useLoader(THREE.TextureLoader, downArrowActive);
|
||||||
useCallback((state) => Number(state.mainSubscene === "level_selection"), [])
|
|
||||||
);
|
|
||||||
|
|
||||||
const selectedLevel = useStore((state) => state.selectedLevel)
|
const selectedLevel = useStore((state) => state.selectedLevel)
|
||||||
.toString()
|
.toString()
|
||||||
.padStart(2, "0");
|
.padStart(2, "0");
|
||||||
|
const activeLevel = useStore((state) => state.activeLevel);
|
||||||
|
const subscene = useStore((state) => state.mainSubscene);
|
||||||
|
const prevData = usePrevious({ subscene, selectedLevel });
|
||||||
|
|
||||||
const { levelSelectionToggle } = useSpring({
|
const [pos, set] = useSpring(() => ({
|
||||||
levelSelectionToggle: toggled,
|
vertPosY: -2.5,
|
||||||
|
horizPosX: -4,
|
||||||
config: { duration: 500 },
|
config: { duration: 500 },
|
||||||
});
|
}));
|
||||||
|
|
||||||
const verticalHudPosY = levelSelectionToggle.to([0, 1], [-2.5, 0]);
|
const fstNumberRef = useRef<THREE.Mesh>();
|
||||||
const horizontalHudPosX = levelSelectionToggle.to([0, 1], [-4, -0.6]);
|
const sndNumberRef = useRef<THREE.Mesh>();
|
||||||
|
const upArrowRef = useRef<THREE.Sprite>();
|
||||||
|
const downArrowRef = useRef<THREE.Sprite>();
|
||||||
|
|
||||||
const generateGeom = useCallback((number: number) => {
|
useEffect(() => {
|
||||||
const geometry = new THREE.PlaneBufferGeometry();
|
const generateGeom = (number: number) => {
|
||||||
|
const geometry = new THREE.PlaneBufferGeometry();
|
||||||
|
|
||||||
const uvAttribute = geometry.attributes.uv;
|
const uvAttribute = geometry.attributes.uv;
|
||||||
|
|
||||||
for (let i = 0; i < uvAttribute.count; i++) {
|
for (let i = 0; i < uvAttribute.count; i++) {
|
||||||
let u = uvAttribute.getX(i);
|
let u = uvAttribute.getX(i);
|
||||||
let v = uvAttribute.getY(i);
|
let v = uvAttribute.getY(i);
|
||||||
|
|
||||||
u = (u * 22) / 240 + number / 10;
|
u = (u * 22) / 240 + number / 10;
|
||||||
|
|
||||||
uvAttribute.setXY(i, u, v);
|
uvAttribute.setXY(i, u, v);
|
||||||
|
}
|
||||||
|
return geometry;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (subscene === "level_selection") {
|
||||||
|
set({ vertPosY: 0, horizPosX: -0.6 });
|
||||||
|
if (fstNumberRef.current && sndNumberRef.current) {
|
||||||
|
fstNumberRef.current.geometry = generateGeom(parseInt(activeLevel[0]));
|
||||||
|
sndNumberRef.current.geometry = generateGeom(parseInt(activeLevel[1]));
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
subscene === "site" &&
|
||||||
|
prevData?.subscene === "level_selection"
|
||||||
|
) {
|
||||||
|
set({ vertPosY: -2.5, horizPosX: -4 });
|
||||||
}
|
}
|
||||||
return geometry;
|
if (selectedLevel !== prevData?.selectedLevel) {
|
||||||
}, []);
|
if (fstNumberRef.current && sndNumberRef.current) {
|
||||||
|
fstNumberRef.current.geometry = generateGeom(
|
||||||
|
parseInt(selectedLevel[0])
|
||||||
|
);
|
||||||
|
sndNumberRef.current.geometry = generateGeom(
|
||||||
|
parseInt(selectedLevel[1])
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
prevData?.selectedLevel &&
|
||||||
|
upArrowRef.current &&
|
||||||
|
downArrowRef.current
|
||||||
|
) {
|
||||||
|
if (selectedLevel > prevData?.selectedLevel) {
|
||||||
|
upArrowRef.current.material.map = upArrowActiveTex;
|
||||||
|
upArrowRef.current.material.needsUpdate = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
upArrowRef.current!.material.map = upArrowTex;
|
||||||
|
upArrowRef.current!.material.needsUpdate = true;
|
||||||
|
}, 100);
|
||||||
|
} else if (selectedLevel < prevData?.selectedLevel) {
|
||||||
|
downArrowRef.current.material.map = downArrowActiveTex;
|
||||||
|
downArrowRef.current.material.needsUpdate = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
downArrowRef.current!.material.map = downArrowTex;
|
||||||
|
downArrowRef.current!.material.needsUpdate = true;
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [
|
||||||
|
activeLevel,
|
||||||
|
downArrowActiveTex,
|
||||||
|
prevData?.selectedLevel,
|
||||||
|
prevData?.subscene,
|
||||||
|
selectedLevel,
|
||||||
|
set,
|
||||||
|
subscene,
|
||||||
|
upArrowActiveTex,
|
||||||
|
upArrowTex,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group>
|
<group>
|
||||||
<a.group position-y={verticalHudPosY} renderOrder={5}>
|
<a.group position-y={pos.vertPosY} renderOrder={5}>
|
||||||
<mesh
|
<mesh
|
||||||
scale={[0.3, 0.4, 0]}
|
scale={[0.3, 0.4, 0]}
|
||||||
position={[0.95, 0, 0]}
|
position={[0.95, 0, 0]}
|
||||||
renderOrder={5}
|
renderOrder={5}
|
||||||
geometry={generateGeom(parseInt(selectedLevel[0]))}
|
ref={fstNumberRef}
|
||||||
>
|
>
|
||||||
<meshBasicMaterial
|
<meshBasicMaterial
|
||||||
map={levelSelectionFontTex}
|
map={levelSelectionFontTex}
|
||||||
|
@ -76,7 +140,7 @@ const LevelSelection = () => {
|
||||||
scale={[0.3, 0.4, 0]}
|
scale={[0.3, 0.4, 0]}
|
||||||
position={[1.23, 0, 0]}
|
position={[1.23, 0, 0]}
|
||||||
renderOrder={5}
|
renderOrder={5}
|
||||||
geometry={generateGeom(parseInt(selectedLevel[1]))}
|
ref={sndNumberRef}
|
||||||
>
|
>
|
||||||
<meshBasicMaterial
|
<meshBasicMaterial
|
||||||
map={levelSelectionFontTex}
|
map={levelSelectionFontTex}
|
||||||
|
@ -106,20 +170,28 @@ const LevelSelection = () => {
|
||||||
scale={[0.3, 0.15, 0]}
|
scale={[0.3, 0.15, 0]}
|
||||||
position={[1.1, -0.35, 0]}
|
position={[1.1, -0.35, 0]}
|
||||||
renderOrder={4}
|
renderOrder={4}
|
||||||
|
ref={downArrowRef}
|
||||||
>
|
>
|
||||||
<spriteMaterial
|
<spriteMaterial
|
||||||
map={downArrowTex}
|
map={downArrowTex}
|
||||||
attach="material"
|
attach="material"
|
||||||
transparent={true}
|
transparent={true}
|
||||||
depthTest={false}
|
depthTest={false}
|
||||||
|
color={0xffffff}
|
||||||
/>
|
/>
|
||||||
</sprite>
|
</sprite>
|
||||||
<sprite scale={[0.3, 0.15, 0]} position={[1.1, 0.5, 0]} renderOrder={4}>
|
<sprite
|
||||||
|
scale={[0.3, 0.15, 0]}
|
||||||
|
position={[1.1, 0.5, 0]}
|
||||||
|
renderOrder={4}
|
||||||
|
ref={upArrowRef}
|
||||||
|
>
|
||||||
<spriteMaterial
|
<spriteMaterial
|
||||||
map={upArrowTex}
|
map={upArrowTex}
|
||||||
attach="material"
|
attach="material"
|
||||||
transparent={true}
|
transparent={true}
|
||||||
depthTest={false}
|
depthTest={false}
|
||||||
|
color={0xffffff}
|
||||||
/>
|
/>
|
||||||
</sprite>
|
</sprite>
|
||||||
</a.group>
|
</a.group>
|
||||||
|
@ -128,7 +200,7 @@ const LevelSelection = () => {
|
||||||
scale={[3, 0.3, 0]}
|
scale={[3, 0.3, 0]}
|
||||||
position={[-0.6, 0, 0]}
|
position={[-0.6, 0, 0]}
|
||||||
renderOrder={4}
|
renderOrder={4}
|
||||||
position-x={horizontalHudPosX}
|
position-x={pos.horizPosX}
|
||||||
>
|
>
|
||||||
<spriteMaterial
|
<spriteMaterial
|
||||||
map={horizontalHudTex}
|
map={horizontalHudTex}
|
||||||
|
|
|
@ -95,8 +95,8 @@ const Site = (props: SiteProps) => {
|
||||||
rotation-y={siteState.siteRotY}
|
rotation-y={siteState.siteRotY}
|
||||||
position-y={siteState.sitePosY}
|
position-y={siteState.sitePosY}
|
||||||
>
|
>
|
||||||
<ActiveLevelNodes />
|
<ActiveLevelNodes visibleNodes={visibleNodes} />
|
||||||
{/*<InactiveLevelNodes />*/}
|
<InactiveLevelNodes visibleNodes={visibleNodes} />
|
||||||
<NodeAnimations />
|
<NodeAnimations />
|
||||||
<Rings
|
<Rings
|
||||||
activateAllRings={props.shouldIntro ? props.introFinished : true}
|
activateAllRings={props.shouldIntro ? props.introFinished : true}
|
||||||
|
|
|
@ -9,13 +9,11 @@ import { NodeDataType, SiteType } from "../Site";
|
||||||
import usePrevious from "../../../../hooks/usePrevious";
|
import usePrevious from "../../../../hooks/usePrevious";
|
||||||
|
|
||||||
type ActiveLevelNodesProps = {
|
type ActiveLevelNodesProps = {
|
||||||
visibleNodes: any;
|
visibleNodes: SiteType;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
||||||
const activeNodeId = useStore((state) => state.activeNode.id);
|
const activeNodeId = useStore((state) => state.activeNode.id);
|
||||||
const gameProgress = useStore((state) => state.gameProgress);
|
|
||||||
const currentSite = useStore((state) => state.activeSite);
|
|
||||||
const activeLevel = useStore((state) => state.activeLevel);
|
const activeLevel = useStore((state) => state.activeLevel);
|
||||||
const prevData = usePrevious({ activeLevel });
|
const prevData = usePrevious({ activeLevel });
|
||||||
|
|
||||||
|
@ -24,7 +22,6 @@ const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const siteData = currentSite === "a" ? site_a : site_b;
|
|
||||||
if (
|
if (
|
||||||
prevData?.activeLevel !== activeLevel &&
|
prevData?.activeLevel !== activeLevel &&
|
||||||
prevData?.activeLevel !== undefined
|
prevData?.activeLevel !== undefined
|
||||||
|
@ -32,36 +29,38 @@ const ActiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
||||||
const prevLevel = parseInt(prevData?.activeLevel);
|
const prevLevel = parseInt(prevData?.activeLevel);
|
||||||
const newLevel = parseInt(activeLevel);
|
const newLevel = parseInt(activeLevel);
|
||||||
if (prevLevel - 1 === newLevel || prevLevel + 1 === newLevel) {
|
if (prevLevel - 1 === newLevel || prevLevel + 1 === newLevel) {
|
||||||
setVisibleNodes(siteData[activeLevel as keyof typeof siteData]);
|
setVisibleNodes(
|
||||||
|
props.visibleNodes[activeLevel as keyof typeof props.visibleNodes]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setVisibleNodes(siteData[activeLevel as keyof typeof siteData]);
|
setVisibleNodes(
|
||||||
|
props.visibleNodes[activeLevel as keyof typeof props.visibleNodes]
|
||||||
|
);
|
||||||
}, 1500);
|
}, 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [activeLevel, currentSite, gameProgress, prevData?.activeLevel]);
|
}, [activeLevel, prevData?.activeLevel, props, props.visibleNodes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Object.values(visibleNodes).map((node: NodeDataType) => {
|
{Object.values(visibleNodes).map((node: NodeDataType) => {
|
||||||
if (isNodeVisible(node, gameProgress)) {
|
return (
|
||||||
return (
|
<Node
|
||||||
<Node
|
nodeName={node.node_name}
|
||||||
nodeName={node.node_name}
|
position={
|
||||||
position={
|
node_positions[node.id.substr(2) as keyof typeof node_positions]
|
||||||
node_positions[node.id.substr(2) as keyof typeof node_positions]
|
.position
|
||||||
.position
|
}
|
||||||
}
|
rotation={
|
||||||
rotation={
|
node_positions[node.id.substr(2) as keyof typeof node_positions]
|
||||||
node_positions[node.id.substr(2) as keyof typeof node_positions]
|
.rotation
|
||||||
.rotation
|
}
|
||||||
}
|
key={node.node_name}
|
||||||
key={node.node_name}
|
active={node.id === activeNodeId}
|
||||||
active={node.id === activeNodeId}
|
level={node.id.substr(0, 2)}
|
||||||
level={node.id.substr(0, 2)}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
import React, { memo, useMemo } from "react";
|
||||||
|
import { useLoader } from "react-three-fiber";
|
||||||
|
import { a } from "@react-spring/three";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import Cou from "../../../../static/sprite/Cou.png";
|
||||||
|
import Dc from "../../../../static/sprite/Dc.png";
|
||||||
|
import SSkn from "../../../../static/sprite/SSkn.png";
|
||||||
|
import Tda from "../../../../static/sprite/Tda.png";
|
||||||
|
import Dia from "../../../../static/sprite/Dia.png";
|
||||||
|
import Lda from "../../../../static/sprite/Lda.png";
|
||||||
|
import MULTI from "../../../../static/sprite/MULTI.png";
|
||||||
|
import level_y_values from "../../../../resources/level_y_values.json";
|
||||||
|
|
||||||
|
type NodeContructorProps = {
|
||||||
|
nodeName: string;
|
||||||
|
position: number[];
|
||||||
|
rotation: number[];
|
||||||
|
level: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const InactiveLevelNode = memo((props: NodeContructorProps) => {
|
||||||
|
const tex = useMemo(() => {
|
||||||
|
if (props.nodeName.includes("S")) {
|
||||||
|
return SSkn;
|
||||||
|
} else if (
|
||||||
|
props.nodeName.startsWith("P") ||
|
||||||
|
props.nodeName.startsWith("G") ||
|
||||||
|
props.nodeName.includes("?")
|
||||||
|
) {
|
||||||
|
return MULTI;
|
||||||
|
} else if (props.nodeName.includes("Dc")) {
|
||||||
|
return Dc;
|
||||||
|
} else {
|
||||||
|
switch (props.nodeName.substr(0, 3)) {
|
||||||
|
case "Tda":
|
||||||
|
return Tda;
|
||||||
|
case "Cou":
|
||||||
|
return Cou;
|
||||||
|
case "Dia":
|
||||||
|
return Dia;
|
||||||
|
case "Lda":
|
||||||
|
return Lda;
|
||||||
|
case "Ere":
|
||||||
|
case "Ekm":
|
||||||
|
case "Eda":
|
||||||
|
case "TaK":
|
||||||
|
case "Env":
|
||||||
|
return MULTI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [props.nodeName]);
|
||||||
|
|
||||||
|
const nonActiveTexture = useLoader(THREE.TextureLoader, tex!);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<group
|
||||||
|
position={[
|
||||||
|
0,
|
||||||
|
level_y_values[props.level as keyof typeof level_y_values],
|
||||||
|
0,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
<a.mesh
|
||||||
|
position-x={props.position[0]}
|
||||||
|
position-y={props.position[1]}
|
||||||
|
position-z={props.position[2]}
|
||||||
|
rotation-y={props.rotation[1]}
|
||||||
|
rotation-z={0}
|
||||||
|
scale={[0.36, 0.18, 0.36]}
|
||||||
|
renderOrder={1}
|
||||||
|
>
|
||||||
|
<planeBufferGeometry attach="geometry" />
|
||||||
|
<meshStandardMaterial
|
||||||
|
attach="material"
|
||||||
|
map={nonActiveTexture}
|
||||||
|
side={THREE.DoubleSide}
|
||||||
|
transparent={true}
|
||||||
|
/>
|
||||||
|
</a.mesh>
|
||||||
|
</group>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default InactiveLevelNode;
|
|
@ -1,59 +1,60 @@
|
||||||
import React, { useMemo, memo } from "react";
|
import React, { memo, useEffect, useState } from "react";
|
||||||
import Node from "./Node";
|
|
||||||
import node_positions from "../../../../resources/node_positions.json";
|
import node_positions from "../../../../resources/node_positions.json";
|
||||||
import { useStore } from "../../../../store";
|
import { useStore } from "../../../../store";
|
||||||
import { isNodeVisible } from "../../../../core/nodeSelector";
|
import { SiteType } from "../Site";
|
||||||
import site_a from "../../../../resources/site_a.json";
|
import InactiveLevelNode from "./InactiveLevelNode";
|
||||||
import site_b from "../../../../resources/site_b.json";
|
import usePrevious from "../../../../hooks/usePrevious";
|
||||||
|
import { generateInactiveNodes } from "../../../../core/utils/nodeUtils";
|
||||||
|
|
||||||
const InactiveLevelNodes = memo(() => {
|
type ActiveLevelNodesProps = {
|
||||||
const gameProgress = useStore((state) => state.gameProgress);
|
visibleNodes: SiteType;
|
||||||
|
};
|
||||||
const currentSite = useStore((state) => state.activeSite);
|
|
||||||
|
|
||||||
const siteData = useMemo(() => (currentSite === "a" ? site_a : site_b), [
|
|
||||||
currentSite,
|
|
||||||
]);
|
|
||||||
|
|
||||||
|
const InactiveLevelNodes = memo((props: ActiveLevelNodesProps) => {
|
||||||
const activeLevel = useStore((state) => state.activeLevel);
|
const activeLevel = useStore((state) => state.activeLevel);
|
||||||
|
const prevData = usePrevious({ activeLevel });
|
||||||
|
|
||||||
const visibleNodes = useMemo(() => {
|
const [visibleNodes, setVisibleNodes] = useState<{}>(
|
||||||
const obj = {};
|
generateInactiveNodes(props.visibleNodes, activeLevel)
|
||||||
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) => {
|
useEffect(() => {
|
||||||
Object.assign(obj, siteData[level as keyof typeof siteData]);
|
if (
|
||||||
});
|
prevData?.activeLevel !== activeLevel &&
|
||||||
|
prevData?.activeLevel !== undefined
|
||||||
return obj;
|
) {
|
||||||
}, [activeLevel, siteData]);
|
const prevLevel = parseInt(prevData?.activeLevel);
|
||||||
|
const newLevel = parseInt(activeLevel);
|
||||||
|
if (prevLevel - 1 === newLevel || prevLevel + 1 === newLevel) {
|
||||||
|
setVisibleNodes(generateInactiveNodes(props.visibleNodes, activeLevel));
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
setVisibleNodes(
|
||||||
|
generateInactiveNodes(props.visibleNodes, activeLevel)
|
||||||
|
);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [activeLevel, prevData?.activeLevel, props.visibleNodes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{Object.entries(visibleNodes).map((node: [string, any]) => {
|
{Object.entries(visibleNodes).map((node: [string, any]) => {
|
||||||
if (isNodeVisible(node[1], gameProgress)) {
|
return (
|
||||||
return (
|
<InactiveLevelNode
|
||||||
<Node
|
nodeName={node[1].node_name}
|
||||||
nodeName={node[1].node_name}
|
position={
|
||||||
position={
|
node_positions[node[0].substr(2) as keyof typeof node_positions]
|
||||||
node_positions[node[0].substr(2) as keyof typeof node_positions]
|
.position
|
||||||
.position
|
}
|
||||||
}
|
rotation={
|
||||||
rotation={
|
node_positions[node[0].substr(2) as keyof typeof node_positions]
|
||||||
node_positions[node[0].substr(2) as keyof typeof node_positions]
|
.rotation
|
||||||
.rotation
|
}
|
||||||
}
|
key={node[1].node_name}
|
||||||
key={node[1].node_name}
|
level={node[0].substr(0, 2)}
|
||||||
level={node[0].substr(0, 2)}
|
/>
|
||||||
/>
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
})}
|
})}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -23,7 +23,7 @@ type NodeContructorProps = {
|
||||||
nodeName: string;
|
nodeName: string;
|
||||||
position: number[];
|
position: number[];
|
||||||
rotation: number[];
|
rotation: number[];
|
||||||
active?: boolean;
|
active: boolean;
|
||||||
level: string;
|
level: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,17 @@ const LevelSelectionManager = (props: StateManagerProps) => {
|
||||||
const setSelectedLevel = useStore((state) => state.setSelectedLevel);
|
const setSelectedLevel = useStore((state) => state.setSelectedLevel);
|
||||||
|
|
||||||
const dispatchObject = useCallback(
|
const dispatchObject = useCallback(
|
||||||
(eventState: { event: string; selectedLevelIdx: number }) => {
|
(eventState: {
|
||||||
|
event: string;
|
||||||
|
selectedLevelIdx: number;
|
||||||
|
level: number;
|
||||||
|
}) => {
|
||||||
switch (eventState.event) {
|
switch (eventState.event) {
|
||||||
|
case "toggle_level_selection":
|
||||||
|
return {
|
||||||
|
action: setSelectedLevel,
|
||||||
|
value: eventState.level,
|
||||||
|
};
|
||||||
case "level_selection_up":
|
case "level_selection_up":
|
||||||
case "level_selection_down":
|
case "level_selection_down":
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -90,7 +90,7 @@ const handleMainSceneEvent = (gameContext: any) => {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "L2":
|
case "L2":
|
||||||
return { event: "toggle_level_selection" };
|
return { event: "toggle_level_selection", level: level };
|
||||||
case "TRIANGLE":
|
case "TRIANGLE":
|
||||||
return { event: "pause_game" };
|
return { event: "pause_game" };
|
||||||
case "SPACE":
|
case "SPACE":
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
import {
|
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
|
||||||
NodeDataType,
|
|
||||||
SiteType,
|
|
||||||
} from "../../components/MainScene/SyncedComponents/Site";
|
|
||||||
import game_progress from "../../resources/initial_progress.json";
|
import game_progress from "../../resources/initial_progress.json";
|
||||||
import { isNodeVisible } from "../nodeSelector";
|
import { isNodeVisible } from "../nodeSelector";
|
||||||
|
|
||||||
|
@ -9,10 +6,13 @@ const filterInvisibleNodes = (
|
||||||
siteData: SiteType,
|
siteData: SiteType,
|
||||||
gameProgress: typeof game_progress
|
gameProgress: typeof game_progress
|
||||||
) => {
|
) => {
|
||||||
const visibleNodes: NodeDataType[] = [];
|
const visibleNodes: SiteType = {};
|
||||||
Object.values(siteData).forEach((level) => {
|
Object.entries(siteData).forEach((level) => {
|
||||||
Object.values(level).forEach((node) => {
|
visibleNodes[level[0]] = {};
|
||||||
if (isNodeVisible(node, gameProgress)) visibleNodes.push(node);
|
Object.entries(level[1]).forEach((node) => {
|
||||||
|
if (isNodeVisible(node[1], gameProgress)) {
|
||||||
|
visibleNodes[level[0]][node[0]] = node[1];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
21
src/core/utils/nodeUtils.ts
Normal file
21
src/core/utils/nodeUtils.ts
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import { SiteType } from "../../components/MainScene/SyncedComponents/Site";
|
||||||
|
|
||||||
|
export const generateInactiveNodes = (
|
||||||
|
visibleNodes: SiteType,
|
||||||
|
activeLevel: string
|
||||||
|
) => {
|
||||||
|
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, visibleNodes[level as keyof typeof visibleNodes]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
};
|
Loading…
Reference in a new issue