mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
middle ring anim done
This commit is contained in:
parent
dc5b8a4324
commit
e5220e193d
9 changed files with 116 additions and 86 deletions
|
@ -7,6 +7,8 @@ import LevelSelection from "./SyncedComponents/LevelSelection";
|
||||||
import GrayPlanes from "./SyncedComponents/GrayPlanes";
|
import GrayPlanes from "./SyncedComponents/GrayPlanes";
|
||||||
import Starfield from "./SyncedComponents/Starfield";
|
import Starfield from "./SyncedComponents/Starfield";
|
||||||
import Site from "./SyncedComponents/Site";
|
import Site from "./SyncedComponents/Site";
|
||||||
|
import MiddleRing from "./SyncedComponents/MiddleRing";
|
||||||
|
import { a } from "@react-spring/three";
|
||||||
|
|
||||||
type SyncedComponentLoaderProps = {
|
type SyncedComponentLoaderProps = {
|
||||||
paused: boolean;
|
paused: boolean;
|
||||||
|
@ -26,7 +28,6 @@ const SyncedComponentLoader = (props: SyncedComponentLoaderProps) => {
|
||||||
document.getElementsByTagName("canvas")[0].className =
|
document.getElementsByTagName("canvas")[0].className =
|
||||||
"main-scene-background";
|
"main-scene-background";
|
||||||
}, 4000);
|
}, 4000);
|
||||||
|
|
||||||
}, [props.shouldIntro]);
|
}, [props.shouldIntro]);
|
||||||
|
|
||||||
const visible = useMemo(() => {
|
const visible = useMemo(() => {
|
||||||
|
@ -44,7 +45,7 @@ const SyncedComponentLoader = (props: SyncedComponentLoaderProps) => {
|
||||||
<GreenTextRenderer />
|
<GreenTextRenderer />
|
||||||
<YellowTextRenderer />
|
<YellowTextRenderer />
|
||||||
<YellowOrb visible={visible} />
|
<YellowOrb visible={visible} />
|
||||||
<LevelSelection />
|
<MiddleRing />
|
||||||
<GrayPlanes />
|
<GrayPlanes />
|
||||||
</group>
|
</group>
|
||||||
<Starfield
|
<Starfield
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React, { useMemo, useRef } from "react";
|
import React, { useEffect, useMemo, useRef } from "react";
|
||||||
import { useFrame, useLoader } from "react-three-fiber";
|
import { useFrame, useLoader } from "react-three-fiber";
|
||||||
import middleRingTexture from "../../../static/sprite/middle_ring_tex.png";
|
import middleRingTexture from "../../../static/sprite/middle_ring_tex.png";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
@ -12,6 +12,9 @@ const MiddleRing = () => {
|
||||||
const transformState = useMiddleRingStore((state) => state.transformState);
|
const transformState = useMiddleRingStore((state) => state.transformState);
|
||||||
const rotating = useMiddleRingStore((state) => state.isRotating);
|
const rotating = useMiddleRingStore((state) => state.isRotating);
|
||||||
const animDuration = useMiddleRingStore((state) => state.animDuration);
|
const animDuration = useMiddleRingStore((state) => state.animDuration);
|
||||||
|
const mainRingVisible = useMiddleRingStore((state) => state.mainRingVisible);
|
||||||
|
|
||||||
|
const partSeparatorVal = useMiddleRingStore(state=> state.partSeparatorVal)
|
||||||
|
|
||||||
const wobbleState = useSpring({
|
const wobbleState = useSpring({
|
||||||
wobbleStrength: transformState.wobbleStrength,
|
wobbleStrength: transformState.wobbleStrength,
|
||||||
|
@ -201,6 +204,10 @@ const MiddleRing = () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(mainRingVisible);
|
||||||
|
}, [mainRingVisible]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<a.group rotation-z={rotState.rotZ}>
|
<a.group rotation-z={rotState.rotZ}>
|
||||||
<a.mesh
|
<a.mesh
|
||||||
|
@ -209,6 +216,7 @@ const MiddleRing = () => {
|
||||||
ref={middleRingRef}
|
ref={middleRingRef}
|
||||||
rotation={[0, 0.9, 0]}
|
rotation={[0, 0.9, 0]}
|
||||||
rotation-x={rotState.rotX}
|
rotation-x={rotState.rotX}
|
||||||
|
visible={mainRingVisible}
|
||||||
>
|
>
|
||||||
<cylinderBufferGeometry
|
<cylinderBufferGeometry
|
||||||
args={[0.75, 0.75, 0.027, 64, 64, true]}
|
args={[0.75, 0.75, 0.027, 64, 64, true]}
|
||||||
|
@ -228,7 +236,8 @@ const MiddleRing = () => {
|
||||||
<group
|
<group
|
||||||
rotation={[0, 0.9, 0]}
|
rotation={[0, 0.9, 0]}
|
||||||
ref={middleRingPartRef}
|
ref={middleRingPartRef}
|
||||||
position={[0, -0.12, 0.3]}
|
position={[0, 0.5, 0.3]}
|
||||||
|
visible={!mainRingVisible}
|
||||||
>
|
>
|
||||||
{[...Array(30).keys()].map((i) => {
|
{[...Array(30).keys()].map((i) => {
|
||||||
const angle = (i / 30) * 2 * Math.PI;
|
const angle = (i / 30) * 2 * Math.PI;
|
||||||
|
@ -236,6 +245,7 @@ const MiddleRing = () => {
|
||||||
<MiddleRingPart
|
<MiddleRingPart
|
||||||
position={[Math.cos(angle) / 1.35, 0, Math.sin(angle) / 1.35]}
|
position={[Math.cos(angle) / 1.35, 0, Math.sin(angle) / 1.35]}
|
||||||
rotation={[0, -angle + Math.PI / 2, 0]}
|
rotation={[0, -angle + Math.PI / 2, 0]}
|
||||||
|
key={angle}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
@ -2,7 +2,8 @@ import React, { useMemo } from "react";
|
||||||
import middleRingTexture from "../../../../static/sprite/middle_ring_tex.png";
|
import middleRingTexture from "../../../../static/sprite/middle_ring_tex.png";
|
||||||
import { useLoader } from "react-three-fiber";
|
import { useLoader } from "react-three-fiber";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import { a } from "@react-spring/three";
|
import { a, useSpring } from "@react-spring/three";
|
||||||
|
import { useMiddleRingStore } from "../../../../store";
|
||||||
|
|
||||||
type MiddleRingPartProps = {
|
type MiddleRingPartProps = {
|
||||||
position: number[];
|
position: number[];
|
||||||
|
@ -10,6 +11,10 @@ type MiddleRingPartProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const MiddleRingPart = (props: MiddleRingPartProps) => {
|
const MiddleRingPart = (props: MiddleRingPartProps) => {
|
||||||
|
const partSeparatorVal = useMiddleRingStore(
|
||||||
|
(state) => state.partSeparatorVal
|
||||||
|
);
|
||||||
|
|
||||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
||||||
|
|
||||||
const middleRingPartTex = useMemo(() => {
|
const middleRingPartTex = useMemo(() => {
|
||||||
|
@ -17,9 +22,17 @@ const MiddleRingPart = (props: MiddleRingPartProps) => {
|
||||||
return middleRingTex;
|
return middleRingTex;
|
||||||
}, [middleRingTex]);
|
}, [middleRingTex]);
|
||||||
|
|
||||||
|
const partPosState = useSpring({
|
||||||
|
posX: props.position[0] / partSeparatorVal,
|
||||||
|
posZ: props.position[2] / partSeparatorVal,
|
||||||
|
config: { duration: 600 },
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group
|
<a.group
|
||||||
position={props.position as [number, number, number]}
|
position-x={partPosState.posX}
|
||||||
|
position-z={partPosState.posZ}
|
||||||
|
position-y={props.position[1]}
|
||||||
rotation={props.rotation as [number, number, number]}
|
rotation={props.rotation as [number, number, number]}
|
||||||
>
|
>
|
||||||
<a.mesh scale={[0.16, 0.032, 0]}>
|
<a.mesh scale={[0.16, 0.032, 0]}>
|
||||||
|
@ -31,7 +44,7 @@ const MiddleRingPart = (props: MiddleRingPartProps) => {
|
||||||
side={THREE.DoubleSide}
|
side={THREE.DoubleSide}
|
||||||
/>
|
/>
|
||||||
</a.mesh>
|
</a.mesh>
|
||||||
</group>
|
</a.group>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,70 +0,0 @@
|
||||||
import React, { memo, useEffect } from "react";
|
|
||||||
import { useHudStore, useLainStore, useStarfieldStore } from "../store";
|
|
||||||
|
|
||||||
// ghost component to manipulate the intro action for the main scene.
|
|
||||||
|
|
||||||
// we separate this file because having something like this
|
|
||||||
// inside <Suspense> tags makes it behave in a more stable manner
|
|
||||||
// by waiting for the components to load and synchronously calling the functions.
|
|
||||||
const MainSceneIntro = memo(() => {
|
|
||||||
// todo component
|
|
||||||
|
|
||||||
// -2.5 - intro val
|
|
||||||
//-9.5 - intro val
|
|
||||||
//1.5 - intro val
|
|
||||||
|
|
||||||
const toggleHud = useHudStore((state) => state.toggleActive);
|
|
||||||
|
|
||||||
//const setHudVisible = useSetRecoilState(hudVisibilityAtom);
|
|
||||||
// const setOrbVisible = useYellowOrbStore((state) => state.setYellowOrbVisible);
|
|
||||||
|
|
||||||
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
|
|
||||||
|
|
||||||
const setIntroStarfieldVisible = useStarfieldStore(
|
|
||||||
(state) => state.setIntroStarfieldVisible
|
|
||||||
);
|
|
||||||
const setMainStarfieldVisible = useStarfieldStore(
|
|
||||||
(state) => state.setMainStarfieldVisible
|
|
||||||
);
|
|
||||||
const setMainStarfieldBoostVal = useStarfieldStore(
|
|
||||||
(state) => state.setMainStarfieldBoostVal
|
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
// setGrayPlanesVisible(true);
|
|
||||||
}, 2500);
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
setMainStarfieldVisible(true);
|
|
||||||
setMainStarfieldBoostVal(0);
|
|
||||||
}, 2800);
|
|
||||||
|
|
||||||
toggleHud();
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
setLainMoveState("standing");
|
|
||||||
|
|
||||||
// setOrbVisible(true);
|
|
||||||
//setHudVisible(true);
|
|
||||||
|
|
||||||
setIntroStarfieldVisible(false);
|
|
||||||
|
|
||||||
toggleHud();
|
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementsByTagName("canvas")[0].className =
|
|
||||||
"main-scene-background";
|
|
||||||
}, 300);
|
|
||||||
}, 3860);
|
|
||||||
}, [
|
|
||||||
setMainStarfieldBoostVal,
|
|
||||||
setMainStarfieldVisible,
|
|
||||||
setIntroStarfieldVisible,
|
|
||||||
setLainMoveState,
|
|
||||||
toggleHud,
|
|
||||||
]);
|
|
||||||
|
|
||||||
return <></>;
|
|
||||||
});
|
|
||||||
|
|
||||||
export default MainSceneIntro;
|
|
|
@ -7,6 +7,12 @@ const MiddleRingManager = (props: any) => {
|
||||||
);
|
);
|
||||||
const setAnimDuration = useMiddleRingStore((state) => state.setAnimDuration);
|
const setAnimDuration = useMiddleRingStore((state) => state.setAnimDuration);
|
||||||
const setRotating = useMiddleRingStore((state) => state.setRotating);
|
const setRotating = useMiddleRingStore((state) => state.setRotating);
|
||||||
|
const setMainRingVisible = useMiddleRingStore(
|
||||||
|
(state) => state.setMainRingVisible
|
||||||
|
);
|
||||||
|
const setPartSeparatorVal = useMiddleRingStore(
|
||||||
|
(state) => state.setPartSeparatorVal
|
||||||
|
);
|
||||||
|
|
||||||
const rotate = useCallback(
|
const rotate = useCallback(
|
||||||
(direction: string) => {
|
(direction: string) => {
|
||||||
|
@ -139,6 +145,62 @@ const MiddleRingManager = (props: any) => {
|
||||||
}, 7800);
|
}, 7800);
|
||||||
}, [setAnimDuration, setRotating, setTransformState]);
|
}, [setAnimDuration, setRotating, setTransformState]);
|
||||||
|
|
||||||
|
const animatePause = useCallback(() => {
|
||||||
|
setTransformState(0.5, "posY");
|
||||||
|
setTimeout(() => {
|
||||||
|
setMainRingVisible(false);
|
||||||
|
}, 600);
|
||||||
|
setTimeout(() => {
|
||||||
|
setPartSeparatorVal(0.9);
|
||||||
|
// move the hidden (main) ring below, cuz when the pause exists it needs to jump back up
|
||||||
|
// instead of reappearing
|
||||||
|
setTransformState(-2.5, "posY");
|
||||||
|
}, 1100);
|
||||||
|
setTimeout(() => {
|
||||||
|
setPartSeparatorVal(1);
|
||||||
|
}, 1500);
|
||||||
|
setTimeout(() => {
|
||||||
|
setPartSeparatorVal(0.9);
|
||||||
|
}, 1900);
|
||||||
|
setTimeout(() => {
|
||||||
|
setPartSeparatorVal(1);
|
||||||
|
}, 2300);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setPartSeparatorVal(0.2);
|
||||||
|
}, 3100);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setMainRingVisible(true);
|
||||||
|
setPartSeparatorVal(1);
|
||||||
|
}, 3800);
|
||||||
|
}, [setMainRingVisible, setPartSeparatorVal, setTransformState]);
|
||||||
|
|
||||||
|
const animateUnpause = useCallback(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
setTransformState(0, "wobbleStrength");
|
||||||
|
setTransformState(-0.4, "rotX");
|
||||||
|
setRotating(true);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
// reset anim duration back to default
|
||||||
|
setTimeout(() => {
|
||||||
|
setAnimDuration(600);
|
||||||
|
}, 900);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
setTransformState(0.13, "posY");
|
||||||
|
}, 900);
|
||||||
|
|
||||||
|
// reset the rotation value to 0
|
||||||
|
setTimeout(() => {
|
||||||
|
setTransformState(0, "rotX");
|
||||||
|
setTransformState(-0.11, "posY");
|
||||||
|
}, 1150);
|
||||||
|
}, 1000);
|
||||||
|
}, [setAnimDuration, setRotating, setTransformState]);
|
||||||
|
|
||||||
const dispatchObject = useCallback(
|
const dispatchObject = useCallback(
|
||||||
(eventState: { event: string }) => {
|
(eventState: { event: string }) => {
|
||||||
switch (eventState.event) {
|
switch (eventState.event) {
|
||||||
|
@ -152,15 +214,21 @@ const MiddleRingManager = (props: any) => {
|
||||||
return { action: rotate, value: ["left"] };
|
return { action: rotate, value: ["left"] };
|
||||||
case "site_right":
|
case "site_right":
|
||||||
return { action: rotate, value: ["right"] };
|
return { action: rotate, value: ["right"] };
|
||||||
|
case "pause_game":
|
||||||
|
return { action: animatePause };
|
||||||
|
case "pause_exit_select":
|
||||||
|
case "pause_change_select":
|
||||||
|
return { action: animateUnpause };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[moveDown, moveUp, rotate]
|
[animatePause, animateUnpause, moveDown, moveUp, rotate]
|
||||||
);
|
);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (props.eventState) {
|
if (props.eventState) {
|
||||||
const dispatchedObject = dispatchObject(props.eventState);
|
const dispatchedObject = dispatchObject(props.eventState);
|
||||||
|
|
||||||
if (dispatchedObject) {
|
if (dispatchedObject) {
|
||||||
|
console.log(dispatchedObject);
|
||||||
dispatchedObject.action.apply(null, dispatchedObject.value as any);
|
dispatchedObject.action.apply(null, dispatchedObject.value as any);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ const SiteManager = (props: StateManagerProps) => {
|
||||||
return {
|
return {
|
||||||
action: setTransformState,
|
action: setTransformState,
|
||||||
value: [Math.PI / 2, "rotX"],
|
value: [Math.PI / 2, "rotX"],
|
||||||
actionDelay: 0,
|
actionDelay: 3600,
|
||||||
};
|
};
|
||||||
case "pause_exit_select":
|
case "pause_exit_select":
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -27,7 +27,7 @@ const SubsceneManager = (props: StateManagerProps) => {
|
||||||
return {
|
return {
|
||||||
action: setMainSubscene,
|
action: setMainSubscene,
|
||||||
value: "pause",
|
value: "pause",
|
||||||
delay: 0,
|
delay: 3400,
|
||||||
};
|
};
|
||||||
case "pause_exit_select":
|
case "pause_exit_select":
|
||||||
case "pause_change_select":
|
case "pause_change_select":
|
||||||
|
|
|
@ -8,6 +8,7 @@ import MiddleRing from "../components/MainScene/SyncedComponents/MiddleRing";
|
||||||
import { useMainSceneStore } from "../store";
|
import { useMainSceneStore } from "../store";
|
||||||
import Pause from "../components/MainScene/PauseSubscene/Pause";
|
import Pause from "../components/MainScene/PauseSubscene/Pause";
|
||||||
import SyncedComponentLoader from "../components/MainScene/SyncedComponentLoader";
|
import SyncedComponentLoader from "../components/MainScene/SyncedComponentLoader";
|
||||||
|
import LevelSelection from "../components/MainScene/SyncedComponents/LevelSelection";
|
||||||
|
|
||||||
const MainScene = () => {
|
const MainScene = () => {
|
||||||
const currentSubscene = useMainSceneStore((state) => state.subscene);
|
const currentSubscene = useMainSceneStore((state) => state.subscene);
|
||||||
|
@ -27,9 +28,9 @@ const MainScene = () => {
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<a.group>
|
<a.group>
|
||||||
<Preloader />
|
<Preloader />
|
||||||
{/*<Pause visible={isPaused} />*/}
|
<Pause visible={isPaused} />
|
||||||
{/*<SyncedComponentLoader paused={isPaused} shouldIntro={shouldIntro} />*/}
|
<LevelSelection />
|
||||||
<MiddleRing />
|
<SyncedComponentLoader paused={isPaused} shouldIntro={shouldIntro} />
|
||||||
<OrbitControls />
|
<OrbitControls />
|
||||||
<pointLight color={0xffffff} position={[0, 0, 7]} intensity={1} />
|
<pointLight color={0xffffff} position={[0, 0, 7]} intensity={1} />
|
||||||
<pointLight color={0x7f7f7f} position={[0, 10, 0]} intensity={1.5} />
|
<pointLight color={0x7f7f7f} position={[0, 10, 0]} intensity={1.5} />
|
||||||
|
|
11
src/store.ts
11
src/store.ts
|
@ -106,6 +106,8 @@ type MiddleRingState = {
|
||||||
};
|
};
|
||||||
isRotating: boolean;
|
isRotating: boolean;
|
||||||
animDuration: number;
|
animDuration: number;
|
||||||
|
mainRingVisible: boolean;
|
||||||
|
partSeparatorVal: number
|
||||||
};
|
};
|
||||||
|
|
||||||
type MediaWordState = {
|
type MediaWordState = {
|
||||||
|
@ -358,16 +360,21 @@ export const useMiddleRingStore = create(
|
||||||
rotX: 0,
|
rotX: 0,
|
||||||
rotZ: 0,
|
rotZ: 0,
|
||||||
},
|
},
|
||||||
|
partSeparatorVal: 1,
|
||||||
isRotating: true,
|
isRotating: true,
|
||||||
animDuration: 600,
|
animDuration: 600,
|
||||||
|
mainRingVisible: true,
|
||||||
} as MiddleRingState,
|
} as MiddleRingState,
|
||||||
(set) => ({
|
(set) => ({
|
||||||
setTransformState: (to: number, at: string) =>
|
setTransformState: (to: number, at: string) =>
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
transformState: { ...state.transformState, [at]: to },
|
transformState: { ...state.transformState, [at]: to },
|
||||||
})),
|
})),
|
||||||
setRotating: (to: boolean) => ({ isRotating: to }),
|
setRotating: (to: boolean) => set(() => ({ isRotating: to })),
|
||||||
setAnimDuration: (to: number) => ({ animDuration: to }),
|
setAnimDuration: (to: number) => set(() => ({ animDuration: to })),
|
||||||
|
setMainRingVisible: (to: boolean) => set(() => ({ mainRingVisible: to })),
|
||||||
|
setPartSeparatorVal: (to: number) =>
|
||||||
|
set(() => ({ partSeparatorVal: to })),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue