Skip to content

Commit

Permalink
separated active and inactive nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
ad044 committed Jul 26, 2022
1 parent ef4428a commit 9f28391
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 101 deletions.
59 changes: 59 additions & 0 deletions src/components/canvas/objects/MainScene/LevelNodes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import usePrevious from "@/hooks/usePrevious";
import { useStore } from "@/store";
import {
FlattenedSiteLayout,
GameSite,
MainSubscene,
NodeID,
Position,
} from "@/types";
import { getLevelY } from "@/utils/site";
import React, { memo, useEffect, useState } from "react";
import Node from "./Node";

type LevelNodesProps = {
flattenedLayout: FlattenedSiteLayout;
site: GameSite;
};

const LevelNodes = (props: LevelNodesProps) => {
const currentLevel = useStore((state) => state.level);
const paused = useStore((state) => state.mainSubscene === MainSubscene.Pause);
const currentNode = useStore((state) => state.node);
const prevData = usePrevious({ level: currentLevel });

const [nodes, setNodes] = useState<NodeID[]>(
props.flattenedLayout[currentLevel]
);
const [pos, setPos] = useState<Position>([0, getLevelY(currentLevel), 0]);

useEffect(() => {
if (prevData?.level !== currentLevel && prevData?.level !== undefined) {
if (Math.abs(prevData.level - currentLevel) === 1) {
// if only changed one level
setNodes(props.flattenedLayout[currentLevel]);
setPos([0, getLevelY(currentLevel), 0]);
} else {
// if changed from level selection
setTimeout(() => {
setNodes(props.flattenedLayout[currentLevel]);
setPos([0, getLevelY(currentLevel), 0]);
}, 1500);
}
}
}, [currentLevel, prevData?.level, props.flattenedLayout, props.site]);

return (
<group position={pos}>
{nodes.map((nodeId) => (
<Node
id={nodeId}
key={nodeId}
active={nodeId === currentNode?.id && !paused}
/>
))}
</group>
);
};

export default memo(LevelNodes);
77 changes: 0 additions & 77 deletions src/components/canvas/objects/MainScene/Levels.tsx

This file was deleted.

28 changes: 11 additions & 17 deletions src/components/canvas/objects/MainScene/Node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,21 @@ import { a, useSpring } from "@react-spring/three";
import { useStore } from "@/store";
import { LainAnimation, NodeID, Position, Rotation, Scale } from "@/types";
import useNodeTexture from "@/hooks/useNodeTexture";
import { getNode, isNodeViewed, translatePositionByAngle } from "@/utils/node";
import nodePositionsJson from "@/json/node_positions.json";
import {
getNode,
getNodeWorldPosition,
getNodeWorldRotation,
isNodeViewed,
translatePositionByAngle,
} from "@/utils/node";
import { DoubleSide, UniformsLib, UniformsUtils } from "three";
import vertex from "@/shaders/node.vert";
import fragment from "@/shaders/node.frag";
import NodeExplosion from "./NodeExplosion";
import NodeRip from "./NodeRip";
import sleep from "@/utils/sleep";
import { getRotationForSegment } from "@/utils/site";
import StaticNode from "./StaticNode";

type NodeProps = {
id: NodeID;
Expand All @@ -40,8 +46,8 @@ const Node = (props: NodeProps) => {
[gameProgress, props.id]
);

const worldPosition = nodePositionsJson[position].position as Position;
const rotation = nodePositionsJson[position].rotation as Rotation;
const worldPosition = getNodeWorldPosition(position);
const rotation = getNodeWorldRotation(position);

const { activeTexture, viewedTexture, normalTexture } = useNodeTexture(type);

Expand Down Expand Up @@ -294,19 +300,7 @@ const Node = (props: NodeProps) => {
</group>
</>
) : (
<a.mesh
position={worldPosition}
rotation={rotation}
scale={[0.36, 0.18, 0.36]}
renderOrder={1}
>
<planeBufferGeometry attach="geometry" />
<meshStandardMaterial
map={isViewed ? viewedTexture : normalTexture}
side={DoubleSide}
transparent={true}
/>
</a.mesh>
<StaticNode id={props.id} />
);
};

Expand Down
42 changes: 42 additions & 0 deletions src/components/canvas/objects/MainScene/Rings.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React, { memo, useMemo } from "react";
import PurpleRing from "./PurpleRing";
import GrayRing from "./GrayRing";
import CyanCrystal from "./CyanCrystal";
import { useStore } from "@/store";
import { getLevelLimit, getLevelY } from "@/utils/site";
import range from "@/utils/range";
import { GameSite } from "@/types";

