memoized some components, added orb

This commit is contained in:
ad044 2020-09-03 23:02:44 +04:00
parent 19560f439e
commit ba98824ad8
12 changed files with 139 additions and 64 deletions

View file

@ -41,5 +41,6 @@
"last 1 firefox version",
"last 1 safari version"
]
}
},
"homepage": "."
}

View file

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

View file

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

View file

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

View file

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

View file

@ -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 = () => {

View file

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

View file

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

View file

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

View file

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

View file

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