mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 15:09:05 +00:00
memoized some components, added orb
This commit is contained in:
parent
19560f439e
commit
ba98824ad8
12 changed files with 139 additions and 64 deletions
|
@ -41,5 +41,6 @@
|
|||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
},
|
||||
"homepage": "."
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { a, useSpring } from "@react-spring/three";
|
||||
//import Orb from "./Orb";
|
||||
import { OrbitControls } from "drei";
|
||||
import React, { Suspense, useCallback, useEffect, useState } from "react";
|
||||
import { Canvas } from "react-three-fiber";
|
||||
|
@ -46,6 +45,7 @@ const Game = () => {
|
|||
const [currentSpriteHUD, setCurrentSpriteHUD] = useState<SpriteHuds>(
|
||||
(level_sprite_huds as SpriteHuds)[currentSprite.substr(2)]
|
||||
);
|
||||
const [spriteUpdateCooldown, setSpriteUpdateCooldown] = useState(false);
|
||||
|
||||
const [HUDActive, setHUDActive] = useState(1);
|
||||
|
||||
|
@ -218,36 +218,48 @@ const Game = () => {
|
|||
// therefore lain should first do a move (up/down/left/right) and then that sprite
|
||||
// will be chosen.
|
||||
case "+":
|
||||
// hide the hud
|
||||
updateHUD();
|
||||
// disable glow on current sprite
|
||||
setCurrentSprite("");
|
||||
setAnimationState(key);
|
||||
setTimeout(() => {
|
||||
setOrthoCameraPosY(1.88);
|
||||
if (!spriteUpdateCooldown) {
|
||||
// hide the hud
|
||||
updateHUD();
|
||||
setCurrentSprite(move.substr(1));
|
||||
setCurrentSpriteHUD(
|
||||
(level_sprite_huds as SpriteHuds)[move.substr(3)]
|
||||
);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
|
||||
break;
|
||||
// disable glow on current sprite
|
||||
setCurrentSprite("");
|
||||
setSpriteUpdateCooldown(true);
|
||||
setAnimationState(key);
|
||||
setTimeout(() => {
|
||||
setOrthoCameraPosY(1.88);
|
||||
updateHUD();
|
||||
setCurrentSprite(move.substr(1));
|
||||
setCurrentSpriteHUD(
|
||||
(level_sprite_huds as SpriteHuds)[move.substr(3)]
|
||||
);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
break;
|
||||
}
|
||||
// only change sprite focus
|
||||
default:
|
||||
setCurrentSprite(move);
|
||||
// toggle hud to go back in
|
||||
updateHUD();
|
||||
setTimeout(() => {
|
||||
// change hud while its hidden
|
||||
setCurrentSpriteHUD(
|
||||
(level_sprite_huds as SpriteHuds)[move.substr(2)]
|
||||
);
|
||||
// toggle it again to be shown in the new position
|
||||
if (!spriteUpdateCooldown) {
|
||||
setCurrentSprite(move);
|
||||
setSpriteUpdateCooldown(true);
|
||||
// toggle hud to go back in
|
||||
updateHUD();
|
||||
}, 500);
|
||||
setTimeout(() => {
|
||||
// change hud while its hidden
|
||||
setCurrentSpriteHUD(
|
||||
(level_sprite_huds as SpriteHuds)[move.substr(2)]
|
||||
);
|
||||
// toggle it again to be shown in the new position
|
||||
updateHUD();
|
||||
}, 500);
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
},
|
||||
[setAnimationState, updateHUD]
|
||||
[setAnimationState, updateHUD, spriteUpdateCooldown]
|
||||
);
|
||||
|
||||
const handleKeyPress = useCallback(
|
||||
|
@ -320,7 +332,7 @@ const Game = () => {
|
|||
id={currentSpriteHUD!["id"]}
|
||||
/>
|
||||
<OrbitControls />
|
||||
<Starfield />
|
||||
<Starfield starfieldPosY={camPosY} />
|
||||
<Lights />
|
||||
</Suspense>
|
||||
</a.perspectiveCamera>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { draco } from "drei";
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
|
||||
|
@ -15,7 +15,7 @@ type GLTFResult = GLTF & {
|
|||
materials: {};
|
||||
};
|
||||
|
||||
const GrayRing = (props: GrayRingProps) => {
|
||||
const GrayRing = memo((props: GrayRingProps) => {
|
||||
const { nodes } = useLoader<GLTFResult>(
|
||||
GLTFLoader,
|
||||
"/models/ring0.glb",
|
||||
|
@ -38,6 +38,6 @@ const GrayRing = (props: GrayRingProps) => {
|
|||
</mesh>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default GrayRing;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import bigHud from "../static/sprites/big_hud.png";
|
||||
|
@ -30,7 +30,7 @@ export type HUDElementProps = {
|
|||
bigHUDScale: PositionAndScaleProps;
|
||||
};
|
||||
|
||||
const HUDElement = (props: HUDElementProps) => {
|
||||
const HUDElement = memo((props: HUDElementProps) => {
|
||||
// these hud elements come in all shapes and forms, some of them are mirrored, rotated
|
||||
// you name it. this function allows me to specify whether i want a normal texture
|
||||
// for the sprite or the mirrored/rotated one.
|
||||
|
@ -113,6 +113,6 @@ const HUDElement = (props: HUDElementProps) => {
|
|||
</a.sprite>
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default HUDElement;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { Suspense } from "react";
|
||||
import React, { Suspense, memo} from "react";
|
||||
import GrayRing from "./GrayRing";
|
||||
import PurpleRing from "./PurpleRing";
|
||||
import LevelSprite from "./LevelSprite";
|
||||
|
@ -24,7 +24,7 @@ const Hub = (props: any) => {
|
|||
rotation={sprite.rotation as RotationProps}
|
||||
sprite={sprite.sprite}
|
||||
key={sprite.id}
|
||||
active={sprite.id === props.currentSprite ? true : false}
|
||||
active={sprite.id === props.currentSprite}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
|
|
@ -24,12 +24,12 @@ type LainConstructorProps = {
|
|||
|
||||
const LainConstructor = (props: LainConstructorProps) => {
|
||||
// any here temporarily
|
||||
const spriteTexture: any = useLoader(THREE.TextureLoader, props.sprite);
|
||||
const lainSpriteTexture: any = useLoader(THREE.TextureLoader, props.sprite);
|
||||
|
||||
const [animator] = useState(
|
||||
() =>
|
||||
new PlainSingularAnimator(
|
||||
spriteTexture,
|
||||
lainSpriteTexture,
|
||||
props.framesHorizontal,
|
||||
props.framesVertical,
|
||||
props.frameCount,
|
||||
|
@ -41,7 +41,7 @@ const LainConstructor = (props: LainConstructorProps) => {
|
|||
animator.animate();
|
||||
});
|
||||
|
||||
return <spriteMaterial attach="material" map={spriteTexture} />;
|
||||
return <spriteMaterial attach="material" map={lainSpriteTexture} />;
|
||||
};
|
||||
|
||||
export const LainIntro = () => {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import React, { useRef, useMemo } from "react";
|
||||
import React, { useRef, useMemo, memo } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import Cou from "../static/sprites/Cou.png";
|
||||
|
@ -22,7 +22,7 @@ type SpriteToPath = {
|
|||
[key: string]: [string, string];
|
||||
};
|
||||
|
||||
const LevelSprite = (props: LevelSpriteConstructorProps) => {
|
||||
const LevelSprite = memo((props: LevelSpriteConstructorProps) => {
|
||||
// the game only has a couple of sprites that it displays in the hub
|
||||
// dynamically importnig them would be worse for performance,
|
||||
// so we import all of them here and then use this function to
|
||||
|
@ -114,6 +114,6 @@ const LevelSprite = (props: LevelSpriteConstructorProps) => {
|
|||
)}
|
||||
</mesh>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default LevelSprite;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
|
||||
const Lights = () => {
|
||||
const Lights = memo(() => {
|
||||
return (
|
||||
<>
|
||||
<ambientLight color={0x808080} />
|
||||
|
@ -9,6 +9,6 @@ const Lights = () => {
|
|||
<pointLight color={0xffffff} position={[0, 0, 0]} intensity={0.1} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default Lights;
|
||||
|
|
55
src/components/Orb.tsx
Normal file
55
src/components/Orb.tsx
Normal file
|
@ -0,0 +1,55 @@
|
|||
import React, { useRef, memo, useState } from "react";
|
||||
import * as THREE from "three";
|
||||
import { useUpdate, useThree, useFrame, useLoader } from "react-three-fiber";
|
||||
import orbSprite from "../static/sprites/orb.png";
|
||||
|
||||
const curve = new THREE.QuadraticBezierCurve3(
|
||||
new THREE.Vector3(1.2, 0, 0),
|
||||
new THREE.Vector3(0.5, -0.8, 0),
|
||||
new THREE.Vector3(-1.2, 1, 0)
|
||||
);
|
||||
|
||||
const points = curve.getPoints(100);
|
||||
|
||||
let orbIdx = 0;
|
||||
|
||||
const Orb = memo(() => {
|
||||
const orbRef = useRef();
|
||||
const [orbDirection, setOrbDirection] = useState("left");
|
||||
const ref = useUpdate((geometry: any) => {
|
||||
geometry.setFromPoints(points);
|
||||
}, []);
|
||||
|
||||
const orbSpriteTexture: any = useLoader(THREE.TextureLoader, orbSprite);
|
||||
|
||||
useFrame(() => {
|
||||
var orbPos = curve.getPoint(orbIdx / 250);
|
||||
if (orbPos.x < -1.4) setOrbDirection("right");
|
||||
if (orbPos.x > 1.4) setOrbDirection("left");
|
||||
if (orbDirection === "left") {
|
||||
orbIdx++;
|
||||
} else {
|
||||
orbIdx--;
|
||||
}
|
||||
(orbRef.current as any).position.x = orbPos.x;
|
||||
(orbRef.current as any).position.y = orbPos.y;
|
||||
});
|
||||
return (
|
||||
<group position={[0, -0.1, -9]}>
|
||||
<sprite scale={[0.3, 0.3, 0.3]} ref={orbRef}>
|
||||
<spriteMaterial attach="material" map={orbSpriteTexture} />
|
||||
</sprite>
|
||||
{/* <line>
|
||||
<bufferGeometry attach="geometry" ref={ref} />
|
||||
<lineBasicMaterial
|
||||
attach="material"
|
||||
color="blue"
|
||||
linewidth={7}
|
||||
transparent={false}
|
||||
/>
|
||||
</line> */}
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
||||
export default Orb;
|
|
@ -1,9 +1,8 @@
|
|||
//import Orb from "./Orb";
|
||||
import { OrthographicCamera } from "drei";
|
||||
import React, { useMemo, useRef } from "react";
|
||||
import { useFrame, useThree } from "react-three-fiber";
|
||||
import { Scene } from "three";
|
||||
import HUDElement, { HUDElementProps } from "./HUDElement";
|
||||
import Orb from "./Orb";
|
||||
|
||||
interface OrthoCameraProps extends HUDElementProps {
|
||||
id: string;
|
||||
|
@ -44,6 +43,7 @@ const OrthoCamera = (props: OrthoCameraProps) => {
|
|||
bigHUDScale={props.bigHUDScale}
|
||||
key={props.id}
|
||||
/>
|
||||
<Orb />
|
||||
</orthographicCamera>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { a, useSpring } from "@react-spring/three";
|
||||
import { draco } from "drei";
|
||||
import React from "react";
|
||||
import React, { memo } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
|
@ -16,7 +16,7 @@ type GLTFResult = GLTF & {
|
|||
materials: {};
|
||||
};
|
||||
|
||||
const PurpleRing = (props: PurpleRingProps) => {
|
||||
const PurpleRing = memo((props: PurpleRingProps) => {
|
||||
const [{ purpleRingRotationY }, setPurpleRingRotationY] = useSpring(
|
||||
() => ({
|
||||
purpleRingRotationY: 0,
|
||||
|
@ -54,6 +54,6 @@ const PurpleRing = (props: PurpleRingProps) => {
|
|||
</mesh>
|
||||
</a.group>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default PurpleRing;
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import React, { useMemo, useReducer, useRef, createRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { a, Interpolation } from "@react-spring/three";
|
||||
import React, { createRef, memo, useMemo, useRef } from "react";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
const Starfield = () => {
|
||||
type StarfieldProps = {
|
||||
starfieldPosY: Interpolation<number, number>;
|
||||
}
|
||||
|
||||
const Starfield = memo((props: StarfieldProps) => {
|
||||
const blueUniforms = useMemo(
|
||||
() => ({
|
||||
color1: {
|
||||
|
@ -105,7 +109,7 @@ const Starfield = () => {
|
|||
const whiteFromLeftRef = useRef(posesWhiteFromleft.map(() => createRef()));
|
||||
|
||||
useFrame(() => {
|
||||
blueFromRightRef.current.map((ref) => {
|
||||
blueFromRightRef.current.forEach((ref) => {
|
||||
if ((ref.current as any).position.x < -1) {
|
||||
(ref.current as any).position.x += 7.3;
|
||||
(ref.current as any).position.z -= 7.3;
|
||||
|
@ -114,16 +118,16 @@ const Starfield = () => {
|
|||
(ref.current as any).position.z += 0.03;
|
||||
}
|
||||
});
|
||||
blueFromLeftRef.current.map((ref) => {
|
||||
blueFromLeftRef.current.forEach((ref) => {
|
||||
if ((ref.current as any).position.x > 3) {
|
||||
(ref.current as any).position.x -= 3.3;
|
||||
(ref.current as any).position.z -= 3.3;
|
||||
(ref.current as any).position.x -= 8.3;
|
||||
(ref.current as any).position.z -= 8.3;
|
||||
} else {
|
||||
(ref.current as any).position.x += 0.03;
|
||||
(ref.current as any).position.z += 0.03;
|
||||
}
|
||||
});
|
||||
cyanFromRightRef.current.map((ref) => {
|
||||
cyanFromRightRef.current.forEach((ref) => {
|
||||
if ((ref.current as any).position.x < -1) {
|
||||
(ref.current as any).position.x += 4.3;
|
||||
(ref.current as any).position.z -= 4.3;
|
||||
|
@ -132,7 +136,7 @@ const Starfield = () => {
|
|||
(ref.current as any).position.z += 0.03;
|
||||
}
|
||||
});
|
||||
cyanFromLeftRef.current.map((ref) => {
|
||||
cyanFromLeftRef.current.forEach((ref) => {
|
||||
if ((ref.current as any).position.x > 3) {
|
||||
(ref.current as any).position.x -= 3.3;
|
||||
(ref.current as any).position.z -= 3.3;
|
||||
|
@ -141,7 +145,7 @@ const Starfield = () => {
|
|||
(ref.current as any).position.z += 0.03;
|
||||
}
|
||||
});
|
||||
whiteFromLeftRef.current.map((ref) => {
|
||||
whiteFromLeftRef.current.forEach((ref) => {
|
||||
if ((ref.current as any).position.x > 3) {
|
||||
(ref.current as any).position.x -= 3.3;
|
||||
(ref.current as any).position.z -= 3.3;
|
||||
|
@ -153,7 +157,7 @@ const Starfield = () => {
|
|||
});
|
||||
|
||||
return (
|
||||
<group position={[-0.7, -1.5, -4]}>
|
||||
<a.group position={[-0.7, -1.5, -4]} >
|
||||
{posesBlueFromRight.map((pos: any, idx: number) => {
|
||||
return (
|
||||
<mesh
|
||||
|
@ -161,7 +165,7 @@ const Starfield = () => {
|
|||
scale={[0.01, 2, 1]}
|
||||
rotation={[1.7, 0, 0.9]}
|
||||
position={[pos[0], pos[1], pos[2]]}
|
||||
key={idx}
|
||||
key={pos[0]}
|
||||
renderOrder={-1}
|
||||
>
|
||||
<planeGeometry attach="geometry" />
|
||||
|
@ -208,6 +212,7 @@ const Starfield = () => {
|
|||
position={[pos[0] - 1.3, pos[1], pos[2] + 1.5]}
|
||||
rotation={[1.7, 0, 0.9]}
|
||||
renderOrder={-1}
|
||||
key={pos[0]}
|
||||
>
|
||||
<planeGeometry attach="geometry" />
|
||||
<shaderMaterial
|
||||
|
@ -230,6 +235,7 @@ const Starfield = () => {
|
|||
position={[pos[0] - 1.3, pos[1], pos[2] + 1.5]}
|
||||
rotation={[1.7, 0, -0.9]}
|
||||
renderOrder={-1}
|
||||
key={pos[0]}
|
||||
>
|
||||
<planeGeometry attach="geometry" />
|
||||
<shaderMaterial
|
||||
|
@ -252,6 +258,7 @@ const Starfield = () => {
|
|||
position={[pos[0] - 1.3, pos[1], pos[2] + 1.5]}
|
||||
rotation={[1.7, 0, -0.9]}
|
||||
renderOrder={-1}
|
||||
key={pos[0]}
|
||||
>
|
||||
<planeGeometry attach="geometry" />
|
||||
<shaderMaterial
|
||||
|
@ -266,8 +273,8 @@ const Starfield = () => {
|
|||
</mesh>
|
||||
);
|
||||
})}
|
||||
</group>
|
||||
</a.group>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default Starfield;
|
||||
|
|
Loading…
Reference in a new issue