mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
nah fuck that, reverted most stuff
This commit is contained in:
parent
a6c7f29c93
commit
014137287e
19 changed files with 1100 additions and 1158 deletions
13
package-lock.json
generated
13
package-lock.json
generated
|
@ -2352,8 +2352,7 @@
|
|||
"arg": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
|
@ -4538,8 +4537,7 @@
|
|||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A=="
|
||||
},
|
||||
"diff-sequences": {
|
||||
"version": "24.9.0",
|
||||
|
@ -8118,8 +8116,7 @@
|
|||
"make-error": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="
|
||||
},
|
||||
"makeerror": {
|
||||
"version": "1.0.11",
|
||||
|
@ -12698,7 +12695,6 @@
|
|||
"version": "9.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz",
|
||||
"integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arg": "^4.1.0",
|
||||
"diff": "^4.0.1",
|
||||
|
@ -13949,8 +13945,7 @@
|
|||
"yn": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,5 @@
|
|||
]
|
||||
},
|
||||
"homepage": ".",
|
||||
"devDependencies": {
|
||||
|
||||
}
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useRef, useMemo, memo } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
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";
|
||||
import CouActive from "../../static/sprites/Cou_active.png";
|
||||
|
@ -18,69 +18,69 @@ import MULTIActive from "../../static/sprites/MULTI_active.png";
|
|||
import level_y_values from "../../resources/level_y_values.json";
|
||||
|
||||
type BlueOrbContructorProps = {
|
||||
sprite: string;
|
||||
position: number[];
|
||||
rotation: number[];
|
||||
active: boolean;
|
||||
level: string;
|
||||
sprite: string;
|
||||
position: number[];
|
||||
rotation: number[];
|
||||
active: boolean;
|
||||
level: string;
|
||||
};
|
||||
|
||||
type LevelYValues = {
|
||||
[level: string]: number;
|
||||
[level: string]: number;
|
||||
};
|
||||
|
||||
type SpriteToPath = {
|
||||
[key: string]: [string, string];
|
||||
[key: string]: [string, string];
|
||||
};
|
||||
|
||||
const BlueOrb = memo((props: BlueOrbContructorProps) => {
|
||||
// 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
|
||||
// associate a sprite with the path
|
||||
const spriteToPath = (sprite: string) => {
|
||||
if (sprite.includes("S")) {
|
||||
return [SSkn, SSKnActive];
|
||||
} else if (
|
||||
sprite.startsWith("P") ||
|
||||
sprite.startsWith("G") ||
|
||||
sprite.includes("?")
|
||||
) {
|
||||
return [MULTI, MULTIActive];
|
||||
} else if (sprite.includes("Dc")) {
|
||||
return [Dc, DcActive];
|
||||
} else {
|
||||
return ({
|
||||
Tda: [Tda, TdaActive],
|
||||
Cou: [Cou, CouActive],
|
||||
Dia: [Dia, DiaActive],
|
||||
Lda: [Lda, LdaActive],
|
||||
Ere: [MULTI, MULTIActive],
|
||||
Ekm: [MULTI, MULTIActive],
|
||||
Eda: [MULTI, MULTIActive],
|
||||
TaK: [MULTI, MULTIActive],
|
||||
Env: [MULTI, MULTIActive],
|
||||
} as SpriteToPath)[sprite.substr(0, 3)];
|
||||
}
|
||||
};
|
||||
// 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
|
||||
// associate a sprite with the path
|
||||
const spriteToPath = (sprite: string) => {
|
||||
if (sprite.includes("S")) {
|
||||
return [SSkn, SSKnActive];
|
||||
} else if (
|
||||
sprite.startsWith("P") ||
|
||||
sprite.startsWith("G") ||
|
||||
sprite.includes("?")
|
||||
) {
|
||||
return [MULTI, MULTIActive];
|
||||
} else if (sprite.includes("Dc")) {
|
||||
return [Dc, DcActive];
|
||||
} else {
|
||||
return ({
|
||||
Tda: [Tda, TdaActive],
|
||||
Cou: [Cou, CouActive],
|
||||
Dia: [Dia, DiaActive],
|
||||
Lda: [Lda, LdaActive],
|
||||
Ere: [MULTI, MULTIActive],
|
||||
Ekm: [MULTI, MULTIActive],
|
||||
Eda: [MULTI, MULTIActive],
|
||||
TaK: [MULTI, MULTIActive],
|
||||
Env: [MULTI, MULTIActive],
|
||||
} as SpriteToPath)[sprite.substr(0, 3)];
|
||||
}
|
||||
};
|
||||
|
||||
const materialRef = useRef<THREE.ShaderMaterial>();
|
||||
const materialRef = useRef<THREE.ShaderMaterial>();
|
||||
|
||||
const spriteSheet = spriteToPath(props.sprite);
|
||||
const spriteSheet = spriteToPath(props.sprite);
|
||||
|
||||
const nonActiveTexture = useLoader(THREE.TextureLoader, spriteSheet[0]);
|
||||
const activeTexture = useLoader(THREE.TextureLoader, spriteSheet[1]);
|
||||
const nonActiveTexture = useLoader(THREE.TextureLoader, spriteSheet[0]);
|
||||
const activeTexture = useLoader(THREE.TextureLoader, spriteSheet[1]);
|
||||
|
||||
const uniforms = useMemo(
|
||||
() => ({
|
||||
tex1: { type: "t", value: nonActiveTexture },
|
||||
tex2: { type: "t", value: activeTexture },
|
||||
timeMSeconds: { value: (Date.now() % (Math.PI * 2000)) / 1000.0 },
|
||||
}),
|
||||
[nonActiveTexture, activeTexture]
|
||||
);
|
||||
const uniforms = useMemo(
|
||||
() => ({
|
||||
tex1: {type: "t", value: nonActiveTexture},
|
||||
tex2: {type: "t", value: activeTexture},
|
||||
timeMSeconds: {value: (Date.now() % (Math.PI * 2000)) / 1000.0},
|
||||
}),
|
||||
[nonActiveTexture, activeTexture]
|
||||
);
|
||||
|
||||
const vertexShader = `
|
||||
const vertexShader = `
|
||||
varying vec2 vUv;
|
||||
|
||||
void main() {
|
||||
|
@ -89,7 +89,7 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
|
|||
}
|
||||
`;
|
||||
|
||||
const fragmentShader = `
|
||||
const fragmentShader = `
|
||||
precision highp float;
|
||||
|
||||
uniform sampler2D tex1;
|
||||
|
@ -108,43 +108,43 @@ const BlueOrb = memo((props: BlueOrbContructorProps) => {
|
|||
}
|
||||
`;
|
||||
|
||||
useFrame(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.uniforms.timeMSeconds.value =
|
||||
(Date.now() % (Math.PI * 2000)) / 1000.0;
|
||||
}
|
||||
});
|
||||
useFrame(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.uniforms.timeMSeconds.value =
|
||||
(Date.now() % (Math.PI * 2000)) / 1000.0;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group position={[0, (level_y_values as LevelYValues)[props.level], 0]}>
|
||||
<mesh
|
||||
position={props.position as [number, number, number]}
|
||||
scale={[(0.046 * 90) / 100, (0.028 * 90) / 100, (0.046 * 90) / 100]}
|
||||
rotation={props.rotation as [number, number, number]}
|
||||
renderOrder={1}
|
||||
>
|
||||
<planeBufferGeometry attach="geometry" />
|
||||
{props.active ? (
|
||||
<shaderMaterial
|
||||
ref={materialRef}
|
||||
attach="material"
|
||||
uniforms={uniforms}
|
||||
fragmentShader={fragmentShader}
|
||||
vertexShader={vertexShader}
|
||||
side={THREE.DoubleSide}
|
||||
transparent={true}
|
||||
/>
|
||||
) : (
|
||||
<meshBasicMaterial
|
||||
attach="material"
|
||||
map={nonActiveTexture}
|
||||
side={THREE.DoubleSide}
|
||||
transparent={true}
|
||||
/>
|
||||
)}
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
return (
|
||||
<group position={[0, (level_y_values as LevelYValues)[props.level], 0]}>
|
||||
<mesh
|
||||
position={props.position as [number, number, number]}
|
||||
scale={[0.25, 0.15, 0.25]}
|
||||
rotation={props.rotation as [number, number, number]}
|
||||
renderOrder={1}
|
||||
>
|
||||
<planeBufferGeometry attach="geometry"/>
|
||||
{props.active ? (
|
||||
<shaderMaterial
|
||||
ref={materialRef}
|
||||
attach="material"
|
||||
uniforms={uniforms}
|
||||
fragmentShader={fragmentShader}
|
||||
vertexShader={vertexShader}
|
||||
side={THREE.DoubleSide}
|
||||
transparent={true}
|
||||
/>
|
||||
) : (
|
||||
<meshStandardMaterial
|
||||
attach="material"
|
||||
map={nonActiveTexture}
|
||||
side={THREE.DoubleSide}
|
||||
transparent={true}
|
||||
/>
|
||||
)}
|
||||
</mesh>
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
||||
export default BlueOrb;
|
||||
|
|
|
@ -6,21 +6,21 @@ import lifeTexture from "../static/sprites/life.png";
|
|||
import { useLoader } from "react-three-fiber";
|
||||
|
||||
type GrayRingProps = {
|
||||
grayRingPosY: number;
|
||||
grayRingPosY: number;
|
||||
};
|
||||
|
||||
const GrayRing = memo((props: GrayRingProps) => {
|
||||
const lofTex = useLoader(THREE.TextureLoader, lofTexture);
|
||||
const holeTex = useLoader(THREE.TextureLoader, holeTexture);
|
||||
const lifeTex = useLoader(THREE.TextureLoader, lifeTexture);
|
||||
const lofTex = useLoader(THREE.TextureLoader, lofTexture);
|
||||
const holeTex = useLoader(THREE.TextureLoader, holeTexture);
|
||||
const lifeTex = useLoader(THREE.TextureLoader, lifeTexture);
|
||||
|
||||
const uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]);
|
||||
const uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]);
|
||||
|
||||
uniforms.lof = { type: "t", value: lofTex };
|
||||
uniforms.hole = { type: "t", value: holeTex };
|
||||
uniforms.life = { type: "t", value: lifeTex };
|
||||
uniforms.lof = { type: "t", value: lofTex };
|
||||
uniforms.hole = { type: "t", value: holeTex };
|
||||
uniforms.life = { type: "t", value: lifeTex };
|
||||
|
||||
const vertexShader = `
|
||||
const vertexShader = `
|
||||
varying vec2 vUv;
|
||||
|
||||
varying vec3 vPos;
|
||||
|
@ -36,7 +36,7 @@ const GrayRing = memo((props: GrayRingProps) => {
|
|||
}
|
||||
`;
|
||||
|
||||
const fragmentShader = `
|
||||
const fragmentShader = `
|
||||
varying vec2 vUv;
|
||||
uniform sampler2D lof;
|
||||
uniform sampler2D hole;
|
||||
|
@ -99,7 +99,7 @@ const GrayRing = memo((props: GrayRingProps) => {
|
|||
addedLights.rgb += clamp(dot(-lightDirection,
|
||||
vNormal), 0.0, 1.0)
|
||||
* pointLights[l].color
|
||||
* 150.0;
|
||||
* 50.0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -151,28 +151,28 @@ const GrayRing = memo((props: GrayRingProps) => {
|
|||
}
|
||||
`;
|
||||
|
||||
return (
|
||||
<mesh
|
||||
position={[0, props.grayRingPosY, 0]}
|
||||
rotation={[0, 3.95, 0]}
|
||||
renderOrder={1}
|
||||
scale={[185, 185, 185]}
|
||||
>
|
||||
<cylinderBufferGeometry
|
||||
args={[0.001, 0.001, 0.000075, 64, 64, true]}
|
||||
attach="geometry"
|
||||
/>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
side={THREE.DoubleSide}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
transparent={true}
|
||||
uniforms={uniforms}
|
||||
lights={true}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
return (
|
||||
<mesh
|
||||
position={[0, props.grayRingPosY, 0]}
|
||||
rotation={[0, 3.95, 0]}
|
||||
renderOrder={1}
|
||||
scale={[33, 33, 33]}
|
||||
>
|
||||
<cylinderBufferGeometry
|
||||
args={[0.04, 0.04, 0.0025, 64, 64, true]}
|
||||
attach="geometry"
|
||||
/>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
side={THREE.DoubleSide}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
transparent={true}
|
||||
uniforms={uniforms}
|
||||
lights={true}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
});
|
||||
|
||||
export default GrayRing;
|
||||
|
|
|
@ -13,164 +13,164 @@ import { hudActiveAtom } from "./HUDElementAtom";
|
|||
import { currentHUDAtom } from "./HUDElementAtom";
|
||||
|
||||
export type HUDElementProps = {
|
||||
hudVisibility: boolean;
|
||||
hudVisibility: boolean;
|
||||
};
|
||||
|
||||
type HudShapeData = {
|
||||
position: number[];
|
||||
scale: number[];
|
||||
type: string;
|
||||
initial_position: number[];
|
||||
position: number[];
|
||||
scale: number[];
|
||||
type: string;
|
||||
initial_position: number[];
|
||||
};
|
||||
|
||||
export type BlueOrbHudData = {
|
||||
long: HudShapeData;
|
||||
boring: HudShapeData;
|
||||
big: HudShapeData;
|
||||
long: HudShapeData;
|
||||
boring: HudShapeData;
|
||||
big: HudShapeData;
|
||||
};
|
||||
|
||||
export type BlueOrbHuds = {
|
||||
[blue_orb_hud_id: string]: BlueOrbHudData;
|
||||
[blue_orb_hud_id: string]: BlueOrbHudData;
|
||||
};
|
||||
|
||||
type LevelYValues = {
|
||||
[level: string]: number;
|
||||
[level: string]: number;
|
||||
};
|
||||
|
||||
const HUDElement = memo((props: HUDElementProps) => {
|
||||
const currentBlueOrbHUD = useRecoilValue(currentHUDAtom);
|
||||
const currentBlueOrbHUD = useRecoilValue(currentHUDAtom);
|
||||
|
||||
const hudActive = useRecoilValue(hudActiveAtom);
|
||||
const hudActive = useRecoilValue(hudActiveAtom);
|
||||
|
||||
const { bigHUDPositionX } = useSpring({
|
||||
bigHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
const { bigHUDPositionX } = useSpring({
|
||||
bigHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
|
||||
const { longHUDPositionX } = useSpring({
|
||||
longHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
const { longHUDPositionX } = useSpring({
|
||||
longHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
|
||||
const { boringHUDPositionX } = useSpring({
|
||||
boringHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
const { boringHUDPositionX } = useSpring({
|
||||
boringHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
|
||||
const bigHUDPosX = bigHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["big"]["initial_position"][0],
|
||||
currentBlueOrbHUD["big"]["position"][0],
|
||||
]
|
||||
);
|
||||
const bigHUDPosX = bigHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["big"]["initial_position"][0],
|
||||
currentBlueOrbHUD["big"]["position"][0],
|
||||
]
|
||||
);
|
||||
|
||||
const boringHUDPosX = boringHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["boring"]["initial_position"][0],
|
||||
currentBlueOrbHUD["boring"]["position"][0],
|
||||
]
|
||||
);
|
||||
const boringHUDPosX = boringHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["boring"]["initial_position"][0],
|
||||
currentBlueOrbHUD["boring"]["position"][0],
|
||||
]
|
||||
);
|
||||
|
||||
const longHUDPosX = longHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["long"]["initial_position"][0],
|
||||
currentBlueOrbHUD["long"]["position"][0],
|
||||
]
|
||||
);
|
||||
const longHUDPosX = longHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["long"]["initial_position"][0],
|
||||
currentBlueOrbHUD["long"]["position"][0],
|
||||
]
|
||||
);
|
||||
|
||||
// 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 blue orb or the mirrored/rotated one.
|
||||
const spriteTypeToSprite = (spriteType: string, hudElement: string) => {
|
||||
switch (spriteType) {
|
||||
case "normal":
|
||||
switch (hudElement) {
|
||||
case "long":
|
||||
return longHud;
|
||||
case "boring":
|
||||
return boringHud;
|
||||
case "big":
|
||||
return bigHud;
|
||||
// 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 blue orb or the mirrored/rotated one.
|
||||
const spriteTypeToSprite = (spriteType: string, hudElement: string) => {
|
||||
switch (spriteType) {
|
||||
case "normal":
|
||||
switch (hudElement) {
|
||||
case "long":
|
||||
return longHud;
|
||||
case "boring":
|
||||
return boringHud;
|
||||
case "big":
|
||||
return bigHud;
|
||||
}
|
||||
break;
|
||||
case "mirrored":
|
||||
switch (hudElement) {
|
||||
case "big":
|
||||
return bigHudMirrored;
|
||||
case "long":
|
||||
return longHudMirrored;
|
||||
case "boring":
|
||||
return boringHudMirrored;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "mirrored":
|
||||
switch (hudElement) {
|
||||
case "big":
|
||||
return bigHudMirrored;
|
||||
case "long":
|
||||
return longHudMirrored;
|
||||
case "boring":
|
||||
return boringHudMirrored;
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const longHudTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["long"]["type"], "long")!
|
||||
);
|
||||
const longHudTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["long"]["type"], "long")!
|
||||
);
|
||||
|
||||
const longHudBoringTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["boring"]["type"], "boring")!
|
||||
);
|
||||
const longHudBoringTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["boring"]["type"], "boring")!
|
||||
);
|
||||
|
||||
const bigHudTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["big"]["type"], "big")!
|
||||
);
|
||||
const bigHudTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["big"]["type"], "big")!
|
||||
);
|
||||
|
||||
return (
|
||||
<group visible={props.hudVisibility} renderOrder={1}>
|
||||
<a.sprite
|
||||
position-x={longHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD["long"]["position"][1]
|
||||
}
|
||||
position-z={currentBlueOrbHUD["long"]["position"][2]}
|
||||
scale={currentBlueOrbHUD["long"]["scale"] as [number, number, number]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={longHudTexture}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
<a.sprite
|
||||
position-x={boringHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD!["boring"]["position"][1]
|
||||
}
|
||||
position-z={currentBlueOrbHUD!["boring"]["position"][2]}
|
||||
scale={
|
||||
currentBlueOrbHUD!["boring"]["scale"] as [number, number, number]
|
||||
}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={longHudBoringTexture}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
<a.sprite
|
||||
position-x={bigHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD!["big"]["position"][1]
|
||||
}
|
||||
position-z={currentBlueOrbHUD!["big"]["position"][2]}
|
||||
scale={currentBlueOrbHUD!["big"]["scale"] as [number, number, number]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={bigHudTexture}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
</group>
|
||||
);
|
||||
return (
|
||||
<group visible={props.hudVisibility} renderOrder={1}>
|
||||
<a.sprite
|
||||
position-x={longHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD["long"]["position"][1]
|
||||
}
|
||||
position-z={currentBlueOrbHUD["long"]["position"][2]}
|
||||
scale={currentBlueOrbHUD["long"]["scale"] as [number, number, number]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={longHudTexture}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
<a.sprite
|
||||
position-x={boringHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD!["boring"]["position"][1]
|
||||
}
|
||||
position-z={currentBlueOrbHUD!["boring"]["position"][2]}
|
||||
scale={
|
||||
currentBlueOrbHUD!["boring"]["scale"] as [number, number, number]
|
||||
}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={longHudBoringTexture}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
<a.sprite
|
||||
position-x={bigHUDPosX}
|
||||
position-y={
|
||||
currentBlueOrbHUD!["big"]["position"][1]
|
||||
}
|
||||
position-z={currentBlueOrbHUD!["big"]["position"][2]}
|
||||
scale={currentBlueOrbHUD!["big"]["scale"] as [number, number, number]}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={bigHudTexture}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.sprite>
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
||||
export default HUDElement;
|
||||
|
|
|
@ -1,426 +1,417 @@
|
|||
import React, { useCallback, useEffect, useState } from "react";
|
||||
import {
|
||||
LainMoveDown,
|
||||
LainMoveLeft,
|
||||
LainMoveRight,
|
||||
LainMoveUp,
|
||||
LainStanding,
|
||||
LainMoveDown,
|
||||
LainMoveLeft,
|
||||
LainMoveRight,
|
||||
LainMoveUp,
|
||||
LainStanding,
|
||||
} from "./Lain/Lain";
|
||||
import { useRecoilState, useRecoilValue, useSetRecoilState } from "recoil";
|
||||
import { useRecoilState, useSetRecoilState } from "recoil";
|
||||
import { currentHUDAtom, hudActiveAtom } from "./HUD/HUDElementAtom";
|
||||
import { currentBlueOrbAtom } from "./BlueOrb/CurrentBlueOrbAtom";
|
||||
import lain_animations from "../resources/lain_animations.json";
|
||||
import blue_orb_huds from "../resources/blue_orb_huds.json";
|
||||
import blue_orb_directions from "../resources/blue_orb_directions.json";
|
||||
import {
|
||||
lainMoveStateAtom,
|
||||
lainMovingAtom,
|
||||
lainPosYAtom,
|
||||
lainRotYAtom,
|
||||
lainMoveStateAtom,
|
||||
lainMovingAtom,
|
||||
lainPosYAtom,
|
||||
} from "./Lain/LainAtom";
|
||||
import { camPosYAtom, camRotYAtom } from "./MainScene/CameraAtom";
|
||||
import {
|
||||
starfieldPosYAtom,
|
||||
starfieldRotYAtom,
|
||||
starfieldPosYAtom,
|
||||
starfieldRotYAtom,
|
||||
} from "./Starfield/StarfieldAtom";
|
||||
import { BlueOrbHuds } from "./HUD/HUDElement";
|
||||
import {
|
||||
orthoCamPosYAtom,
|
||||
orthoCamRotYAtom,
|
||||
orthoCamPosYAtom,
|
||||
orthoCamRotYAtom,
|
||||
} from "./OrthoCamera/OrthoCameraAtom";
|
||||
import {
|
||||
grayPlanesPosYAtom,
|
||||
grayPlanesRotYAtom,
|
||||
grayPlanesPosYAtom,
|
||||
grayPlanesRotYAtom,
|
||||
} from "./GrayPlanes/GrayPlanesAtom";
|
||||
import {
|
||||
middleRingNoiseAtom,
|
||||
middleRingPosYAtom,
|
||||
middleRingRotatingAtom,
|
||||
middleRingRotXAtom,
|
||||
middleRingRotYAtom,
|
||||
middleRingRotZAtom,
|
||||
middleRingWobbleStrengthAtom,
|
||||
middleRingNoiseAtom,
|
||||
middleRingPosYAtom,
|
||||
middleRingRotatingAtom,
|
||||
middleRingRotXAtom,
|
||||
middleRingRotYAtom,
|
||||
middleRingRotZAtom,
|
||||
middleRingWobbleStrengthAtom,
|
||||
} from "./MiddleRing/MiddleRingAtom";
|
||||
import { lightPosYAtom, lightRotYAtom } from "./Lights/LightsAtom";
|
||||
|
||||
type KeyCodeAssociations = {
|
||||
[keyCode: number]: string;
|
||||
[keyCode: number]: string;
|
||||
};
|
||||
|
||||
type SpriteDirectionData = {
|
||||
[direction: string]: string;
|
||||
[direction: string]: string;
|
||||
};
|
||||
|
||||
type SpriteDirections = {
|
||||
[sprite_id: string]: SpriteDirectionData;
|
||||
[sprite_id: string]: SpriteDirectionData;
|
||||
};
|
||||
|
||||
type LainAnimationData = {
|
||||
frame_count: number;
|
||||
duration: number;
|
||||
frame_count: number;
|
||||
duration: number;
|
||||
};
|
||||
type LainAnimations = {
|
||||
[sprite: string]: LainAnimationData;
|
||||
[sprite: string]: LainAnimationData;
|
||||
};
|
||||
|
||||
const InputHandler = () => {
|
||||
const [currentBlueOrb, setCurrentBlueOrb] = useRecoilState(
|
||||
currentBlueOrbAtom
|
||||
);
|
||||
const [currentBlueOrb, setCurrentBlueOrb] = useRecoilState(
|
||||
currentBlueOrbAtom
|
||||
);
|
||||
|
||||
const [lainMoving, setLainMoving] = useRecoilState(lainMovingAtom);
|
||||
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
|
||||
const setLainRotY = useSetRecoilState(lainRotYAtom);
|
||||
const [lainMoving, setLainMoving] = useRecoilState(lainMovingAtom);
|
||||
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
|
||||
|
||||
const [spriteUpdateCooldown, setSpriteUpdateCooldown] = useState(false);
|
||||
const [spriteUpdateCooldown, setSpriteUpdateCooldown] = useState(false);
|
||||
|
||||
const setCurrentHUDElement = useSetRecoilState(currentHUDAtom);
|
||||
const setCurrentHUDElement = useSetRecoilState(currentHUDAtom);
|
||||
|
||||
const setHudActive = useSetRecoilState(hudActiveAtom);
|
||||
const setHudActive = useSetRecoilState(hudActiveAtom);
|
||||
|
||||
const setCamPosY = useSetRecoilState(camPosYAtom);
|
||||
const setCamRotY = useSetRecoilState(camRotYAtom);
|
||||
const setCamPosY = useSetRecoilState(camPosYAtom);
|
||||
const setCamRotY = useSetRecoilState(camRotYAtom);
|
||||
|
||||
const setOrthoCamPosY = useSetRecoilState(orthoCamPosYAtom);
|
||||
const setOrthoCamRotY = useSetRecoilState(orthoCamRotYAtom);
|
||||
const setOrthoCamPosY = useSetRecoilState(orthoCamPosYAtom);
|
||||
const setOrthoCamRotY = useSetRecoilState(orthoCamRotYAtom);
|
||||
|
||||
const setLainPosY = useSetRecoilState(lainPosYAtom);
|
||||
const setLainPosY = useSetRecoilState(lainPosYAtom);
|
||||
|
||||
const setGrayPlanePosY = useSetRecoilState(grayPlanesPosYAtom);
|
||||
const setGrayPlaneRotY = useSetRecoilState(grayPlanesRotYAtom);
|
||||
const setGrayPlanePosY = useSetRecoilState(grayPlanesPosYAtom);
|
||||
const setGrayPlaneRotY = useSetRecoilState(grayPlanesRotYAtom);
|
||||
|
||||
const setStarfieldPosY = useSetRecoilState(starfieldPosYAtom);
|
||||
const setStarfieldRotY = useSetRecoilState(starfieldRotYAtom);
|
||||
const setStarfieldPosY = useSetRecoilState(starfieldPosYAtom);
|
||||
const setStarfieldRotY = useSetRecoilState(starfieldRotYAtom);
|
||||
|
||||
const setMiddleRingWobbleStrength = useSetRecoilState(
|
||||
middleRingWobbleStrengthAtom
|
||||
);
|
||||
const setMiddleRingRotating = useSetRecoilState(middleRingRotatingAtom);
|
||||
const setMiddleRingNoise = useSetRecoilState(middleRingNoiseAtom);
|
||||
const setMiddleRingPosY = useSetRecoilState(middleRingPosYAtom);
|
||||
const setMiddleRingRotX = useSetRecoilState(middleRingRotXAtom);
|
||||
const setMiddleRingRotZ = useSetRecoilState(middleRingRotZAtom);
|
||||
const setMiddleRingRotY = useSetRecoilState(middleRingRotYAtom);
|
||||
const setMiddleRingWobbleStrength = useSetRecoilState(
|
||||
middleRingWobbleStrengthAtom
|
||||
);
|
||||
const setMiddleRingRotating = useSetRecoilState(middleRingRotatingAtom);
|
||||
const setMiddleRingNoise = useSetRecoilState(middleRingNoiseAtom);
|
||||
const setMiddleRingPosY = useSetRecoilState(middleRingPosYAtom);
|
||||
const setMiddleRingRotX = useSetRecoilState(middleRingRotXAtom);
|
||||
const setMiddleRingRotZ = useSetRecoilState(middleRingRotZAtom);
|
||||
const setMiddleRingRotY = useSetRecoilState(middleRingRotYAtom);
|
||||
|
||||
const setLightPosY = useSetRecoilState(lightPosYAtom);
|
||||
const setLightRotY = useSetRecoilState(lightRotYAtom);
|
||||
const setLightPosY = useSetRecoilState(lightPosYAtom);
|
||||
const setLightRotY = useSetRecoilState(lightRotYAtom);
|
||||
|
||||
const moveCamera = useCallback(
|
||||
(val: number) => {
|
||||
setCamPosY((prev: number) => prev + val);
|
||||
setLainPosY((prev: number) => prev - val);
|
||||
setStarfieldPosY((prev: number) => prev - val);
|
||||
setOrthoCamPosY((prev: number) => prev - val);
|
||||
setGrayPlanePosY((prev: number) => prev - val);
|
||||
setLightPosY((prev: number) => prev - val);
|
||||
const moveCamera = useCallback(
|
||||
(val: number) => {
|
||||
setCamPosY((prev: number) => prev + val);
|
||||
setLainPosY((prev: number) => prev - val);
|
||||
setStarfieldPosY((prev: number) => prev - val);
|
||||
setOrthoCamPosY((prev: number) => prev - val);
|
||||
setGrayPlanePosY((prev: number) => prev - val);
|
||||
setLightPosY((prev: number) => prev - val);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev - (val - 0.2));
|
||||
}, 1300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev - 0.2);
|
||||
}, 1800);
|
||||
},
|
||||
[
|
||||
setCamPosY,
|
||||
setLainPosY,
|
||||
setStarfieldPosY,
|
||||
setOrthoCamPosY,
|
||||
setGrayPlanePosY,
|
||||
setMiddleRingPosY,
|
||||
setLightPosY,
|
||||
]
|
||||
);
|
||||
|
||||
const rotateCamera = useCallback(
|
||||
(val: number) => {
|
||||
setCamRotY((prev: number) => prev + val);
|
||||
setStarfieldRotY((prev: number) => prev - val);
|
||||
setOrthoCamRotY((prev: number) => prev - val);
|
||||
setGrayPlaneRotY((prev: number) => prev - val);
|
||||
setLightRotY((prev: number) => prev - val);
|
||||
setLainRotY((prev: number) => prev - val);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotY((prev: number) => prev - 0.55);
|
||||
}, 1800);
|
||||
},
|
||||
[
|
||||
setCamRotY,
|
||||
setStarfieldRotY,
|
||||
setOrthoCamRotY,
|
||||
setGrayPlaneRotY,
|
||||
setLightRotY,
|
||||
setMiddleRingRotY,
|
||||
setLainRotY,
|
||||
]
|
||||
);
|
||||
|
||||
const getMove = (currentLoc: string, key: string): string => {
|
||||
return (blue_orb_directions as SpriteDirections)[currentLoc][key];
|
||||
};
|
||||
|
||||
const getKeyCodeAssociation = (keyCode: number): string => {
|
||||
return ({
|
||||
40: "down",
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
} as KeyCodeAssociations)[keyCode];
|
||||
};
|
||||
|
||||
const setAnimationState = useCallback(
|
||||
(key: string) => {
|
||||
switch (key) {
|
||||
case "down":
|
||||
setLainMoveState(<LainMoveDown />);
|
||||
|
||||
setTimeout(() => {
|
||||
moveCamera(0.25);
|
||||
}, 1300);
|
||||
|
||||
// make noise appear again
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.06);
|
||||
}, 800);
|
||||
|
||||
// disable rotation of the ring
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotating(false);
|
||||
}, 700);
|
||||
|
||||
// set ring rotation on x axis to create motion effect
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0.3);
|
||||
}, 1500);
|
||||
|
||||
// rotate it again, set ring noise to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(-0.1);
|
||||
setMiddleRingNoise(0);
|
||||
}, 3500);
|
||||
|
||||
// rotate it back AGAIN (holy fuk psx game)
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0.05);
|
||||
}, 4500);
|
||||
|
||||
// reset value, set noise to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0);
|
||||
setMiddleRingRotating(true);
|
||||
}, 4800);
|
||||
|
||||
// enable noise again in about 11-12 secs
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.03);
|
||||
}, 11600);
|
||||
|
||||
break;
|
||||
case "left":
|
||||
setTimeout(() => {
|
||||
rotateCamera(0.55);
|
||||
}, 1100);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0.07);
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(-0.03);
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0);
|
||||
}, 4500);
|
||||
|
||||
setLainMoveState(<LainMoveLeft />);
|
||||
break;
|
||||
case "up":
|
||||
setLainMoveState(<LainMoveUp />);
|
||||
|
||||
setTimeout(() => {
|
||||
moveCamera(-0.25);
|
||||
}, 1300);
|
||||
|
||||
// change noise to 0, make the ring bend downwards
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0);
|
||||
setMiddleRingWobbleStrength(0.2);
|
||||
}, 300);
|
||||
|
||||
// disable rotation of the ring
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotating(false);
|
||||
}, 700);
|
||||
|
||||
// make the ring bend upwards
|
||||
setTimeout(() => {
|
||||
setMiddleRingWobbleStrength(-0.3);
|
||||
}, 1300);
|
||||
|
||||
// reset the ring bend, set the rotation to slightly curve
|
||||
// to replicate a motion effect (since its moving upwards)
|
||||
// and enable rotation again
|
||||
setTimeout(() => {
|
||||
setMiddleRingWobbleStrength(0.0);
|
||||
setMiddleRingRotX(-0.2);
|
||||
setMiddleRingRotating(true);
|
||||
}, 1500);
|
||||
|
||||
// reset the rotation value to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0);
|
||||
}, 2500);
|
||||
|
||||
// enable noise again in about 8~ secs
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.03);
|
||||
}, 7800);
|
||||
|
||||
break;
|
||||
case "right":
|
||||
setTimeout(() => {
|
||||
rotateCamera(-0.55);
|
||||
}, 1100);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(-0.07);
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0.03);
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0);
|
||||
}, 4500);
|
||||
|
||||
setLainMoveState(<LainMoveRight />);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// set moving to true to avoid player from overlapping animations and stuff
|
||||
// by waiting for the anim to finish
|
||||
setLainMoving(true);
|
||||
|
||||
// wait for the anim to finish, set lain to standing state, release the move lock
|
||||
setTimeout(() => {
|
||||
setLainMoveState(<LainStanding />);
|
||||
setTimeout(() => {
|
||||
setLainMoving(false);
|
||||
}, 300);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"]);
|
||||
},
|
||||
[
|
||||
moveCamera,
|
||||
rotateCamera,
|
||||
setLainMoveState,
|
||||
setLainMoving,
|
||||
setMiddleRingNoise,
|
||||
setMiddleRingRotX,
|
||||
setMiddleRingRotZ,
|
||||
setMiddleRingRotating,
|
||||
setMiddleRingWobbleStrength,
|
||||
]
|
||||
);
|
||||
|
||||
const updateHUD = useCallback(() => {
|
||||
setHudActive((prev: number) => Number(!prev));
|
||||
}, [setHudActive]);
|
||||
|
||||
const moveDispatcher = useCallback(
|
||||
(move: string, key: string) => {
|
||||
switch (move[0]) {
|
||||
// do nothing / cant move
|
||||
case undefined:
|
||||
break;
|
||||
// "+" in the json denotes that the sprite chosen by getMove is not currently on screen,
|
||||
// therefore lain should first do a move (up/down/left/right) and then that sprite
|
||||
// will be chosen.
|
||||
case "+":
|
||||
if (!spriteUpdateCooldown) {
|
||||
// hide the hud
|
||||
updateHUD();
|
||||
// disable glow on current sprite
|
||||
setCurrentBlueOrb("");
|
||||
setSpriteUpdateCooldown(true);
|
||||
setAnimationState(key);
|
||||
setTimeout(() => {
|
||||
updateHUD();
|
||||
// skip the "+"
|
||||
setCurrentBlueOrb(move.substr(1));
|
||||
setCurrentHUDElement(
|
||||
(blue_orb_huds as BlueOrbHuds)[move.substr(3)]
|
||||
);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
|
||||
setMiddleRingPosY((prev: number) => prev - (val - 0.2));
|
||||
}, 1300);
|
||||
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
}
|
||||
break;
|
||||
// only change sprite focus
|
||||
default:
|
||||
if (!spriteUpdateCooldown) {
|
||||
setCurrentBlueOrb(move);
|
||||
setSpriteUpdateCooldown(true);
|
||||
// toggle hud to go back in
|
||||
updateHUD();
|
||||
setMiddleRingPosY((prev: number) => prev - 0.2);
|
||||
}, 1800);
|
||||
},
|
||||
[
|
||||
setCamPosY,
|
||||
setLainPosY,
|
||||
setStarfieldPosY,
|
||||
setOrthoCamPosY,
|
||||
setGrayPlanePosY,
|
||||
setMiddleRingPosY,
|
||||
setLightPosY,
|
||||
]
|
||||
);
|
||||
|
||||
const rotateCamera = useCallback(
|
||||
(val: number) => {
|
||||
setCamRotY((prev: number) => prev + val);
|
||||
setStarfieldRotY((prev: number) => prev - val);
|
||||
setOrthoCamRotY((prev: number) => prev - val);
|
||||
setGrayPlaneRotY((prev: number) => prev - val);
|
||||
setLightRotY((prev: number) => prev - val);
|
||||
|
||||
setTimeout(() => {
|
||||
// change hud while its hidden
|
||||
setCurrentHUDElement(
|
||||
(blue_orb_huds as BlueOrbHuds)[move.substr(2)]
|
||||
);
|
||||
// toggle it again to be shown in the new position
|
||||
updateHUD();
|
||||
}, 500);
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
setAnimationState,
|
||||
updateHUD,
|
||||
spriteUpdateCooldown,
|
||||
setCurrentHUDElement,
|
||||
setCurrentBlueOrb,
|
||||
]
|
||||
);
|
||||
setMiddleRingRotY((prev: number) => prev - 0.55);
|
||||
}, 1800);
|
||||
},
|
||||
[
|
||||
setCamRotY,
|
||||
setStarfieldRotY,
|
||||
setOrthoCamRotY,
|
||||
setGrayPlaneRotY,
|
||||
setLightRotY,
|
||||
setMiddleRingRotY,
|
||||
]
|
||||
);
|
||||
|
||||
const handleKeyPress = useCallback(
|
||||
(event) => {
|
||||
const { keyCode } = event;
|
||||
|
||||
const key = getKeyCodeAssociation(keyCode);
|
||||
|
||||
if (key && !lainMoving) {
|
||||
setTimeout(() => {
|
||||
rotateCamera(0.785);
|
||||
}, 1100);
|
||||
//
|
||||
const move = getMove(currentBlueOrb, key);
|
||||
|
||||
moveDispatcher(move, key);
|
||||
}
|
||||
},
|
||||
[lainMoving, currentBlueOrb, moveDispatcher, rotateCamera]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", handleKeyPress);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyPress);
|
||||
const getMove = (currentLoc: string, key: string): string => {
|
||||
return (blue_orb_directions as SpriteDirections)[currentLoc][key];
|
||||
};
|
||||
}, [handleKeyPress]);
|
||||
|
||||
return <></>;
|
||||
const getKeyCodeAssociation = (keyCode: number): string => {
|
||||
return ({
|
||||
40: "down",
|
||||
37: "left",
|
||||
38: "up",
|
||||
39: "right",
|
||||
} as KeyCodeAssociations)[keyCode];
|
||||
};
|
||||
|
||||
const setAnimationState = useCallback(
|
||||
(key: string) => {
|
||||
switch (key) {
|
||||
case "down":
|
||||
setLainMoveState(<LainMoveDown />);
|
||||
|
||||
setTimeout(() => {
|
||||
moveCamera(1.5);
|
||||
}, 1300);
|
||||
|
||||
// make noise appear again
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.06);
|
||||
}, 800);
|
||||
|
||||
// disable rotation of the ring
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotating(false);
|
||||
}, 700);
|
||||
|
||||
// set ring rotation on x axis to craete motion effect
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0.3);
|
||||
}, 1500);
|
||||
|
||||
// rotate it again, set ring noise to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(-0.1);
|
||||
setMiddleRingNoise(0);
|
||||
}, 3500);
|
||||
|
||||
// rotate it back AGAIN (holy fuk psx game)
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0.05);
|
||||
}, 4500);
|
||||
|
||||
// reset value, set noise to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0);
|
||||
setMiddleRingRotating(true);
|
||||
}, 4800);
|
||||
|
||||
// enable noise again in about 11-12 secs
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.03);
|
||||
}, 11600);
|
||||
|
||||
break;
|
||||
case "left":
|
||||
setTimeout(() => {
|
||||
rotateCamera(0.55);
|
||||
}, 1100);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0.07);
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(-0.03);
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0);
|
||||
}, 4500);
|
||||
|
||||
setLainMoveState(<LainMoveLeft />);
|
||||
break;
|
||||
case "up":
|
||||
setLainMoveState(<LainMoveUp />);
|
||||
|
||||
setTimeout(() => {
|
||||
moveCamera(-1.5);
|
||||
}, 1300);
|
||||
|
||||
// change noise to 0, make the ring bend downwards
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0);
|
||||
setMiddleRingWobbleStrength(0.2);
|
||||
}, 300);
|
||||
|
||||
// disable rotation of the ring
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotating(false);
|
||||
}, 700);
|
||||
|
||||
// make the ring bend upwards
|
||||
setTimeout(() => {
|
||||
setMiddleRingWobbleStrength(-0.3);
|
||||
}, 1300);
|
||||
|
||||
// reset the ring bend, set the rotation to slightly curve
|
||||
// to replicate a motion effect (since its moving upwards)
|
||||
// and enable rotation again
|
||||
setTimeout(() => {
|
||||
setMiddleRingWobbleStrength(0.0);
|
||||
setMiddleRingRotX(-0.2);
|
||||
setMiddleRingRotating(true);
|
||||
}, 1500);
|
||||
|
||||
// reset the rotation value to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0);
|
||||
}, 2500);
|
||||
|
||||
// enable noise again in about 8~ secs
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.03);
|
||||
}, 7800);
|
||||
|
||||
break;
|
||||
case "right":
|
||||
setTimeout(() => {
|
||||
rotateCamera(-0.55);
|
||||
}, 1100);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(-0.07);
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0.03);
|
||||
}, 3500);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotZ(0);
|
||||
}, 4500);
|
||||
|
||||
setLainMoveState(<LainMoveRight />);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// set moving to true to avoid player from overlapping animations and stuff
|
||||
// by waiting for the anim to finish
|
||||
setLainMoving(true);
|
||||
|
||||
// wait for the anim to finish, set lain to standing state, release the move lock
|
||||
setTimeout(() => {
|
||||
setLainMoveState(<LainStanding />);
|
||||
setTimeout(() => {
|
||||
setLainMoving(false);
|
||||
}, 300);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"]);
|
||||
},
|
||||
[
|
||||
moveCamera,
|
||||
rotateCamera,
|
||||
setLainMoveState,
|
||||
setLainMoving,
|
||||
setMiddleRingNoise,
|
||||
setMiddleRingRotX,
|
||||
setMiddleRingRotating,
|
||||
setMiddleRingWobbleStrength,
|
||||
]
|
||||
);
|
||||
|
||||
const updateHUD = useCallback(() => {
|
||||
setHudActive((prev: number) => Number(!prev));
|
||||
}, [setHudActive]);
|
||||
|
||||
const moveDispatcher = useCallback(
|
||||
(move: string, key: string) => {
|
||||
switch (move[0]) {
|
||||
// do nothing / cant move
|
||||
case undefined:
|
||||
break;
|
||||
// "+" in the json denotes that the sprite chosen by getMove is not currently on screen,
|
||||
// therefore lain should first do a move (up/down/left/right) and then that sprite
|
||||
// will be chosen.
|
||||
case "+":
|
||||
if (!spriteUpdateCooldown) {
|
||||
// hide the hud
|
||||
updateHUD();
|
||||
// disable glow on current sprite
|
||||
setCurrentBlueOrb("");
|
||||
setSpriteUpdateCooldown(true);
|
||||
setAnimationState(key);
|
||||
setTimeout(() => {
|
||||
updateHUD();
|
||||
// skip the "+"
|
||||
setCurrentBlueOrb(move.substr(1));
|
||||
setCurrentHUDElement(
|
||||
(blue_orb_huds as BlueOrbHuds)[move.substr(3)]
|
||||
);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
}
|
||||
break;
|
||||
// only change sprite focus
|
||||
default:
|
||||
if (!spriteUpdateCooldown) {
|
||||
setCurrentBlueOrb(move);
|
||||
setSpriteUpdateCooldown(true);
|
||||
// toggle hud to go back in
|
||||
updateHUD();
|
||||
setTimeout(() => {
|
||||
// change hud while its hidden
|
||||
setCurrentHUDElement(
|
||||
(blue_orb_huds as BlueOrbHuds)[move.substr(2)]
|
||||
);
|
||||
// toggle it again to be shown in the new position
|
||||
updateHUD();
|
||||
}, 500);
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
setAnimationState,
|
||||
updateHUD,
|
||||
spriteUpdateCooldown,
|
||||
setCurrentHUDElement,
|
||||
setCurrentBlueOrb,
|
||||
]
|
||||
);
|
||||
|
||||
const handleKeyPress = useCallback(
|
||||
(event) => {
|
||||
const { keyCode } = event;
|
||||
|
||||
const key = getKeyCodeAssociation(keyCode);
|
||||
|
||||
if (key && !lainMoving) {
|
||||
const move = getMove(currentBlueOrb, key);
|
||||
|
||||
moveDispatcher(move, key);
|
||||
}
|
||||
},
|
||||
[lainMoving, currentBlueOrb, moveDispatcher]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener("keydown", handleKeyPress);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener("keydown", handleKeyPress);
|
||||
};
|
||||
}, [handleKeyPress]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
export default InputHandler;
|
||||
|
|
|
@ -10,139 +10,130 @@ import moveRightSpriteSheet from "../../static/sprites/move_right.png";
|
|||
import standingSpriteSheet from "../../static/sprites/standing.png";
|
||||
import introSpriteSheet from "../../static/sprites/intro.png";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import {
|
||||
lainMoveStateAtom,
|
||||
lainMovingAtom,
|
||||
lainPosYAtom,
|
||||
lainRotYAtom,
|
||||
} from "./LainAtom";
|
||||
import { lainMoveStateAtom, lainMovingAtom, lainPosYAtom } from "./LainAtom";
|
||||
|
||||
type LainConstructorProps = {
|
||||
sprite: string;
|
||||
frameCount: number;
|
||||
framesVertical: number;
|
||||
framesHorizontal: number;
|
||||
sprite: string;
|
||||
frameCount: number;
|
||||
framesVertical: number;
|
||||
framesHorizontal: number;
|
||||
};
|
||||
|
||||
const LainConstructor = (props: LainConstructorProps) => {
|
||||
// any here temporarily
|
||||
const lainSpriteTexture: any = useLoader(THREE.TextureLoader, props.sprite);
|
||||
// any here temporarily
|
||||
const lainSpriteTexture: any = useLoader(THREE.TextureLoader, props.sprite);
|
||||
|
||||
const [animator] = useState(
|
||||
() =>
|
||||
new PlainSingularAnimator(
|
||||
lainSpriteTexture,
|
||||
props.framesHorizontal,
|
||||
props.framesVertical,
|
||||
props.frameCount,
|
||||
props.frameCount * 0.27
|
||||
)
|
||||
);
|
||||
const [animator] = useState(
|
||||
() =>
|
||||
new PlainSingularAnimator(
|
||||
lainSpriteTexture,
|
||||
props.framesHorizontal,
|
||||
props.framesVertical,
|
||||
props.frameCount,
|
||||
props.frameCount * 0.27
|
||||
)
|
||||
);
|
||||
|
||||
useFrame(() => {
|
||||
animator.animate();
|
||||
});
|
||||
useFrame(() => {
|
||||
animator.animate();
|
||||
});
|
||||
|
||||
return (
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={lainSpriteTexture}
|
||||
alphaTest={0.01}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={lainSpriteTexture}
|
||||
alphaTest={0.01}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LainIntro = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={introSpriteSheet}
|
||||
frameCount={50}
|
||||
framesHorizontal={10}
|
||||
framesVertical={5}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={introSpriteSheet}
|
||||
frameCount={50}
|
||||
framesHorizontal={10}
|
||||
framesVertical={5}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LainStanding = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={standingSpriteSheet}
|
||||
frameCount={3}
|
||||
framesHorizontal={3}
|
||||
framesVertical={1}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={standingSpriteSheet}
|
||||
frameCount={3}
|
||||
framesHorizontal={3}
|
||||
framesVertical={1}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LainMoveDown = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveDownSpriteSheet}
|
||||
frameCount={36}
|
||||
framesHorizontal={6}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveDownSpriteSheet}
|
||||
frameCount={36}
|
||||
framesHorizontal={6}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LainMoveLeft = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveLeftSpriteSheet}
|
||||
frameCount={47}
|
||||
framesHorizontal={8}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveLeftSpriteSheet}
|
||||
frameCount={47}
|
||||
framesHorizontal={8}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LainMoveRight = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveRightSpriteSheet}
|
||||
frameCount={47}
|
||||
framesHorizontal={8}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveRightSpriteSheet}
|
||||
frameCount={47}
|
||||
framesHorizontal={8}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const LainMoveUp = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveUpSpriteSheet}
|
||||
frameCount={36}
|
||||
framesHorizontal={6}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={moveUpSpriteSheet}
|
||||
frameCount={36}
|
||||
framesHorizontal={6}
|
||||
framesVertical={6}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const Lain = () => {
|
||||
const lainMoving = useRecoilValue(lainMovingAtom);
|
||||
const lainMoveState = useRecoilValue(lainMoveStateAtom);
|
||||
const lainPosY = useRecoilValue(lainPosYAtom);
|
||||
const lainRotY = useRecoilValue(lainRotYAtom);
|
||||
const lainMoving = useRecoilValue(lainMovingAtom);
|
||||
const lainMoveState = useRecoilValue(lainMoveStateAtom);
|
||||
const lainPosY = useRecoilValue(lainPosYAtom);
|
||||
|
||||
const lainPosYState = useSpring({
|
||||
lainPosY: lainPosY,
|
||||
lainRotY: lainRotY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
const lainPosYState = useSpring({
|
||||
lainPosY: lainPosY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
|
||||
return (
|
||||
<Suspense fallback={<>loading...</>}>
|
||||
<a.group rotation-y={lainPosYState.lainRotY}>
|
||||
<a.sprite
|
||||
position-y={lainPosYState.lainPosY}
|
||||
position-z={0.05}
|
||||
scale={[0.6, 0.6, 0.6]}
|
||||
>
|
||||
{lainMoving ? lainMoveState : <LainStanding />}
|
||||
</a.sprite>
|
||||
</a.group>
|
||||
</Suspense>
|
||||
);
|
||||
return (
|
||||
<Suspense fallback={<>loading...</>}>
|
||||
<a.sprite
|
||||
position-x={0.1}
|
||||
position-y={lainPosYState.lainPosY}
|
||||
scale={[4.9, 4.9, 4.9]}
|
||||
>
|
||||
{lainMoving ? lainMoveState : <LainStanding />}
|
||||
</a.sprite>
|
||||
</Suspense>
|
||||
);
|
||||
};
|
||||
|
||||
export default Lain;
|
||||
|
|
|
@ -3,7 +3,7 @@ import React from "react";
|
|||
|
||||
export const lainPosYAtom = atom({
|
||||
key: "lainPosYAtom",
|
||||
default: -0.02,
|
||||
default: -0.15,
|
||||
});
|
||||
|
||||
export const lainRotYAtom = atom({
|
||||
|
|
|
@ -5,17 +5,17 @@ import CyanCrystal from "./CyanCrystal";
|
|||
|
||||
//constructor for levels
|
||||
type LevelProps = {
|
||||
levelPosY: number;
|
||||
levelPosY: number;
|
||||
};
|
||||
|
||||
const Level = (props: LevelProps) => {
|
||||
return (
|
||||
<group position={[0, props.levelPosY, 0]}>
|
||||
<PurpleRing purpleRingPosY={0.07} />
|
||||
<GrayRing grayRingPosY={-0.045} />
|
||||
<CyanCrystal crystalRingPosY={-0.45} />
|
||||
</group>
|
||||
);
|
||||
return (
|
||||
<group position={[0, props.levelPosY, 0]}>
|
||||
<PurpleRing purpleRingPosY={0.43} />
|
||||
<GrayRing grayRingPosY={-0.28} />
|
||||
<CyanCrystal crystalRingPosY={-0.45} />
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
export default Level;
|
||||
|
|
|
@ -1,44 +1,30 @@
|
|||
import React, { memo, useRef } from "react";
|
||||
import React, { memo } from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { lightPosYAtom, lightRotYAtom } from "./LightsAtom";
|
||||
|
||||
const Lights = memo(() => {
|
||||
const lightRotY = useRecoilValue(lightRotYAtom);
|
||||
const lightPosY = useRecoilValue(lightPosYAtom);
|
||||
const lightRotY = useRecoilValue(lightRotYAtom);
|
||||
const lightPosY = useRecoilValue(lightPosYAtom);
|
||||
|
||||
const lightState = useSpring({
|
||||
lightRotY: lightRotY,
|
||||
lightPosY: lightPosY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
const lightState = useSpring({
|
||||
lightRotY: lightRotY,
|
||||
lightPosY: lightPosY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
|
||||
return (
|
||||
<a.group
|
||||
position-y={lightState.lightPosY}
|
||||
rotation-y={lightState.lightRotY}
|
||||
>
|
||||
|
||||
<pointLight color={0xffffff} position={[0, 0, 6]} intensity={1} />
|
||||
|
||||
<pointLight color={0x7f7f7f} position={[0, 0.5, -0.5]} intensity={2.5} />
|
||||
|
||||
{/*<pointLight color={0xffffff} position={[0, 0, 6.2]} intensity={1} />*/}
|
||||
{/*<mesh position={[50.09, -1, 5.2]} scale={[0.1, 0.1, 0.1]}>*/}
|
||||
{/* <sphereBufferGeometry attach="geometry">*/}
|
||||
{/* <meshStandardMaterial color={0xffffff} attach="material" />*/}
|
||||
{/* </sphereBufferGeometry>*/}
|
||||
{/*</mesh>*/}
|
||||
|
||||
{/*<pointLight color={0xffffff} position={[0.08, 0, 0]} intensity={0.3} />*/}
|
||||
{/*<mesh position={[0.08, 0, 0]} scale={[0.01, 0.01, 0.01]}>*/}
|
||||
{/* <sphereBufferGeometry attach="geometry">*/}
|
||||
{/* <meshStandardMaterial color={0xffffff} attach="material" />*/}
|
||||
{/* </sphereBufferGeometry>*/}
|
||||
{/*</mesh>*/}
|
||||
|
||||
</a.group>
|
||||
);
|
||||
return (
|
||||
<a.group
|
||||
position-y={lightState.lightPosY}
|
||||
rotation-y={lightState.lightRotY}
|
||||
>
|
||||
<ambientLight color={0x808080} intensity={0.6} />
|
||||
<pointLight color={0xffffff} position={[0, 0, 7]} intensity={0.7} />
|
||||
<pointLight color={0x7f7f7f} position={[0, 10, 0]} intensity={1.5} />
|
||||
<pointLight color={0xffffff} position={[-8, 0, 0]} intensity={0.3} />
|
||||
<pointLight color={0xffffff} position={[8, 0, 0]} intensity={0.3} />
|
||||
</a.group>
|
||||
);
|
||||
});
|
||||
|
||||
export default Lights;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { a, useSpring } from "@react-spring/three";
|
||||
import { OrbitControls } from "drei";
|
||||
import React, { Suspense, useEffect } from "react";
|
||||
import Site from "../Site/Site";
|
||||
import Site from "../Site";
|
||||
import Lain, { LainIntro } from "../Lain/Lain";
|
||||
import Lights from "../Lights/Lights";
|
||||
import OrthoCamera from "../OrthoCamera/OrthoCamera";
|
||||
|
@ -13,73 +13,72 @@ import { camPosYAtom, camRotYAtom } from "./CameraAtom";
|
|||
import InputHandler from "../InputHandler";
|
||||
import MainSceneIntro from "./MainSceneIntro";
|
||||
import {
|
||||
mainGroupPosYAtom,
|
||||
mainGroupPosZAtom,
|
||||
mainGroupRotXAtom,
|
||||
mainGroupPosYAtom,
|
||||
mainGroupPosZAtom,
|
||||
mainGroupRotXAtom,
|
||||
} from "./MainGroupAtom";
|
||||
import GrayPlanes from "../GrayPlanes/GrayPlanes";
|
||||
import MiddleRing from "../MiddleRing/MiddleRing";
|
||||
|
||||
const MainScene = () => {
|
||||
const setLainMoving = useSetRecoilState(lainMovingAtom);
|
||||
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
|
||||
const mainGroupPosY = useRecoilValue(mainGroupPosYAtom);
|
||||
const mainGroupPosZ = useRecoilValue(mainGroupPosZAtom);
|
||||
const mainGroupRotX = useRecoilValue(mainGroupRotXAtom);
|
||||
const setLainMoving = useSetRecoilState(lainMovingAtom);
|
||||
const setLainMoveState = useSetRecoilState(lainMoveStateAtom);
|
||||
const mainGroupPosY = useRecoilValue(mainGroupPosYAtom);
|
||||
const mainGroupPosZ = useRecoilValue(mainGroupPosZAtom);
|
||||
const mainGroupRotX = useRecoilValue(mainGroupRotXAtom);
|
||||
|
||||
const camPosY = useRecoilValue(camPosYAtom);
|
||||
const camRotY = useRecoilValue(camRotYAtom);
|
||||
const camPosY = useRecoilValue(camPosYAtom);
|
||||
const camRotY = useRecoilValue(camRotYAtom);
|
||||
|
||||
const cameraState = useSpring({
|
||||
camPosY: camPosY,
|
||||
camRotY: camRotY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
const cameraState = useSpring({
|
||||
camPosY: camPosY,
|
||||
camRotY: camRotY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
|
||||
const mainGroupStatePos = useSpring({
|
||||
mainGroupPosY: mainGroupPosY,
|
||||
mainGroupPosZ: mainGroupPosZ,
|
||||
config: { duration: 3644 },
|
||||
});
|
||||
const mainGroupStatePos = useSpring({
|
||||
mainGroupPosY: mainGroupPosY,
|
||||
mainGroupPosZ: mainGroupPosZ,
|
||||
config: { duration: 3644 },
|
||||
});
|
||||
|
||||
const mainGroupStateRot = useSpring({
|
||||
mainGroupRotX: mainGroupRotX,
|
||||
config: { duration: 1500 },
|
||||
});
|
||||
const mainGroupStateRot = useSpring({
|
||||
mainGroupRotX: mainGroupRotX,
|
||||
config: { duration: 1500 },
|
||||
});
|
||||
|
||||
// set lain intro spritesheet before the page loads fully
|
||||
useEffect(() => {
|
||||
// setLainMoving(true);
|
||||
// setLainMoveState(<LainIntro />);
|
||||
}, [setLainMoveState, setLainMoving]);
|
||||
// set lain intro spritesheet before the page loads fully
|
||||
useEffect(() => {
|
||||
// setLainMoving(true);
|
||||
// setLainMoveState(<LainIntro />);
|
||||
}, [setLainMoveState, setLainMoving]);
|
||||
|
||||
return (
|
||||
<a.perspectiveCamera
|
||||
position-z={4.69}
|
||||
position-y={cameraState.camPosY}
|
||||
rotation-y={cameraState.camRotY}
|
||||
rotation-x={-0.01}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<MainSceneIntro />
|
||||
<a.group
|
||||
rotation-x={mainGroupStateRot.mainGroupRotX}
|
||||
position-y={mainGroupStatePos.mainGroupPosY}
|
||||
position-z={mainGroupStatePos.mainGroupPosZ}
|
||||
return (
|
||||
<a.perspectiveCamera
|
||||
position-z={3}
|
||||
position-y={cameraState.camPosY}
|
||||
rotation-y={cameraState.camRotY}
|
||||
>
|
||||
<InputHandler />
|
||||
<Preloader />
|
||||
<Site />
|
||||
<OrthoCamera />
|
||||
<Starfield />
|
||||
<GrayPlanes />
|
||||
<Lights />
|
||||
{/*<MiddleRing />*/}
|
||||
<OrbitControls />
|
||||
</a.group>
|
||||
<Lain />
|
||||
</Suspense>
|
||||
</a.perspectiveCamera>
|
||||
);
|
||||
<Suspense fallback={null}>
|
||||
<MainSceneIntro />
|
||||
<a.group
|
||||
rotation-x={mainGroupStateRot.mainGroupRotX}
|
||||
position-y={mainGroupStatePos.mainGroupPosY}
|
||||
position-z={mainGroupStatePos.mainGroupPosZ}
|
||||
>
|
||||
<InputHandler />
|
||||
<Preloader />
|
||||
<Site />
|
||||
<OrthoCamera />
|
||||
<Starfield />
|
||||
<GrayPlanes />
|
||||
<Lights />
|
||||
<MiddleRing />
|
||||
<OrbitControls />
|
||||
</a.group>
|
||||
<Lain />
|
||||
</Suspense>
|
||||
</a.perspectiveCamera>
|
||||
);
|
||||
};
|
||||
export default MainScene;
|
||||
|
|
|
@ -4,59 +4,59 @@ import middleRingTexture from "../../static/sprites/middle_ring_tex.png";
|
|||
import * as THREE from "three";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import {
|
||||
middleRingNoiseAtom,
|
||||
middleRingPosYAtom,
|
||||
middleRingRotatingAtom,
|
||||
middleRingRotXAtom,
|
||||
middleRingRotYAtom,
|
||||
middleRingRotZAtom,
|
||||
middleRingWobbleStrengthAtom,
|
||||
middleRingNoiseAtom,
|
||||
middleRingPosYAtom,
|
||||
middleRingRotatingAtom,
|
||||
middleRingRotXAtom,
|
||||
middleRingRotYAtom,
|
||||
middleRingRotZAtom,
|
||||
middleRingWobbleStrengthAtom,
|
||||
} from "./MiddleRingAtom";
|
||||
import { useRecoilValue } from "recoil";
|
||||
|
||||
const MiddleRing = () => {
|
||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
||||
const middleRingTex = useLoader(THREE.TextureLoader, middleRingTexture);
|
||||
|
||||
const middleRingWobbleStrength = useRecoilValue(middleRingWobbleStrengthAtom);
|
||||
const middleRingRotating = useRecoilValue(middleRingRotatingAtom);
|
||||
const middleRingNoise = useRecoilValue(middleRingNoiseAtom);
|
||||
const middleRingPosY = useRecoilValue(middleRingPosYAtom);
|
||||
const middleRingRotX = useRecoilValue(middleRingRotXAtom);
|
||||
const middleRingRotZ = useRecoilValue(middleRingRotZAtom);
|
||||
const middleRingRotY = useRecoilValue(middleRingRotYAtom);
|
||||
const middleRingWobbleStrength = useRecoilValue(middleRingWobbleStrengthAtom);
|
||||
const middleRingRotating = useRecoilValue(middleRingRotatingAtom);
|
||||
const middleRingNoise = useRecoilValue(middleRingNoiseAtom);
|
||||
const middleRingPosY = useRecoilValue(middleRingPosYAtom);
|
||||
const middleRingRotX = useRecoilValue(middleRingRotXAtom);
|
||||
const middleRingRotZ = useRecoilValue(middleRingRotZAtom);
|
||||
const middleRingRotY = useRecoilValue(middleRingRotYAtom);
|
||||
|
||||
const middleRingWobbleState = useSpring({
|
||||
middleRingWobbleStrength: middleRingWobbleStrength,
|
||||
middleRingNoise: middleRingNoise,
|
||||
config: { duration: 200 },
|
||||
});
|
||||
const middleRingWobbleState = useSpring({
|
||||
middleRingWobbleStrength: middleRingWobbleStrength,
|
||||
middleRingNoise: middleRingNoise,
|
||||
config: { duration: 200 },
|
||||
});
|
||||
|
||||
const middleRingPosState = useSpring({
|
||||
middleRingPosY: middleRingPosY,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
const middleRingPosState = useSpring({
|
||||
middleRingPosY: middleRingPosY,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
|
||||
const middleRingRotState = useSpring({
|
||||
middleRingRotX: middleRingRotX,
|
||||
middleRingRotZ: middleRingRotZ,
|
||||
middleRingRotY: middleRingRotY,
|
||||
config: { duration: 1000 },
|
||||
});
|
||||
const middleRingRotState = useSpring({
|
||||
middleRingRotX: middleRingRotX,
|
||||
middleRingRotZ: middleRingRotZ,
|
||||
middleRingRotY: middleRingRotY,
|
||||
config: { duration: 1000 },
|
||||
});
|
||||
|
||||
const uniforms = useMemo(
|
||||
() => ({
|
||||
tex: { type: "t", value: middleRingTex },
|
||||
uTime: { value: 1.0 },
|
||||
wobbleStrength: { value: 0.0 },
|
||||
noiseAmp: { value: 0.03 },
|
||||
}),
|
||||
[middleRingTex]
|
||||
);
|
||||
const uniforms = useMemo(
|
||||
() => ({
|
||||
tex: { type: "t", value: middleRingTex },
|
||||
uTime: { value: 1.0 },
|
||||
wobbleStrength: { value: 0.0 },
|
||||
noiseAmp: { value: 0.03 },
|
||||
}),
|
||||
[middleRingTex]
|
||||
);
|
||||
|
||||
const middleRingMaterialRef = useRef<THREE.ShaderMaterial>();
|
||||
const middleRingRef = useRef<THREE.Object3D>();
|
||||
const middleRingMaterialRef = useRef<THREE.ShaderMaterial>();
|
||||
const middleRingRef = useRef<THREE.Object3D>();
|
||||
|
||||
const vertexShader = `
|
||||
const vertexShader = `
|
||||
varying vec2 vUv;
|
||||
uniform float uTime;
|
||||
uniform float wobbleStrength;
|
||||
|
@ -187,7 +187,7 @@ const MiddleRing = () => {
|
|||
}
|
||||
`;
|
||||
|
||||
const fragmentShader = `
|
||||
const fragmentShader = `
|
||||
uniform sampler2D tex;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
@ -197,49 +197,49 @@ const MiddleRing = () => {
|
|||
}
|
||||
`;
|
||||
|
||||
const clock = new THREE.Clock();
|
||||
const clock = new THREE.Clock();
|
||||
|
||||
useFrame(() => {
|
||||
if (middleRingMaterialRef.current) {
|
||||
middleRingMaterialRef.current.uniforms.uTime.value = clock.getElapsedTime();
|
||||
middleRingMaterialRef.current.uniforms.wobbleStrength.value = middleRingWobbleState.middleRingWobbleStrength.get();
|
||||
middleRingMaterialRef.current.uniforms.noiseAmp.value = middleRingWobbleState.middleRingNoise.get();
|
||||
useFrame(() => {
|
||||
if (middleRingMaterialRef.current) {
|
||||
middleRingMaterialRef.current.uniforms.uTime.value = clock.getElapsedTime();
|
||||
middleRingMaterialRef.current.uniforms.wobbleStrength.value = middleRingWobbleState.middleRingWobbleStrength.get();
|
||||
middleRingMaterialRef.current.uniforms.noiseAmp.value = middleRingWobbleState.middleRingNoise.get();
|
||||
|
||||
middleRingMaterialRef.current.needsUpdate = true;
|
||||
}
|
||||
if (middleRingRotating) {
|
||||
middleRingRef.current!.rotation.y += 0.05;
|
||||
}
|
||||
});
|
||||
middleRingMaterialRef.current.needsUpdate = true;
|
||||
}
|
||||
if (middleRingRotating) {
|
||||
middleRingRef.current!.rotation.y += 0.05;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<a.group
|
||||
rotation-z={middleRingRotState.middleRingRotZ}
|
||||
rotation-y={middleRingRotState.middleRingRotY}
|
||||
>
|
||||
<a.mesh
|
||||
position={[0, 0, 0.3]}
|
||||
position-y={middleRingPosState.middleRingPosY}
|
||||
ref={middleRingRef}
|
||||
rotation={[0, 0.9, 0]}
|
||||
rotation-x={middleRingRotState.middleRingRotX}
|
||||
>
|
||||
<cylinderBufferGeometry
|
||||
args={[0.85, 0.85, 0.027, 64, 64, true]}
|
||||
attach="geometry"
|
||||
/>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
side={THREE.DoubleSide}
|
||||
uniforms={uniforms}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
ref={middleRingMaterialRef}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.mesh>
|
||||
</a.group>
|
||||
);
|
||||
return (
|
||||
<a.group
|
||||
rotation-z={middleRingRotState.middleRingRotZ}
|
||||
rotation-y={middleRingRotState.middleRingRotY}
|
||||
>
|
||||
<a.mesh
|
||||
position={[0, 0, 0.3]}
|
||||
position-y={middleRingPosState.middleRingPosY}
|
||||
ref={middleRingRef}
|
||||
rotation={[0, 0.9, 0]}
|
||||
rotation-x={middleRingRotState.middleRingRotX}
|
||||
>
|
||||
<cylinderBufferGeometry
|
||||
args={[0.85, 0.85, 0.027, 64, 64, true]}
|
||||
attach="geometry"
|
||||
/>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
side={THREE.DoubleSide}
|
||||
uniforms={uniforms}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
ref={middleRingMaterialRef}
|
||||
transparent={true}
|
||||
/>
|
||||
</a.mesh>
|
||||
</a.group>
|
||||
);
|
||||
};
|
||||
|
||||
export default MiddleRing;
|
||||
|
|
|
@ -10,44 +10,44 @@ import { orbVisibilityAtom } from "../Orb/OrbAtom";
|
|||
import { hudVisibilityAtom } from "../HUD/HUDElementAtom";
|
||||
|
||||
const OrthoCamera = memo(() => {
|
||||
const { gl, scene, camera } = useThree();
|
||||
const virtualScene = useMemo(() => new Scene(), []);
|
||||
const virtualCam = useRef();
|
||||
const orthoCameraPosY = useRecoilValue(orthoCamPosYAtom);
|
||||
const orthoCameraRotY = useRecoilValue(orthoCamRotYAtom);
|
||||
const { gl, scene, camera } = useThree();
|
||||
const virtualScene = useMemo(() => new Scene(), []);
|
||||
const virtualCam = useRef();
|
||||
const orthoCameraPosY = useRecoilValue(orthoCamPosYAtom);
|
||||
const orthoCameraRotY = useRecoilValue(orthoCamRotYAtom);
|
||||
|
||||
const orbVisible = useRecoilValue(orbVisibilityAtom);
|
||||
const orbVisible = useRecoilValue(orbVisibilityAtom);
|
||||
|
||||
const hudVisible = useRecoilValue(hudVisibilityAtom);
|
||||
const hudVisible = useRecoilValue(hudVisibilityAtom);
|
||||
|
||||
const orthoCameraState = useSpring({
|
||||
orthoCameraPosY: orthoCameraPosY,
|
||||
orthoCameraRotY: orthoCameraRotY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
const orthoCameraState = useSpring({
|
||||
orthoCameraPosY: orthoCameraPosY,
|
||||
orthoCameraRotY: orthoCameraRotY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
|
||||
useFrame(() => {
|
||||
gl.autoClear = false;
|
||||
gl.clear();
|
||||
gl.render(scene, camera);
|
||||
gl.clearDepth();
|
||||
gl.render(virtualScene, virtualCam.current!);
|
||||
}, 1);
|
||||
useFrame(() => {
|
||||
gl.autoClear = false;
|
||||
gl.clear();
|
||||
gl.render(scene, camera);
|
||||
gl.clearDepth();
|
||||
gl.render(virtualScene, virtualCam.current!);
|
||||
}, 1);
|
||||
|
||||
//-0.6
|
||||
return (
|
||||
<a.group rotation={[0, 0, 0]} rotation-y={orthoCameraState.orthoCameraRotY}>
|
||||
<a.orthographicCamera
|
||||
ref={virtualCam}
|
||||
position={[0, 0, 10]}
|
||||
rotation={[0, 0, 0]}
|
||||
position-y={orthoCameraState.orthoCameraPosY}
|
||||
>
|
||||
<HUDElement key={1} hudVisibility={hudVisible} />
|
||||
<Orb orbVisibility={orbVisible} />
|
||||
</a.orthographicCamera>
|
||||
</a.group>
|
||||
);
|
||||
//-0.6
|
||||
return (
|
||||
<a.group rotation={[0, 0, 0]} rotation-y={orthoCameraState.orthoCameraRotY}>
|
||||
<a.orthographicCamera
|
||||
ref={virtualCam}
|
||||
position={[0, 0, 10]}
|
||||
rotation={[0, 0, 0]}
|
||||
position-y={orthoCameraState.orthoCameraPosY}
|
||||
>
|
||||
<HUDElement key={1} hudVisibility={hudVisible} />
|
||||
<Orb orbVisibility={orbVisible} />
|
||||
</a.orthographicCamera>
|
||||
</a.group>
|
||||
);
|
||||
});
|
||||
|
||||
export default OrthoCamera;
|
||||
|
|
|
@ -1,25 +1,34 @@
|
|||
import React, { memo, useRef } from "react";
|
||||
import React, { memo, useMemo, useRef } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { GLTF } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
import siteATex from "../static/sprites/site_a.png";
|
||||
import siteBTex from "../static/sprites/site_b.png";
|
||||
|
||||
type PurpleRingProps = {
|
||||
purpleRingPosY: number;
|
||||
purpleRingPosY: number;
|
||||
};
|
||||
|
||||
const PurpleRing = memo((props: PurpleRingProps) => {
|
||||
const siteA = useLoader(THREE.TextureLoader, siteATex);
|
||||
const siteB = useLoader(THREE.TextureLoader, siteBTex);
|
||||
const siteA = useLoader(THREE.TextureLoader, siteATex);
|
||||
const siteB = useLoader(THREE.TextureLoader, siteBTex);
|
||||
|
||||
const purpleRingRef = useRef<THREE.Object3D>();
|
||||
const purpleRingRef = useRef<THREE.Object3D>();
|
||||
|
||||
const uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]);
|
||||
// const uniforms = useMemo(
|
||||
// () => ({
|
||||
// siteA: { type: "t", value: siteA },
|
||||
// siteB: { type: "t", value: siteB },
|
||||
// }),
|
||||
// [siteA, siteB]
|
||||
// );
|
||||
|
||||
uniforms.siteA = { type: "t", value: siteA };
|
||||
uniforms.siteB = { type: "t", value: siteB };
|
||||
const uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["lights"]]);
|
||||
|
||||
const vertexShader = `
|
||||
uniforms.siteA = { type: "t", value: siteA };
|
||||
uniforms.siteB = { type: "t", value: siteB };
|
||||
|
||||
const vertexShader = `
|
||||
varying vec2 vUv;
|
||||
|
||||
varying vec3 vPos;
|
||||
|
@ -35,7 +44,7 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
}
|
||||
`;
|
||||
|
||||
const fragmentShader = `
|
||||
const fragmentShader = `
|
||||
varying vec2 vUv;
|
||||
uniform sampler2D siteA;
|
||||
uniform sampler2D siteB;
|
||||
|
@ -99,7 +108,7 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
addedLights.rgb += clamp(dot(-lightDirection,
|
||||
vNormal), 0.0, 1.0)
|
||||
* pointLights[l].color
|
||||
* 80.0;
|
||||
* 50.0;
|
||||
}
|
||||
|
||||
// number of segments
|
||||
|
@ -168,33 +177,33 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
}
|
||||
`;
|
||||
|
||||
useFrame(() => {
|
||||
purpleRingRef.current!.rotation.y += 0.005;
|
||||
});
|
||||
useFrame(() => {
|
||||
purpleRingRef.current!.rotation.y += 0.005;
|
||||
});
|
||||
|
||||
return (
|
||||
<mesh
|
||||
position={[0, props.purpleRingPosY, 0]}
|
||||
rotation={[0, 0.5, 0]}
|
||||
renderOrder={1}
|
||||
scale={[95, 95, 95]}
|
||||
ref={purpleRingRef}
|
||||
>
|
||||
<cylinderBufferGeometry
|
||||
args={[0.0019, 0.0019, 0.00015, 64, 64, true]}
|
||||
attach="geometry"
|
||||
/>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
side={THREE.DoubleSide}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
transparent={true}
|
||||
uniforms={uniforms}
|
||||
lights={true}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
return (
|
||||
<mesh
|
||||
position={[0, props.purpleRingPosY, 0]}
|
||||
rotation={[0, 0.5, 0]}
|
||||
renderOrder={1}
|
||||
scale={[25, 25, 25]}
|
||||
ref={purpleRingRef}
|
||||
>
|
||||
<cylinderBufferGeometry
|
||||
args={[0.05, 0.05, 0.0035, 64, 64, true]}
|
||||
attach="geometry"
|
||||
/>
|
||||
<shaderMaterial
|
||||
attach="material"
|
||||
side={THREE.DoubleSide}
|
||||
vertexShader={vertexShader}
|
||||
fragmentShader={fragmentShader}
|
||||
transparent={true}
|
||||
uniforms={uniforms}
|
||||
lights={true}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
});
|
||||
|
||||
export default PurpleRing;
|
||||
|
|
89
src/components/Site.tsx
Normal file
89
src/components/Site.tsx
Normal file
|
@ -0,0 +1,89 @@
|
|||
import React, { memo, Suspense } from "react";
|
||||
import site_a from "../resources/site_a.json";
|
||||
import blue_orb_positions from "../resources/blue_orb_positions.json";
|
||||
import BlueOrb from "./BlueOrb/BlueOrb";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { currentBlueOrbAtom } from "./BlueOrb/CurrentBlueOrbAtom";
|
||||
import Level from "./Level";
|
||||
import level_y_values from "../resources/level_y_values.json";
|
||||
|
||||
type ImageTableIndices = {
|
||||
1: string;
|
||||
2: string;
|
||||
3: string;
|
||||
};
|
||||
|
||||
type ProtocolLines = {
|
||||
1: string;
|
||||
2: string;
|
||||
3: string;
|
||||
4: string;
|
||||
};
|
||||
|
||||
type Words = {
|
||||
1: string;
|
||||
2: string;
|
||||
3: string;
|
||||
};
|
||||
|
||||
type BlueOrbData = {
|
||||
"SLPS_016_0x offset": string;
|
||||
image_table_indices: ImageTableIndices;
|
||||
is_hidden: string;
|
||||
media_file: string;
|
||||
node_name: string;
|
||||
protocol_lines: ProtocolLines;
|
||||
site: string;
|
||||
type: string;
|
||||
unlocked_by: string;
|
||||
upgrade_requirement: string;
|
||||
words: Words;
|
||||
};
|
||||
|
||||
type BlueOrbPositionData = {
|
||||
position: number[];
|
||||
rotation: number[];
|
||||
};
|
||||
|
||||
type BlueOrbPositions = {
|
||||
[orbPos: string]: BlueOrbPositionData;
|
||||
};
|
||||
|
||||
const Site = memo(() => {
|
||||
const currentBlueOrb = useRecoilValue(currentBlueOrbAtom);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Suspense fallback={<>loading...</>}>
|
||||
{/* distance between LEVELS is 1.5 */}
|
||||
{Object.values(level_y_values).map((yVal) => {
|
||||
return <Level levelPosY={yVal} key={yVal} />;
|
||||
})}
|
||||
|
||||
{Object.entries(site_a).map((blueOrb: [string, BlueOrbData]) => {
|
||||
if (blueOrb[1]["unlocked_by"] === "-1")
|
||||
return (
|
||||
<BlueOrb
|
||||
sprite={blueOrb[1]["node_name"]}
|
||||
position={
|
||||
(blue_orb_positions as BlueOrbPositions)[
|
||||
blueOrb[0].substr(2)
|
||||
]["position"]
|
||||
}
|
||||
rotation={
|
||||
(blue_orb_positions as BlueOrbPositions)[
|
||||
blueOrb[0].substr(2)
|
||||
]["rotation"]
|
||||
}
|
||||
key={blueOrb[1]["node_name"]}
|
||||
active={blueOrb[0] === currentBlueOrb}
|
||||
level={blueOrb[0].substr(0, 2)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export default Site;
|
|
@ -1,106 +0,0 @@
|
|||
import React, {
|
||||
memo,
|
||||
Suspense,
|
||||
useEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import site_a from "../../resources/site_a.json";
|
||||
import blue_orb_positions from "../../resources/blue_orb_positions.json";
|
||||
import BlueOrb from "../BlueOrb/BlueOrb";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { currentBlueOrbAtom } from "../BlueOrb/CurrentBlueOrbAtom";
|
||||
import Level from "../Level";
|
||||
import level_y_values from "../../resources/level_y_values.json";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
|
||||
import columns from "../../resources/columns.json";
|
||||
|
||||
type ImageTableIndices = {
|
||||
1: string;
|
||||
2: string;
|
||||
3: string;
|
||||
};
|
||||
|
||||
type ProtocolLines = {
|
||||
1: string;
|
||||
2: string;
|
||||
3: string;
|
||||
4: string;
|
||||
};
|
||||
|
||||
type Words = {
|
||||
1: string;
|
||||
2: string;
|
||||
3: string;
|
||||
};
|
||||
|
||||
export type BlueOrbData = {
|
||||
"SLPS_016_0x offset": string;
|
||||
image_table_indices: ImageTableIndices;
|
||||
is_hidden: string;
|
||||
media_file: string;
|
||||
node_name: string;
|
||||
protocol_lines: ProtocolLines;
|
||||
site: string;
|
||||
type: string;
|
||||
unlocked_by: string;
|
||||
upgrade_requirement: string;
|
||||
words: Words;
|
||||
};
|
||||
|
||||
type BlueOrbPositionData = {
|
||||
position: number[];
|
||||
rotation: number[];
|
||||
};
|
||||
|
||||
type BlueOrbPositions = {
|
||||
[orbPos: string]: BlueOrbPositionData;
|
||||
};
|
||||
|
||||
const Site = memo(() => {
|
||||
const currentBlueOrb = useRecoilValue(currentBlueOrbAtom);
|
||||
|
||||
useFrame(() => {
|
||||
// grpRef.current!.rotation.y += 0.01
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<Suspense fallback={<>loading...</>}>
|
||||
{/* distance between LEVELS is 1.5 */}
|
||||
{Object.values(level_y_values).map((yVal) => {
|
||||
return <Level levelPosY={yVal} key={yVal} />;
|
||||
})}
|
||||
|
||||
<a.group >
|
||||
{Object.entries(site_a).map((blueOrb: [string, BlueOrbData]) => {
|
||||
if (blueOrb[1]["unlocked_by"] === "-1")
|
||||
return (
|
||||
<BlueOrb
|
||||
sprite={blueOrb[1]["node_name"]}
|
||||
position={
|
||||
(blue_orb_positions as BlueOrbPositions)[
|
||||
blueOrb[0].substr(2)
|
||||
]["position"]
|
||||
}
|
||||
rotation={
|
||||
(blue_orb_positions as BlueOrbPositions)[
|
||||
blueOrb[0].substr(2)
|
||||
]["rotation"]
|
||||
}
|
||||
key={blueOrb[1]["node_name"]}
|
||||
active={blueOrb[0] === currentBlueOrb}
|
||||
level={blueOrb[0].substr(0, 2)}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</a.group>
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
export default Site;
|
|
@ -1,2 +0,0 @@
|
|||
import { atom } from "recoil";
|
||||
|
|
@ -1,85 +1,51 @@
|
|||
{
|
||||
"05": {
|
||||
"position": [0.06, -0.045, 0.185],
|
||||
"rotation": [0, 0.24, 0]
|
||||
"position": [0.4, -0.25, 1.3],
|
||||
"rotation": [0, 0.2, 0]
|
||||
},
|
||||
"13": {
|
||||
"position": [0.06, -0.005, 0.185],
|
||||
"rotation": [0, 0, 0]
|
||||
},
|
||||
"21": {
|
||||
"position": [0.06, 0.045, 0.182],
|
||||
"rotation": [0, 0, 0]
|
||||
},
|
||||
|
||||
"14": {
|
||||
"position": [-0.07, 0, 0.186],
|
||||
"rotation": [0, -0.24, 0]
|
||||
"position": [-0.35, 0, 1.3],
|
||||
"rotation": [0, -0.15, 0]
|
||||
},
|
||||
"22": {
|
||||
"position": [-0.07, 0.05, 0.186],
|
||||
"rotation": [0, -0.24, 0]
|
||||
"position": [-0.35, 0.3, 1.3],
|
||||
"rotation": [0, -0.15, 0]
|
||||
},
|
||||
"06": {
|
||||
"position": [-0.07, -0.05, 0.186],
|
||||
"rotation": [0, -0.24, 0]
|
||||
"position": [-0.35, -0.25, 1.3],
|
||||
"rotation": [0, -0.25, 0]
|
||||
},
|
||||
"13": {
|
||||
"position": [0.4, 0, 1.3],
|
||||
"rotation": [0, 0.27, 0]
|
||||
},
|
||||
|
||||
"15": {
|
||||
"position": [-0.17, 0, 0.09],
|
||||
"rotation": [0, -1, 0]
|
||||
"position": [-1, 0, 0.95],
|
||||
"rotation": [0, -0.9, 0]
|
||||
},
|
||||
"23": {
|
||||
"position": [-0.17, 0.05, 0.09],
|
||||
"rotation": [0, -1, 0]
|
||||
},
|
||||
"07": {
|
||||
"position": [-0.17, -0.05, 0.09],
|
||||
"rotation": [0, -1, 0]
|
||||
},
|
||||
|
||||
"08": {
|
||||
"position": [-0.19, 0, -0.03],
|
||||
"rotation": [0, -1.8, 0]
|
||||
},
|
||||
"16": {
|
||||
"position": [-0.19, 0.05, -0.03],
|
||||
"rotation": [0, -1.8, 0]
|
||||
"position": [-1.3, 0, 0.3],
|
||||
"rotation": [0, -1.4, 0]
|
||||
},
|
||||
"00": {
|
||||
"position": [-0.19, -0.05, -0.03],
|
||||
"rotation": [0, -1.8, 0]
|
||||
"position": [-1.3, -0.25, 0.3],
|
||||
"rotation": [0, -1.4, 0]
|
||||
},
|
||||
|
||||
"10": {
|
||||
"position": [-0.85, 0, -1.05],
|
||||
"rotation": [0, -2.45, 0]
|
||||
},
|
||||
"18": {
|
||||
"position": [-0.85, 0.3, -1.05],
|
||||
"rotation": [0, -2.45, 0]
|
||||
"16": {
|
||||
"position": [-1.3, 0.3, 0.3],
|
||||
"rotation": [0, -1.4, 0]
|
||||
},
|
||||
"02": {
|
||||
"position": [-0.85, -0.25, -1.05],
|
||||
"rotation": [0, -2.45, 0]
|
||||
},
|
||||
|
||||
"17": {
|
||||
"position": [-1.25, 0.3, -0.5],
|
||||
"rotation": [0, -1.85, 0]
|
||||
},
|
||||
"09": {
|
||||
"position": [-1.25, 0, -0.5],
|
||||
"rotation": [0, -1.85, 0]
|
||||
},
|
||||
"01": {
|
||||
"position": [-1.25, -0.25, -0.5],
|
||||
"rotation": [0, -1.85, 0]
|
||||
},
|
||||
|
||||
"20": {
|
||||
"position": [-1.25, 0.05, -0.8],
|
||||
"rotation": [0, -1.85, 0]
|
||||
"position": [1, 0.3, 0.9],
|
||||
"rotation": [0, 0.69, 0]
|
||||
},
|
||||
"12": {
|
||||
"position": [1, 0, 0.9],
|
||||
|
@ -89,7 +55,34 @@
|
|||
"position": [1, -0.25, 0.9],
|
||||
"rotation": [0, 0.69, 0]
|
||||
},
|
||||
|
||||
"21": {
|
||||
"position": [0.4, 0.3, 1.3],
|
||||
"rotation": [0, 0.27, 0]
|
||||
},
|
||||
"23": {
|
||||
"position": [-1, 0.3, 0.95],
|
||||
"rotation": [0, -0.9, 0]
|
||||
},
|
||||
"07": {
|
||||
"position": [-1, -0.25, 0.95],
|
||||
"rotation": [0, -0.9, 0]
|
||||
},
|
||||
"09": {
|
||||
"position": [-1.25, 0, -0.5],
|
||||
"rotation": [0, -1.85, 0]
|
||||
},
|
||||
"01": {
|
||||
"position": [-1.25, -0.25, -0.5],
|
||||
"rotation": [0, -1.85, 0]
|
||||
},
|
||||
"18": {
|
||||
"position": [-0.85, 0.3, -1.05],
|
||||
"rotation": [0, -2.45, 0]
|
||||
},
|
||||
"02": {
|
||||
"position": [-0.85, -0.25, -1.05],
|
||||
"rotation": [0, -2.45, 0]
|
||||
},
|
||||
"03": {
|
||||
"position": [-0.15, -0.25, -1.3],
|
||||
"rotation": [0, -2.45, 0]
|
||||
|
@ -102,7 +95,6 @@
|
|||
"position": [-0.15, 0.3, -1.3],
|
||||
"rotation": [0, -2.45, 0]
|
||||
},
|
||||
|
||||
"?": {
|
||||
"position": [-0.15, 0.3, -1.3],
|
||||
"rotation": [0, -2.45, 0]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"01": -0.75,
|
||||
"02": -0.5,
|
||||
"03": -0.25,
|
||||
"01": -4.5,
|
||||
"02": -3,
|
||||
"03": -1.5,
|
||||
"04": 0,
|
||||
"05": 0.25,
|
||||
"06": 0.5,
|
||||
"05": 1.5,
|
||||
"06": 3,
|
||||
"07": 4.5,
|
||||
"08": 6,
|
||||
"09": 7.5,
|
||||
|
@ -21,4 +21,4 @@
|
|||
"20": 24,
|
||||
"21": 25.5,
|
||||
"22": 27
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue