mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
transient updates on text renderer, adding gate scene
This commit is contained in:
parent
83fc6e1e53
commit
ea87f6f97f
17 changed files with 299 additions and 70 deletions
|
@ -8,6 +8,7 @@ import MediaPlayer from "./components/MediaScene/MediaPlayer";
|
|||
import MediaScene from "./scenes/MediaScene";
|
||||
import EventManager from "./components/StateManagers/EventManager";
|
||||
import { useSceneStore } from "./store";
|
||||
import GateScene from "./scenes/GateScene";
|
||||
|
||||
const App = () => {
|
||||
const [moveToGame, setMoveToGame] = useState(false);
|
||||
|
@ -24,6 +25,7 @@ const App = () => {
|
|||
return {
|
||||
main: <MainScene />,
|
||||
media: <MediaScene />,
|
||||
gate: <GateScene />,
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
|
56
src/components/GateScene/GateMiddle.tsx
Normal file
56
src/components/GateScene/GateMiddle.tsx
Normal file
|
@ -0,0 +1,56 @@
|
|||
import React, { useMemo } from "react";
|
||||
import * as THREE from "three";
|
||||
|
||||
const GateMiddle = () => {
|
||||
const uniforms = useMemo(
|
||||
() => ({
|
||||
color1: {
|
||||
value: new THREE.Color("white"),
|
||||
},
|
||||
color2: {
|
||||
value: new THREE.Color("red"),
|
||||
},
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
const vertexShader = `
|
||||
varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
vUv = uv;
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
const fragmentShader = `
|
||||
uniform vec3 color1;
|
||||
uniform vec3 color2;
|
||||
uniform float alpha;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
float alpha = smoothstep(0.0, 1.0, vUv.y);
|
||||
float colorMix = smoothstep(1.0, 2.0, 1.8);
|
||||
|
||||
gl_FragColor = vec4(mix(color1, color2, colorMix), alpha);
|
||||
}
|
||||
`;
|
||||
|
||||
return (
|
||||
<>
|
||||
<mesh scale={[2,2,2]}>
|
||||
<planeBufferGeometry attach="geometry"></planeBufferGeometry>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
uniforms={uniforms}
|
||||
/>
|
||||
</mesh>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GateMiddle;
|
54
src/components/GateScene/GateSide.tsx
Normal file
54
src/components/GateScene/GateSide.tsx
Normal file
|
@ -0,0 +1,54 @@
|
|||
import React, { useMemo, useRef } from "react";
|
||||
import blueBinary from "../../static/sprite/blue_binary.png";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
const GateSide = () => {
|
||||
const blueBinaryTex = useLoader(THREE.TextureLoader, blueBinary);
|
||||
|
||||
const texture = useMemo(() => {
|
||||
blueBinaryTex.wrapS = THREE.RepeatWrapping;
|
||||
blueBinaryTex.wrapT = THREE.RepeatWrapping;
|
||||
blueBinaryTex.repeat.set(5, 5);
|
||||
|
||||
return blueBinaryTex;
|
||||
}, [blueBinaryTex]);
|
||||
|
||||
useFrame(() => {
|
||||
if (Date.now() % 2 === 0) {
|
||||
texture.offset.y += 0.5;
|
||||
}
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<mesh
|
||||
rotation={[0, 0.2, 0]}
|
||||
position={[-1.7, 0, 1.5]}
|
||||
scale={[3, 1.5, 0]}
|
||||
>
|
||||
<planeBufferGeometry attach="geometry"></planeBufferGeometry>
|
||||
<meshBasicMaterial
|
||||
attach="material"
|
||||
map={texture}
|
||||
transparent={true}
|
||||
opacity={0.6}
|
||||
/>
|
||||
</mesh>
|
||||
<mesh
|
||||
rotation={[0, -0.2, 0]}
|
||||
position={[1.7, 0, 1.5]}
|
||||
scale={[3, 1.5, 0]}
|
||||
>
|
||||
<planeBufferGeometry attach="geometry"></planeBufferGeometry>
|
||||
<meshBasicMaterial
|
||||
attach="material"
|
||||
map={texture}
|
||||
transparent={true}
|
||||
opacity={0.6}
|
||||
/>
|
||||
</mesh>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default GateSide;
|
|
@ -1,4 +1,4 @@
|
|||
import React, { memo, Suspense, useMemo } from "react";
|
||||
import React, { memo, Suspense } from "react";
|
||||
import site_a from "../../resources/site_a.json";
|
||||
import Level from "./Level";
|
||||
import level_y_values from "../../resources/level_y_values.json";
|
||||
|
@ -6,8 +6,6 @@ import blue_orb_positions from "../../resources/blue_orb_positions.json";
|
|||
import BlueOrb from "./BlueOrb";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { useBlueOrbStore, useLevelStore, useSiteStore } from "../../store";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
const Site = memo(() => {
|
||||
const activeBlueOrbId = useBlueOrbStore((state) => state.activeBlueOrbId);
|
||||
|
|
|
@ -21,13 +21,15 @@ type BlueOrbDispatcher = {
|
|||
move_left: BlueOrbDispatchData;
|
||||
move_right: BlueOrbDispatchData;
|
||||
change_blue_orb: BlueOrbDispatchData;
|
||||
throw_blue_orb: BlueOrbDispatchData;
|
||||
throw_blue_orb_media: BlueOrbDispatchData;
|
||||
throw_blue_orb_gate: BlueOrbDispatchData;
|
||||
};
|
||||
|
||||
const BlueOrbManager = (props: StateManagerProps) => {
|
||||
const setActiveBlueOrb = useBlueOrbStore((state) => state.setActiveBlueOrbId);
|
||||
const setBlueOrbRowIdx = useBlueOrbStore((state) => state.setBlueOrbRowIdx);
|
||||
const setBlueOrbColIdx = useBlueOrbStore((state) => state.setBlueOrbColIdx);
|
||||
const setBlueOrbMatrixIndices = useBlueOrbStore(
|
||||
(state) => state.setBlueOrbMatrixIndices
|
||||
);
|
||||
|
||||
const setIsActiveBlueOrbInteractedWith: SetIsActiveBlueOrbInteractedWith = useBlueOrbStore(
|
||||
(state) => state.setIsActiveBlueOrbInteractedWith
|
||||
|
@ -76,18 +78,21 @@ const BlueOrbManager = (props: StateManagerProps) => {
|
|||
const updateActiveBlueOrb = useCallback(
|
||||
(
|
||||
delay: number,
|
||||
isMoving: boolean,
|
||||
newActiveBlueOrbId: string,
|
||||
newBlueOrbColIdx: number,
|
||||
newBlueOrbRowIdx: number
|
||||
) => {
|
||||
setActiveBlueOrb("");
|
||||
if (isMoving) setActiveBlueOrb("");
|
||||
setTimeout(() => {
|
||||
setActiveBlueOrb(newActiveBlueOrbId);
|
||||
setBlueOrbColIdx(newBlueOrbColIdx);
|
||||
setBlueOrbRowIdx(newBlueOrbRowIdx);
|
||||
setBlueOrbMatrixIndices({
|
||||
rowIdx: newBlueOrbRowIdx,
|
||||
colIdx: newBlueOrbColIdx,
|
||||
});
|
||||
}, delay);
|
||||
},
|
||||
[setActiveBlueOrb, setBlueOrbColIdx, setBlueOrbRowIdx]
|
||||
[setActiveBlueOrb, setBlueOrbMatrixIndices]
|
||||
);
|
||||
|
||||
const dispatchObject = useCallback(
|
||||
|
@ -102,6 +107,7 @@ const BlueOrbManager = (props: StateManagerProps) => {
|
|||
action: updateActiveBlueOrb,
|
||||
value: [
|
||||
3903.704,
|
||||
true,
|
||||
newActiveBlueOrbId,
|
||||
newBlueOrbColIdx,
|
||||
newBlueOrbRowIdx,
|
||||
|
@ -111,6 +117,7 @@ const BlueOrbManager = (props: StateManagerProps) => {
|
|||
action: updateActiveBlueOrb,
|
||||
value: [
|
||||
3903.704,
|
||||
true,
|
||||
newActiveBlueOrbId,
|
||||
newBlueOrbColIdx,
|
||||
newBlueOrbRowIdx,
|
||||
|
@ -120,6 +127,7 @@ const BlueOrbManager = (props: StateManagerProps) => {
|
|||
action: updateActiveBlueOrb,
|
||||
value: [
|
||||
3903.704,
|
||||
true,
|
||||
newActiveBlueOrbId,
|
||||
newBlueOrbColIdx,
|
||||
newBlueOrbRowIdx,
|
||||
|
@ -129,6 +137,7 @@ const BlueOrbManager = (props: StateManagerProps) => {
|
|||
action: updateActiveBlueOrb,
|
||||
value: [
|
||||
3903.704,
|
||||
true,
|
||||
newActiveBlueOrbId,
|
||||
newBlueOrbColIdx,
|
||||
newBlueOrbRowIdx,
|
||||
|
@ -136,9 +145,19 @@ const BlueOrbManager = (props: StateManagerProps) => {
|
|||
},
|
||||
change_blue_orb: {
|
||||
action: updateActiveBlueOrb,
|
||||
value: [0, newActiveBlueOrbId, newBlueOrbColIdx, newBlueOrbRowIdx],
|
||||
value: [
|
||||
0,
|
||||
false,
|
||||
newActiveBlueOrbId,
|
||||
newBlueOrbColIdx,
|
||||
newBlueOrbRowIdx,
|
||||
],
|
||||
},
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: animateActiveBlueOrbThrow,
|
||||
value: [0, true],
|
||||
},
|
||||
throw_blue_orb_gate: {
|
||||
action: animateActiveBlueOrbThrow,
|
||||
value: [0, true],
|
||||
},
|
||||
|
|
|
@ -48,8 +48,7 @@ export type StateManagerProps = {
|
|||
export type GameContext = {
|
||||
keyPress?: string;
|
||||
scene: string;
|
||||
blueOrbRowIdx: number;
|
||||
blueOrbColIdx: number;
|
||||
blueOrbMatrixIndices: { rowIdx: number; colIdx: number };
|
||||
currentLevel: string;
|
||||
siteRotIdx: string;
|
||||
activeMediaComponent: string;
|
||||
|
@ -59,8 +58,9 @@ const EventManager = () => {
|
|||
const currentScene = useSceneStore((state) => state.currentScene);
|
||||
|
||||
// main scene
|
||||
const blueOrbRowIdx = useBlueOrbStore((state) => state.blueOrbRowIdx);
|
||||
const blueOrbColIdx = useBlueOrbStore((state) => state.blueOrbColIdx);
|
||||
const blueOrbMatrixIndices = useBlueOrbStore(
|
||||
(state) => state.blueOrbMatrixIndices
|
||||
);
|
||||
const siteRotIdx = useSiteStore((state) => state.siteRotIdx);
|
||||
const currentLevel = useLevelStore((state) => state.currentLevel);
|
||||
|
||||
|
@ -77,15 +77,13 @@ const EventManager = () => {
|
|||
() => ({
|
||||
scene: currentScene,
|
||||
siteRotIdx: siteRotIdx,
|
||||
blueOrbRowIdx: blueOrbRowIdx,
|
||||
blueOrbColIdx: blueOrbColIdx,
|
||||
blueOrbMatrixIndices: blueOrbMatrixIndices,
|
||||
currentLevel: currentLevel,
|
||||
activeMediaComponent: activeMediaComponent,
|
||||
}),
|
||||
[
|
||||
activeMediaComponent,
|
||||
blueOrbColIdx,
|
||||
blueOrbRowIdx,
|
||||
blueOrbMatrixIndices,
|
||||
currentLevel,
|
||||
currentScene,
|
||||
siteRotIdx,
|
||||
|
|
|
@ -84,7 +84,7 @@ const GreenTextManager = (props: StateManagerProps) => {
|
|||
action: toggleAndSetGreenText,
|
||||
value: [newActiveBlueOrbId, newActiveHudId, 500],
|
||||
},
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: initializeGreenTextForMediaScene,
|
||||
value: [],
|
||||
},
|
||||
|
|
|
@ -28,7 +28,12 @@ const LainManager = (props: StateManagerProps) => {
|
|||
value: "move_right",
|
||||
duration: 3904.704,
|
||||
},
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: setLainMoveState,
|
||||
value: "throwBlueOrb",
|
||||
duration: 3904.704,
|
||||
},
|
||||
throw_blue_orb_gate: {
|
||||
action: setLainMoveState,
|
||||
value: "throwBlueOrb",
|
||||
duration: 3904.704,
|
||||
|
|
|
@ -101,7 +101,7 @@ const MediaComponentManager = (props: StateManagerProps) => {
|
|||
action: switchToLeftSide,
|
||||
value: "thirdWord",
|
||||
},
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: setActiveMediaComponent,
|
||||
value: "play",
|
||||
},
|
||||
|
|
|
@ -49,7 +49,7 @@ const MediaImageManager = (props: StateManagerProps) => {
|
|||
const dispatchObject = useCallback(
|
||||
(event: string, newActiveBlueOrbId: string) => {
|
||||
const dispatcherObjects = {
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: updateSceneImages,
|
||||
value: newActiveBlueOrbId,
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@ type MediaWordDispatchData = {
|
|||
sndWord_up: MediaWordDispatcher;
|
||||
thirdWord_down: MediaWordDispatcher;
|
||||
thirdWord_up: MediaWordDispatcher;
|
||||
throw_blue_orb: MediaWordDispatcher;
|
||||
throw_blue_orb_media: MediaWordDispatcher;
|
||||
};
|
||||
|
||||
const MediaWordManager = (props: StateManagerProps) => {
|
||||
|
@ -52,7 +52,7 @@ const MediaWordManager = (props: StateManagerProps) => {
|
|||
action: addToWordPositionDataStructIdx,
|
||||
value: -1,
|
||||
},
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: resetWordPositionDataStructIdx,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -8,7 +8,12 @@ const SceneManager = (props: StateManagerProps) => {
|
|||
const dispatchObject = useCallback(
|
||||
(event: string, newScene: string) => {
|
||||
const dispatcherObjects = {
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: setScene,
|
||||
value: newScene,
|
||||
delay: 3904.704,
|
||||
},
|
||||
throw_blue_orb_gate: {
|
||||
action: setScene,
|
||||
value: newScene,
|
||||
delay: 3904.704,
|
||||
|
|
|
@ -41,7 +41,7 @@ type YellowTextDispatcher = {
|
|||
change_blue_orb: YellowTextDispatchData;
|
||||
play_down: YellowTextDispatchData;
|
||||
exit_up: YellowTextDispatchData;
|
||||
throw_blue_orb: YellowTextDispatchData;
|
||||
throw_blue_orb_media: YellowTextDispatchData;
|
||||
exit_media_scene: YellowTextDispatchData;
|
||||
};
|
||||
|
||||
|
@ -258,7 +258,7 @@ const YellowTextManager = (props: any) => {
|
|||
action: animateMediaYellowText,
|
||||
value: ["Exit", [-0.8, -0.08, 0.6]],
|
||||
},
|
||||
throw_blue_orb: {
|
||||
throw_blue_orb_media: {
|
||||
action: initializeYellowTextForMediaScene,
|
||||
},
|
||||
exit_media_scene: {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import { a, useSpring, useTrail } from "@react-spring/three";
|
||||
import React, { useEffect, useMemo } from "react";
|
||||
import { useSiteStore, useTextRendererStore } from "../../store";
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import {
|
||||
TextRendererState,
|
||||
useSiteStore,
|
||||
useTextRendererStore,
|
||||
} from "../../store";
|
||||
import BigLetter from "./BigLetter";
|
||||
import MediumLetter from "./MediumLetter";
|
||||
|
||||
|
@ -14,22 +18,34 @@ const TextRenderer = () => {
|
|||
const isSiteChangingY = useSiteStore((state) => state.isSiteChangingY);
|
||||
|
||||
// ======================================= YELLOW TEXT ======================================
|
||||
const yellowText = useTextRendererStore((state) => state.yellowText);
|
||||
const yellowTextArr = useMemo(() => yellowText.split(""), [yellowText]);
|
||||
const yellowTextPosY = useTextRendererStore((state) => state.yellowTextPosY);
|
||||
|
||||
// yellow text posx and posy need to be updated reactively aswell when changing site rotation/y value
|
||||
const yellowTextPosX = useTextRendererStore((state) => state.yellowTextPosX);
|
||||
const yellowTextPosY = useTextRendererStore((state) => state.yellowTextPosY);
|
||||
|
||||
const yellowTextOffsetXCoeff = useTextRendererStore(
|
||||
(state) => state.yellowTextOffsetXCoeff
|
||||
);
|
||||
|
||||
const yellowTextArrRef = useRef(
|
||||
useTextRendererStore.getState().yellowText.split("")
|
||||
);
|
||||
|
||||
const yellowTextPosXRef = useRef(
|
||||
useTextRendererStore.getState().yellowTextPosX
|
||||
);
|
||||
const yellowTextPosYRef = useRef(
|
||||
useTextRendererStore.getState().yellowTextPosY
|
||||
);
|
||||
|
||||
// this is used to animate the letters moving one after another
|
||||
const yellowLetterTrail = useTrail(yellowText.length, {
|
||||
yellowLetterPosX: yellowTextPosX,
|
||||
yellowLetterPosY: yellowTextPosY,
|
||||
const yellowLetterTrail = useTrail(yellowTextArrRef.current.length, {
|
||||
yellowLetterPosX: yellowTextPosXRef.current,
|
||||
yellowLetterPosY: yellowTextPosYRef.current,
|
||||
config: { duration: 280 },
|
||||
});
|
||||
|
||||
// this is used when the GROUP itself has to be animated in a "static" manner
|
||||
// this is used when the whole GROUP itself needs to be animated
|
||||
const yellowLetterSpring = useSpring({
|
||||
yellowLetterPosX: yellowTextPosX,
|
||||
yellowLetterPosY: yellowTextPosY,
|
||||
|
@ -38,14 +54,21 @@ const TextRenderer = () => {
|
|||
|
||||
// ==================================== GREEN TEXT ============================================
|
||||
|
||||
const greenText = useTextRendererStore((state) => state.greenText);
|
||||
const greenTextPosY = useTextRendererStore((state) => state.greenTextPosY);
|
||||
const greenTextPosXObj = useTextRendererStore((state) => state.greenTextPosX);
|
||||
const greenTextArr = useMemo(() => greenText.split(""), [greenText]);
|
||||
const greenTextActive = useTextRendererStore(
|
||||
(state) => state.greenTextActive
|
||||
);
|
||||
|
||||
const greenTextPosYRef = useRef(
|
||||
useTextRendererStore.getState().greenTextPosY
|
||||
);
|
||||
|
||||
const greenTextPosXRef = useRef(
|
||||
useTextRendererStore.getState().greenTextPosX
|
||||
);
|
||||
|
||||
const greenTextArrRef = useRef(
|
||||
useTextRendererStore.getState().greenText.split("")
|
||||
);
|
||||
const { greenTextPosXToggle } = useSpring({
|
||||
greenTextPosXToggle: greenTextActive,
|
||||
config: { duration: 500 },
|
||||
|
@ -53,13 +76,34 @@ const TextRenderer = () => {
|
|||
|
||||
const greenTextPosX = greenTextPosXToggle.to(
|
||||
[0, 1],
|
||||
[greenTextPosXObj.initial, greenTextPosXObj.final]
|
||||
[greenTextPosXRef.current.initial, greenTextPosXRef.current.final]
|
||||
);
|
||||
|
||||
// subscribing to state and updating transiently
|
||||
useEffect(
|
||||
() =>
|
||||
useTextRendererStore.subscribe(
|
||||
(state) => {
|
||||
yellowTextPosXRef.current = (state as TextRendererState).yellowTextPosX;
|
||||
yellowTextPosYRef.current = (state as TextRendererState).yellowTextPosY;
|
||||
yellowTextArrRef.current = (state as TextRendererState).yellowText.split(
|
||||
""
|
||||
);
|
||||
greenTextPosYRef.current = (state as TextRendererState).greenTextPosY;
|
||||
greenTextPosXRef.current = (state as TextRendererState).greenTextPosX;
|
||||
greenTextArrRef.current = (state as TextRendererState).greenText.split(
|
||||
""
|
||||
);
|
||||
},
|
||||
(state) => state
|
||||
),
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<group position={[0, 0, 10]}>
|
||||
{isSiteChangingY
|
||||
? yellowTextArr.map((letter, idx) => (
|
||||
? yellowTextArrRef.current.map((letter, idx) => (
|
||||
<a.group
|
||||
key={idx}
|
||||
position-x={yellowLetterSpring.yellowLetterPosX}
|
||||
|
@ -69,8 +113,8 @@ const TextRenderer = () => {
|
|||
>
|
||||
<BigLetter
|
||||
color={"yellow"}
|
||||
yellowTextOffsetXCoeff={yellowTextOffsetXCoeff}
|
||||
letter={yellowTextArr[idx]}
|
||||
yellowTextOffsetXCoeff={0}
|
||||
letter={yellowTextArrRef.current[idx]}
|
||||
letterIdx={idx}
|
||||
key={idx}
|
||||
/>
|
||||
|
@ -88,7 +132,7 @@ const TextRenderer = () => {
|
|||
<BigLetter
|
||||
color={"yellow"}
|
||||
yellowTextOffsetXCoeff={yellowTextOffsetXCoeff}
|
||||
letter={yellowTextArr[idx]}
|
||||
letter={yellowTextArrRef.current[idx]}
|
||||
letterIdx={idx}
|
||||
key={idx}
|
||||
/>
|
||||
|
@ -98,11 +142,11 @@ const TextRenderer = () => {
|
|||
|
||||
<a.group
|
||||
position-x={greenTextPosX}
|
||||
position-y={greenTextPosY}
|
||||
position-y={greenTextPosYRef.current}
|
||||
position-z={-8.7}
|
||||
scale={[0.02, 0.035, 0.02]}
|
||||
>
|
||||
{greenTextArr.map((letter, idx) => (
|
||||
{greenTextArrRef.current.map((letter, idx) => (
|
||||
<MediumLetter
|
||||
color={"yellow"}
|
||||
letter={letter}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { GameContext } from "../components/StateManagers/EventManager";
|
||||
import available_blue_orbs_on_projection from "../resources/available_blue_orbs_on_projection.json";
|
||||
import site_a from "../resources/site_a.json";
|
||||
|
||||
const hudAssocs = {
|
||||
"00": "fg_hud_1",
|
||||
|
@ -21,26 +22,31 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
|
|||
|
||||
const keyPress = gameContext.keyPress;
|
||||
|
||||
let newBlueOrbColIdx = gameContext.blueOrbColIdx;
|
||||
let newBlueOrbRowIdx = gameContext.blueOrbRowIdx;
|
||||
const blueOrbColIdx = gameContext.blueOrbMatrixIndices.colIdx;
|
||||
const blueOrbRowIdx = gameContext.blueOrbMatrixIndices.rowIdx;
|
||||
|
||||
let newBlueOrbColIdx = gameContext.blueOrbMatrixIndices.colIdx;
|
||||
let newBlueOrbRowIdx = gameContext.blueOrbMatrixIndices.rowIdx;
|
||||
let newLevel = gameContext.currentLevel;
|
||||
let newSiteRotIdx: string | number = gameContext.siteRotIdx;
|
||||
let newSiteRotIdx = gameContext.siteRotIdx;
|
||||
let newScene = gameContext.scene;
|
||||
|
||||
switch (keyPress) {
|
||||
case "left":
|
||||
newBlueOrbColIdx = gameContext.blueOrbColIdx - 1;
|
||||
newBlueOrbColIdx = blueOrbColIdx - 1;
|
||||
if (newBlueOrbColIdx < 0) {
|
||||
event = "move_left";
|
||||
newSiteRotIdx = parseInt(gameContext.siteRotIdx) + 1;
|
||||
if (newSiteRotIdx > 8) newSiteRotIdx = "1";
|
||||
newSiteRotIdx =
|
||||
parseInt(gameContext.siteRotIdx) + 1 > 8
|
||||
? "1"
|
||||
: (parseInt(gameContext.siteRotIdx) + 1).toString();
|
||||
newBlueOrbColIdx = 0;
|
||||
} else {
|
||||
event = "change_blue_orb";
|
||||
}
|
||||
break;
|
||||
case "down":
|
||||
newBlueOrbRowIdx = gameContext.blueOrbRowIdx + 1;
|
||||
newBlueOrbRowIdx = blueOrbRowIdx + 1;
|
||||
if (newBlueOrbRowIdx > 2) {
|
||||
event = "move_down";
|
||||
|
||||
|
@ -53,7 +59,7 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
|
|||
}
|
||||
break;
|
||||
case "up":
|
||||
newBlueOrbRowIdx = gameContext.blueOrbRowIdx - 1;
|
||||
newBlueOrbRowIdx = blueOrbRowIdx - 1;
|
||||
if (newBlueOrbRowIdx < 0) {
|
||||
event = "move_up";
|
||||
|
||||
|
@ -67,18 +73,45 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
|
|||
}
|
||||
break;
|
||||
case "right":
|
||||
newBlueOrbColIdx = gameContext.blueOrbColIdx + 1;
|
||||
newBlueOrbColIdx = blueOrbColIdx + 1;
|
||||
if (newBlueOrbColIdx > 3) {
|
||||
event = "move_right";
|
||||
newSiteRotIdx = (parseInt(gameContext.siteRotIdx) - 1).toString();
|
||||
newSiteRotIdx =
|
||||
parseInt(gameContext.siteRotIdx) - 1 < 1
|
||||
? "8"
|
||||
: (parseInt(gameContext.siteRotIdx) - 1).toString();
|
||||
|
||||
newBlueOrbColIdx = 3;
|
||||
} else {
|
||||
event = "change_blue_orb";
|
||||
}
|
||||
break;
|
||||
case "select":
|
||||
event = "throw_blue_orb";
|
||||
newScene = "media";
|
||||
// in this case we have to check the type of the blue orb
|
||||
// and dispatch an action depending on that, so we have to precalculate the
|
||||
// new active blue orb here.
|
||||
const newActiveBlueOrbId =
|
||||
newLevel +
|
||||
available_blue_orbs_on_projection[
|
||||
newSiteRotIdx as keyof typeof available_blue_orbs_on_projection
|
||||
][newBlueOrbRowIdx as number][newBlueOrbColIdx as number];
|
||||
|
||||
const blueOrbType =
|
||||
site_a[newActiveBlueOrbId as keyof typeof site_a].type;
|
||||
|
||||
const eventAnimation = "throw_blue_orb_";
|
||||
|
||||
switch (parseInt(blueOrbType)) {
|
||||
case 0:
|
||||
case 2:
|
||||
event = eventAnimation + "media";
|
||||
newScene = "media";
|
||||
break;
|
||||
case 8:
|
||||
event = eventAnimation + "gate";
|
||||
newScene = "gate";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const newActiveBlueOrbId =
|
||||
|
@ -91,6 +124,7 @@ const handleMainSceneEvent = (gameContext: GameContext) => {
|
|||
hudAssocs[
|
||||
`${newBlueOrbRowIdx}${newBlueOrbColIdx}` as keyof typeof hudAssocs
|
||||
];
|
||||
|
||||
return {
|
||||
event: event,
|
||||
newBlueOrbColIdx: newBlueOrbColIdx,
|
||||
|
|
16
src/scenes/GateScene.tsx
Normal file
16
src/scenes/GateScene.tsx
Normal file
|
@ -0,0 +1,16 @@
|
|||
import React from "react";
|
||||
import GateSide from "../components/GateScene/GateSide";
|
||||
import { OrbitControls } from "drei";
|
||||
import GateMiddle from "../components/GateScene/GateMiddle";
|
||||
|
||||
const GateScene = () => {
|
||||
return (
|
||||
<perspectiveCamera position-z={3}>
|
||||
<OrbitControls />
|
||||
<pointLight intensity={5.2} color={0xffffff} position={[-2, 0, 0]} />
|
||||
<GateSide />
|
||||
<GateMiddle/>
|
||||
</perspectiveCamera>
|
||||
);
|
||||
};
|
||||
export default GateScene;
|
16
src/store.ts
16
src/store.ts
|
@ -26,10 +26,8 @@ type BlueOrbState = {
|
|||
setActiveBlueOrbRotZ: (to: number) => void;
|
||||
setActiveBlueOrbId: (to: string) => void;
|
||||
setIsActiveBlueOrbInteractedWith: (to: boolean) => void;
|
||||
blueOrbRowIdx: number;
|
||||
blueOrbColIdx: number;
|
||||
setBlueOrbRowIdx: (to: number) => void;
|
||||
setBlueOrbColIdx: (to: number) => void;
|
||||
blueOrbMatrixIndices: { rowIdx: number; colIdx: number };
|
||||
setBlueOrbMatrixIndices: (to: { rowIdx: number; colIdx: number }) => void;
|
||||
};
|
||||
|
||||
type LainState = {
|
||||
|
@ -128,7 +126,7 @@ type MediaState = {
|
|||
setMediaPercentageElapsed: (to: number) => void;
|
||||
};
|
||||
|
||||
type TextRendererState = {
|
||||
export type TextRendererState = {
|
||||
yellowText: string;
|
||||
yellowTextPosY: number;
|
||||
yellowTextPosX: number;
|
||||
|
@ -209,9 +207,9 @@ export const useBlueOrbStore = create<BlueOrbState>((set) => ({
|
|||
setIsActiveBlueOrbInteractedWith: (to) =>
|
||||
set(() => ({ isActiveBlueOrbInteractedWith: to })),
|
||||
blueOrbRowIdx: 0,
|
||||
setBlueOrbRowIdx: (to) => set(() => ({ blueOrbRowIdx: to })),
|
||||
blueOrbColIdx: 0,
|
||||
setBlueOrbColIdx: (to) => set(() => ({ blueOrbColIdx: to })),
|
||||
|
||||
blueOrbMatrixIndices: { rowIdx: 0, colIdx: 0 },
|
||||
setBlueOrbMatrixIndices: (to) => set(() => ({ blueOrbMatrixIndices: to })),
|
||||
}));
|
||||
|
||||
export const useLainStore = create<LainState>((set) => ({
|
||||
|
@ -382,7 +380,7 @@ export const useMediaWordStore = create<MediaWordState>((set) => ({
|
|||
}));
|
||||
|
||||
export const useSceneStore = create<SceneState>((set) => ({
|
||||
currentScene: "main",
|
||||
currentScene: "gate",
|
||||
setScene: (to) => set(() => ({ currentScene: to })),
|
||||
}));
|
||||
|
||||
|
|
Loading…
Reference in a new issue