type RingsProps = {
activateAllRings: boolean;
site: GameSite;
};

const Rings = (props: RingsProps) => {
const level = useStore((state) => state.level);

const visibleLevels: number[] = useMemo(() => {
if (props.activateAllRings) {
return range(1, getLevelLimit(props.site) + 1);
} else {
const start = Math.max(0, level - 2);
const end = Math.min(getLevelLimit(props.site) + 1, level + 2);

return range(start, end);
}
}, [level, props.activateAllRings, props.site]);

return (
<>
{visibleLevels.map((level: number) => (
<group position={[0, getLevelY(level), 0]} key={level}>
<PurpleRing level={level} site={props.site} />
<GrayRing />
<CyanCrystal />
</group>
))}
</>
);
};

export default memo(Rings);
13 changes: 7 additions & 6 deletions src/components/canvas/objects/MainScene/Site.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React, { useEffect, useMemo } from "react";
import { a, useSpring } from "@react-spring/three";
import { useStore } from "@/store";
import Levels from "./Levels";
import { FlattenedSiteLayout, MainSubscene, NodeID } from "@/types";
import { getLevelY } from "@/utils/site";
import { getRotationForSegment } from "@/utils/site";
import Rings from "./Rings";
import StaticLevelNodes from "./StaticLevelNodes";
import LevelNodes from "./LevelNodes";

type SiteProps = {
introFinished: boolean;
Expand Down Expand Up @@ -97,7 +99,7 @@ const Site = (props: SiteProps) => {
);

const siteLayout = useStore((state) => state.siteLayouts[state.site]);

const site = useStore((state) => state.site);
const layout: FlattenedSiteLayout = useMemo(() => {
return siteLayout.map((level) =>
level.flat().filter((e): e is NodeID => e !== null)
Expand All @@ -108,10 +110,9 @@ const Site = (props: SiteProps) => {
<a.group rotation-x={tiltState.tilt}>
<a.group rotation-x={rotationSpring.x}>
<a.group rotation-y={rotationSpring.y} position-y={positionSpring.y}>
<Levels
flattenedLayout={layout}
activateAllLevels={props.introFinished}
/>
<StaticLevelNodes flattenedLayout={layout} site={site} />
<LevelNodes flattenedLayout={layout} site={site} />
<Rings activateAllRings={props.introFinished} site={site} />
</a.group>
</a.group>
</a.group>
Expand Down
52 changes: 52 additions & 0 deletions src/components/canvas/objects/MainScene/StaticLevelNodes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import usePrevious from "@/hooks/usePrevious";
import { useStore } from "@/store";
import { FlattenedSiteLayout, GameSite } from "@/types";
import range from "@/utils/range";
import { getLevelLimit, getLevelY } from "@/utils/site";
import React, { memo, useEffect, useState } from "react";
import StaticNode from "./StaticNode";

type StaticLevelNodesProps = {
flattenedLayout: FlattenedSiteLayout;
site: GameSite;
};

const StaticLevelNodes = (props: StaticLevelNodesProps) => {
const currentLevel = useStore((state) => state.level);
const prevData = usePrevious({ level: currentLevel });

const [visibleLevels, setVisibleLevels] = useState<number[]>(
range(
Math.max(currentLevel - 3, 0),
Math.min(currentLevel + 3, getLevelLimit(props.site))
)
);

useEffect(() => {
if (prevData?.level !== currentLevel && prevData?.level !== undefined) {
const start = Math.max(currentLevel - 3, 1);
const end = Math.min(currentLevel + 3, getLevelLimit(props.site));
if (Math.abs(prevData.level - currentLevel) === 1) {
// if only changed one level
setVisibleLevels(range(start, end));
} else {
// if changed from level selection
setTimeout(() => setVisibleLevels(range(start, end)), 1500);
}
}
}, [currentLevel, prevData?.level, props.site]);

return (
<>
{visibleLevels.map((level) => (
<group position={[0, getLevelY(level), 0]} key={level}>
{props.flattenedLayout[level].map((nodeId) => (
<StaticNode id={nodeId} key={nodeId} />
))}
</group>
))}
</>
);
};

export default memo(StaticLevelNodes);
Loading

0 comments on commit 9f28391

Please sign in to comment.