fixed some bugs, cleaned up site

This commit is contained in:
ad044 2020-12-22 20:55:09 +04:00
parent ac5edb303f
commit 02cdfa5dfe
10 changed files with 291 additions and 128 deletions

View file

@ -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;

View file

@ -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<THREE.Object3D>();
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<THREE.ShaderMaterial>();
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 (
<mesh
position={[0, props.purpleRingPosY, 0]}
renderOrder={1}
scale={[26, 26, 26]}
ref={purpleRingRef}
>
@ -231,6 +240,7 @@ const PurpleRing = memo((props: PurpleRingProps) => {
transparent={true}
uniforms={uniforms}
lights={true}
ref={matRef}
/>
</mesh>
);

View file

@ -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 (
<Suspense fallback={null}>
<a.group
rotation-y={siteState.siteRotY}
position-y={siteState.sitePosY}
rotation-x={siteState.siteRotX}
rotation-x={introSiteState.rotX}
position-z={introSiteState.posZ}
>
{Object.entries(level_y_values).map((level: [string, number]) => {
if (
(currentSite === "b" && parseInt(level[0]) <= 13) ||
currentSite === "a"
) {
return (
<group position={[0, level[1], 0]} key={level[0]}>
<PurpleRing purpleRingPosY={0.44} level={level[0]} />
<GrayRing grayRingPosY={-0.29} />
<CyanCrystal crystalRingPosY={-0.45} />
</group>
);
}
})}
{Object.entries(visibleNodes).map((node: [string, any]) => {
if (isNodeVisible(node[0], gameProgress, currentSite)) {
return (
<Node
sprite={node[1].node_name}
position={
node_positions[
node[0].substr(2) as keyof typeof node_positions
].position
}
rotation={
node_positions[
node[0].substr(2) as keyof typeof node_positions
].rotation
}
key={node[1].node_name}
level={node[0].substr(0, 2)}
/>
);
}
})}
<a.group rotation-x={siteState.siteRotX}>
<a.group
rotation-y={siteState.siteRotY}
position-y={siteState.sitePosY}
>
{/*<ActiveLevelNodes />*/}
{/*<InactiveLevelNodes />*/}
<Rings />
</a.group>
</a.group>
</a.group>
</Suspense>
);
});
};
export default Site;

View file

@ -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 (
<a.group
rotation-y={siteState.siteRotY}
position-y={siteState.sitePosY}
rotation-x={siteState.siteRotX}
>
<>
{Object.entries(activeLevelNodes).map((node: [string, any]) => {
if (isNodeVisible(node[0], gameProgress, currentSite)) {
return (
@ -57,7 +43,7 @@ const ActiveLevelNodes = () => {
);
}
})}
</a.group>
</>
);
};

View file

@ -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 (
<Node
sprite={node[1].node_name}
position={
node_positions[node[0].substr(2) as keyof typeof node_positions]
.position
}
rotation={
node_positions[node[0].substr(2) as keyof typeof node_positions]
.rotation
}
key={node[1].node_name}
level={node[0].substr(0, 2)}
/>
);
}
})}
</>
);
};
export default InactiveLevelNodes;

View file

@ -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 (
<group position={[0, level[1], 0]} key={level[0]}>
<PurpleRing
purpleRingPosY={0.44}
level={level[0]}
site={currentSite}
/>
<GrayRing grayRingPosY={-0.29} />
<CyanCrystal crystalRingPosY={-0.45} />
</group>
);
}
})}
</>
);
};
export default Rings;

View file

@ -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);
}
}

View file

@ -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",
};
}
}

View file

@ -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 (
<a.perspectiveCamera position-z={3}>
<perspectiveCamera position-z={3}>
<Suspense fallback={null}>
<a.group>
<Preloader />
<Site />
<ActiveLevelNodes />
<HUD visible={!isPaused} />
<GreenTextRenderer visible={!isPaused} />
<YellowTextRenderer visible={!isPaused} />
@ -45,7 +43,7 @@ const MainScene = () => {
</a.group>
<Lain />
</Suspense>
</a.perspectiveCamera>
</perspectiveCamera>
);
};
export default MainScene;

View file

@ -258,6 +258,10 @@ export const useHudStore = create<HUDState>((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<StarfieldState>((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<PauseState>((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 })),
})
)
);