reformatted starfield code a bit, made it move with camera

This commit is contained in:
ad044 2020-09-07 20:42:20 +04:00
parent 168fe2cb9f
commit 6f5af7dbef
2 changed files with 74 additions and 74 deletions

View file

@ -122,6 +122,14 @@ const Game = () => {
[] []
); );
const [{ starfieldPositionY }, setStarfieldPositionY] = useSpring(
() => ({
starfieldPositionY: -0.5,
config: { precision: 0.0001, duration: 1200 },
}),
[]
);
const moveCamera = useCallback( const moveCamera = useCallback(
(val: number) => (val: number) =>
void setTimeout( void setTimeout(
@ -134,6 +142,18 @@ const Game = () => {
[cameraPositionY, setCameraPositionY] [cameraPositionY, setCameraPositionY]
); );
const moveStarfield = useCallback(
(val: number) =>
void setTimeout(
() =>
setStarfieldPositionY(() => ({
starfieldPositionY: starfieldPositionY.get() + val,
})),
1300
),
[starfieldPositionY, setStarfieldPositionY]
);
const moveLain = useCallback( const moveLain = useCallback(
(val: number) => (val: number) =>
void setTimeout( void setTimeout(
@ -161,6 +181,7 @@ const Game = () => {
const camRotY = cameraRotationY.to([0, 1], [0, Math.PI]); const camRotY = cameraRotationY.to([0, 1], [0, Math.PI]);
const camPosY = cameraPositionY.to([0, 1], [0, Math.PI]); const camPosY = cameraPositionY.to([0, 1], [0, Math.PI]);
const lainPosY = lainPositionY.to([0, 1], [0, Math.PI]); const lainPosY = lainPositionY.to([0, 1], [0, Math.PI]);
const starfieldPosY = starfieldPositionY.to([0, 1], [0, Math.PI]);
const getMove = (currentLoc: string, key: string): string => { const getMove = (currentLoc: string, key: string): string => {
return (level_sprite_directions as SpriteDirections)[currentLoc][key]; return (level_sprite_directions as SpriteDirections)[currentLoc][key];
@ -180,6 +201,7 @@ const Game = () => {
switch (key) { switch (key) {
case "down": case "down":
moveCamera(0.6); moveCamera(0.6);
moveStarfield(-0.6);
moveLain(-0.6); moveLain(-0.6);
setLainMoveState(<LainMoveDown />); setLainMoveState(<LainMoveDown />);
break; break;
@ -189,6 +211,7 @@ const Game = () => {
break; break;
case "up": case "up":
moveCamera(-0.6); moveCamera(-0.6);
moveStarfield(0.6);
moveLain(0.6); moveLain(0.6);
setLainMoveState(<LainMoveUp />); setLainMoveState(<LainMoveUp />);
break; break;
@ -210,7 +233,7 @@ const Game = () => {
setLainMoveState(<LainStanding />); setLainMoveState(<LainStanding />);
}, (lain_animations as LainAnimations)[key]["duration"]); }, (lain_animations as LainAnimations)[key]["duration"]);
}, },
[moveCamera, moveLain, rotateCamera] [moveCamera, moveLain, rotateCamera, moveStarfield]
); );
const updateHUD = useCallback(() => { const updateHUD = useCallback(() => {
@ -372,7 +395,7 @@ const Game = () => {
id={currentSpriteHUD!["id"]} id={currentSpriteHUD!["id"]}
orbVisibility={!isIntro} orbVisibility={!isIntro}
/> />
<Starfield starfieldPosY={camPosY} /> <Starfield starfieldPosY={starfieldPosY} />
<Lights /> <Lights />
</Suspense> </Suspense>
</group> </group>

View file

@ -1,48 +1,29 @@
import { Interpolation } from "@react-spring/three"; import { Interpolation, a } from "@react-spring/three";
import React, { createRef, memo, useMemo, useRef } from "react"; import React, { createRef, memo, useMemo, useRef } from "react";
import { useFrame } from "react-three-fiber"; import { useFrame } from "react-three-fiber";
import * as THREE from "three"; import * as THREE from "three";
type StarfieldProps = { type StarfieldProps = {
starfieldPosY: Interpolation<number, number>; starfieldPosY: Interpolation<number, number>;
} };
const Starfield = memo((props: StarfieldProps) => { const Starfield = memo((props: StarfieldProps) => {
const blueUniforms = useMemo( const uniformConstructor = (col: string) => {
() => ({ return {
color1: { color1: {
value: new THREE.Color("white"), value: new THREE.Color("white"),
}, },
color2: { color2: {
value: new THREE.Color("blue"), value: new THREE.Color(col),
}, },
}), };
[] };
);
const cyanUniforms = useMemo( const [blueUniforms, cyanUniforms, whiteUniforms] = [
() => ({ "blue",
color1: { "cyan",
value: new THREE.Color("white"), "gray",
}, ].map((color: string) => useMemo(() => uniformConstructor(color), [color]));
color2: {
value: new THREE.Color("cyan"),
},
}),
[]
);
const whiteUniforms = useMemo(
() => ({
color1: {
value: new THREE.Color("white"),
},
color2: {
value: new THREE.Color("gray"),
},
}),
[]
);
const vertexShader = ` const vertexShader = `
varying vec2 vUv; varying vec2 vUv;
@ -72,41 +53,33 @@ const Starfield = memo((props: StarfieldProps) => {
const lcgInstance = LCG(1664525, 1013904223, 2 ** 32, 2); const lcgInstance = LCG(1664525, 1013904223, 2 ** 32, 2);
const posesBlueFromRight = Array.from({ length: 40 }, () => [ const [
posesBlueFromRight,
posesBlueFromLeft,
posesCyanFromRight,
posesCyanFromLeft,
posesWhiteFromLeft,
] = [40, 40, 10, 5, 5].map((x) =>
Array.from({ length: x }, () => [
lcgInstance() / 1000000000, lcgInstance() / 1000000000,
lcgInstance() / 1000000000, lcgInstance() / 1000000000,
lcgInstance() / 1000000000, lcgInstance() / 1000000000,
]); ])
);
const posesBlueFromLeft = Array.from({ length: 25 }, () => [ const [
lcgInstance() / 1000000000, blueFromRightRef,
lcgInstance() / 1000000000, blueFromLeftRef,
lcgInstance() / 1000000000, cyanFromRightRef,
]); cyanFromLeftRef,
whiteFromLeftRef,
const posesCyanFromRight = Array.from({ length: 10 }, () => [ ] = [
lcgInstance() / 1000000000, posesBlueFromRight,
lcgInstance() / 1000000000, posesBlueFromLeft,
lcgInstance() / 1000000000, posesCyanFromRight,
]); posesCyanFromLeft,
posesWhiteFromLeft,
const posesCyanFromLeft = Array.from({ length: 5 }, () => [ ].map((poses) => useRef(poses.map(() => createRef())));
lcgInstance() / 1000000000,
lcgInstance() / 1000000000,
lcgInstance() / 1000000000,
]);
const posesWhiteFromleft = Array.from({ length: 5 }, () => [
lcgInstance() / 1000000000,
lcgInstance() / 1000000000,
lcgInstance() / 1000000000,
]);
const blueFromRightRef = useRef(posesBlueFromRight.map(() => createRef()));
const blueFromLeftRef = useRef(posesBlueFromLeft.map(() => createRef()));
const cyanFromRightRef = useRef(posesCyanFromRight.map(() => createRef()));
const cyanFromLeftRef = useRef(posesCyanFromLeft.map(() => createRef()));
const whiteFromLeftRef = useRef(posesWhiteFromleft.map(() => createRef()));
useFrame(() => { useFrame(() => {
blueFromRightRef.current.forEach((ref) => { blueFromRightRef.current.forEach((ref) => {
@ -150,14 +123,18 @@ const Starfield = memo((props: StarfieldProps) => {
(ref.current as any).position.x -= 3.3; (ref.current as any).position.x -= 3.3;
(ref.current as any).position.z -= 3.3; (ref.current as any).position.z -= 3.3;
} else { } else {
(ref.current as any).position.x += 0.03; (ref.current as any).position.x += 0.02;
(ref.current as any).position.z += 0.03; (ref.current as any).position.z += 0.02;
} }
}); });
}); });
return ( return (
<group position={[-0.7, -1.5, -4]} rotation={[0,0,0]}> <a.group
position={[-0.7, 0, -4]}
rotation={[0, 0, 0]}
position-y={props.starfieldPosY}
>
{posesBlueFromRight.map((pos: any, idx: number) => { {posesBlueFromRight.map((pos: any, idx: number) => {
return ( return (
<mesh <mesh
@ -187,7 +164,7 @@ const Starfield = memo((props: StarfieldProps) => {
ref={(blueFromLeftRef.current as any)[idx]} ref={(blueFromLeftRef.current as any)[idx]}
scale={[0.01, 2, 1]} scale={[0.01, 2, 1]}
rotation={[1.7, 0, -0.9]} rotation={[1.7, 0, -0.9]}
position={[pos[0] - 2.4, pos[1] - 1.5, pos[2]]} position={[pos[0] - 2.4, pos[1] - 0.5, pos[2]]}
key={pos[0]} key={pos[0]}
renderOrder={-1} renderOrder={-1}
> >
@ -250,12 +227,12 @@ const Starfield = memo((props: StarfieldProps) => {
</mesh> </mesh>
); );
})} })}
{posesWhiteFromleft.map((pos: any, idx: number) => { {posesWhiteFromLeft.map((pos: any, idx: number) => {
return ( return (
<mesh <mesh
ref={(whiteFromLeftRef.current as any)[idx]} ref={(whiteFromLeftRef.current as any)[idx]}
scale={[0.01, 0.9, 1]} scale={[0.01, 0.9, 1]}
position={[pos[0] - 1.3, pos[1], pos[2] + 1.5]} position={[pos[0] - 1.3, pos[1] + 0.5, pos[2] + 1.5]}
rotation={[1.7, 0, -0.9]} rotation={[1.7, 0, -0.9]}
renderOrder={-1} renderOrder={-1}
key={pos[0]} key={pos[0]}
@ -273,7 +250,7 @@ const Starfield = memo((props: StarfieldProps) => {
</mesh> </mesh>
); );
})} })}
</group> </a.group>
); );
}); });