mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
a bunch of shit
This commit is contained in:
parent
c71a8eae5b
commit
5ea6ef9a98
12 changed files with 975 additions and 121 deletions
|
@ -9,7 +9,11 @@ import boringHud from "../../static/sprites/long_hud_boring.png";
|
|||
import boringHudMirrored from "../../static/sprites/long_hud_boring_mirrored.png";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { bigHudTextAtom, hudActiveAtom } from "./HUDElementAtom";
|
||||
import {
|
||||
bigHudTextAtom,
|
||||
hudActiveAtom,
|
||||
mediumHudTextAtom,
|
||||
} from "./HUDElementAtom";
|
||||
import { currentHUDAtom } from "./HUDElementAtom";
|
||||
import HUDText from "./HUDText";
|
||||
|
||||
|
@ -24,11 +28,17 @@ type HudShapeData = {
|
|||
initial_position: number[];
|
||||
};
|
||||
|
||||
type MediumTextData = {
|
||||
position: number[];
|
||||
initial_position: number[];
|
||||
};
|
||||
|
||||
export type BlueOrbHudData = {
|
||||
long: HudShapeData;
|
||||
boring: HudShapeData;
|
||||
big: HudShapeData;
|
||||
big_text: number[];
|
||||
medium_text: MediumTextData;
|
||||
};
|
||||
|
||||
export type BlueOrbHuds = {
|
||||
|
@ -40,9 +50,10 @@ type LevelYValues = {
|
|||
};
|
||||
|
||||
const HUDElement = memo((props: HUDElementProps) => {
|
||||
const currentBlueOrbHUD = useRecoilValue(currentHUDAtom);
|
||||
const currentHud = useRecoilValue(currentHUDAtom);
|
||||
|
||||
const currentBigHudText = useRecoilValue(bigHudTextAtom);
|
||||
const currentMediumHudText = useRecoilValue(mediumHudTextAtom);
|
||||
|
||||
const hudActive = useRecoilValue(hudActiveAtom);
|
||||
|
||||
|
@ -63,25 +74,22 @@ const HUDElement = memo((props: HUDElementProps) => {
|
|||
|
||||
const bigHUDPosX = bigHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["big"]["initial_position"][0],
|
||||
currentBlueOrbHUD["big"]["position"][0],
|
||||
]
|
||||
[currentHud["big"]["initial_position"][0], currentHud["big"]["position"][0]]
|
||||
);
|
||||
|
||||
const boringHUDPosX = boringHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["boring"]["initial_position"][0],
|
||||
currentBlueOrbHUD["boring"]["position"][0],
|
||||
currentHud["boring"]["initial_position"][0],
|
||||
currentHud["boring"]["position"][0],
|
||||
]
|
||||
);
|
||||
|
||||
const longHUDPosX = longHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentBlueOrbHUD["long"]["initial_position"][0],
|
||||
currentBlueOrbHUD["long"]["position"][0],
|
||||
currentHud["long"]["initial_position"][0],
|
||||
currentHud["long"]["position"][0],
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -114,60 +122,64 @@ const HUDElement = memo((props: HUDElementProps) => {
|
|||
|
||||
const longHudTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["long"]["type"], "long")!
|
||||
spriteTypeToSprite(currentHud["long"]["type"], "long")!
|
||||
);
|
||||
|
||||
const longHudBoringTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["boring"]["type"], "boring")!
|
||||
spriteTypeToSprite(currentHud["boring"]["type"], "boring")!
|
||||
);
|
||||
|
||||
const bigHudTexture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
spriteTypeToSprite(currentBlueOrbHUD["big"]["type"], "big")!
|
||||
spriteTypeToSprite(currentHud["big"]["type"], "big")!
|
||||
);
|
||||
|
||||
return (
|
||||
<group visible={props.hudVisibility} renderOrder={1}>
|
||||
<group visible={props.hudVisibility}>
|
||||
<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]}
|
||||
position-y={currentHud["long"]["position"][1]}
|
||||
position-z={currentHud["long"]["position"][2]}
|
||||
scale={currentHud["long"]["scale"] as [number, number, number]}
|
||||
renderOrder={2}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={longHudTexture}
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</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]
|
||||
}
|
||||
position-y={currentHud!["boring"]["position"][1]}
|
||||
position-z={currentHud!["boring"]["position"][2]}
|
||||
scale={currentHud!["boring"]["scale"] as [number, number, number]}
|
||||
renderOrder={2}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={longHudBoringTexture}
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</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]}
|
||||
position-y={currentHud!["big"]["position"][1]}
|
||||
position-z={currentHud!["big"]["position"][2]}
|
||||
scale={currentHud!["big"]["scale"] as [number, number, number]}
|
||||
renderOrder={2}
|
||||
>
|
||||
<spriteMaterial
|
||||
attach="material"
|
||||
map={bigHudTexture}
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</a.sprite>
|
||||
<HUDText text={currentBigHudText} />
|
||||
<HUDText bigText={currentBigHudText} mediumText={currentMediumHudText} />
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
|
|
@ -30,4 +30,19 @@ export const bigLetterPosXAtom = atom({
|
|||
export const bigHudTextAtom = atom({
|
||||
key: "bigHudTextAtom",
|
||||
default: "Tda031",
|
||||
})
|
||||
});
|
||||
|
||||
export const mediumHudTextAtom = atom({
|
||||
key: "mediumHudTextAtom",
|
||||
default: "TOUKO's DIARY",
|
||||
});
|
||||
|
||||
export const mediumHudTextPosYAtom = atom({
|
||||
key: "mediumHudTextPosYAtom",
|
||||
default: 0.16,
|
||||
});
|
||||
|
||||
export const mediumHudTextPosXAtom = atom({
|
||||
key: "mediumHudTextPosXAtom",
|
||||
default: 0.18,
|
||||
});
|
||||
|
|
|
@ -1,43 +1,110 @@
|
|||
import React from "react";
|
||||
import Letter from "../TextRenderer/TextRenderer";
|
||||
import { BigLetter, MediumLetter } from "../TextRenderer/TextRenderer";
|
||||
import { a, useSpring, useTrail } from "@react-spring/three";
|
||||
import { useRecoilValue } from "recoil";
|
||||
import { bigLetterPosXAtom, bigLetterPosYAtom } from "./HUDElementAtom";
|
||||
import {
|
||||
bigLetterPosXAtom,
|
||||
bigLetterPosYAtom, currentHUDAtom,
|
||||
hudActiveAtom,
|
||||
} from "./HUDElementAtom";
|
||||
import { isSiteYChangingAtom } from "../Site/SiteAtom";
|
||||
|
||||
type HUDTextProps = {
|
||||
text: string;
|
||||
bigText: string;
|
||||
mediumText: string;
|
||||
};
|
||||
|
||||
const HUDText = (props: HUDTextProps) => {
|
||||
const bigLetterPosX = useRecoilValue(bigLetterPosXAtom);
|
||||
const bigLetterPosY = useRecoilValue(bigLetterPosYAtom);
|
||||
|
||||
const textArr = props.text.split("");
|
||||
const currentHud = useRecoilValue(currentHUDAtom);
|
||||
|
||||
const letterTrail = useTrail(textArr.length, {
|
||||
const isSiteChangingY = useRecoilValue(isSiteYChangingAtom);
|
||||
|
||||
const hudActive = useRecoilValue(hudActiveAtom);
|
||||
|
||||
const { mediumTextHUDPositionX } = useSpring({
|
||||
mediumTextHUDPositionX: hudActive,
|
||||
config: { duration: 500 },
|
||||
});
|
||||
|
||||
const mediumHudPosX = mediumTextHUDPositionX.to(
|
||||
[0, 1],
|
||||
[
|
||||
currentHud["medium_text"]["initial_position"][0],
|
||||
currentHud["medium_text"]["position"][0],
|
||||
]
|
||||
);
|
||||
|
||||
const bigTextArr = props.bigText.split("");
|
||||
const mediumTextArr = props.mediumText.split("");
|
||||
|
||||
// this one is used for letter animations
|
||||
const letterTrail = useTrail(bigTextArr.length, {
|
||||
bigLetterPosX: bigLetterPosX,
|
||||
bigLetterPosY: bigLetterPosY,
|
||||
config: { duration: 400 },
|
||||
config: { duration: 280 },
|
||||
});
|
||||
|
||||
// this one is used when the site moves up/down and
|
||||
// the text has to stay stationary
|
||||
const letterStaticState = useSpring({
|
||||
bigLetterPosX: bigLetterPosX,
|
||||
bigLetterPosY: bigLetterPosY,
|
||||
config: { duration: 1200 },
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{letterTrail.map(({ bigLetterPosX, bigLetterPosY }, idx) => (
|
||||
<a.group
|
||||
key={idx}
|
||||
position-x={bigLetterPosX}
|
||||
position-y={bigLetterPosY}
|
||||
position-z={-8.7}
|
||||
scale={[0.04, 0.06, 0.04]}
|
||||
>
|
||||
<Letter
|
||||
{isSiteChangingY
|
||||
? bigTextArr.map((letter, idx) => (
|
||||
<a.group
|
||||
key={idx}
|
||||
position-x={letterStaticState.bigLetterPosX}
|
||||
position-y={letterStaticState.bigLetterPosY}
|
||||
position-z={-8.7}
|
||||
scale={[0.04, 0.06, 0.04]}
|
||||
>
|
||||
<BigLetter
|
||||
color={"yellow"}
|
||||
letter={bigTextArr[idx]}
|
||||
kerningOffset={idx}
|
||||
key={idx}
|
||||
/>
|
||||
</a.group>
|
||||
))
|
||||
: letterTrail.map(({ bigLetterPosX, bigLetterPosY }, idx) => (
|
||||
<a.group
|
||||
key={idx}
|
||||
position-x={bigLetterPosX}
|
||||
position-y={bigLetterPosY}
|
||||
position-z={-8.7}
|
||||
scale={[0.04, 0.06, 0.04]}
|
||||
>
|
||||
<BigLetter
|
||||
color={"yellow"}
|
||||
letter={bigTextArr[idx]}
|
||||
kerningOffset={idx}
|
||||
key={idx}
|
||||
/>
|
||||
</a.group>
|
||||
))}
|
||||
<a.group
|
||||
position-x={mediumHudPosX}
|
||||
position-y={currentHud["medium_text"]["position"][1]}
|
||||
position-z={-8.7}
|
||||
scale={[0.02, 0.035, 0.02]}
|
||||
>
|
||||
{mediumTextArr.map((letter, idx) => (
|
||||
<MediumLetter
|
||||
color={"yellow"}
|
||||
letter={textArr[idx]}
|
||||
letter={letter}
|
||||
kerningOffset={idx}
|
||||
key={idx}
|
||||
/>
|
||||
</a.group>
|
||||
))}
|
||||
))}
|
||||
</a.group>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@ import {
|
|||
bigLetterPosYAtom,
|
||||
currentHUDAtom,
|
||||
hudActiveAtom,
|
||||
mediumHudTextAtom,
|
||||
} from "./HUD/HUDElementAtom";
|
||||
import { currentBlueOrbAtom } from "./BlueOrb/CurrentBlueOrbAtom";
|
||||
import lain_animations from "../resources/lain_animations.json";
|
||||
|
@ -32,7 +33,11 @@ import {
|
|||
} from "./MiddleRing/MiddleRingAtom";
|
||||
import { bigLetterOffsetXCoeffAtom } from "./TextRenderer/TextRendererAtom";
|
||||
import { SiteData } from "./Site/Site";
|
||||
import { sitePosYAtom, siteRotYAtom } from "./Site/SiteAtom";
|
||||
import {
|
||||
isSiteYChangingAtom,
|
||||
sitePosYAtom,
|
||||
siteRotYAtom,
|
||||
} from "./Site/SiteAtom";
|
||||
|
||||
type KeyCodeAssociations = {
|
||||
[keyCode: number]: string;
|
||||
|
@ -96,12 +101,15 @@ const InputHandler = () => {
|
|||
|
||||
const setSiteRotY = useSetRecoilState(siteRotYAtom);
|
||||
const setSitePosY = useSetRecoilState(sitePosYAtom);
|
||||
const setIsSiteYChanging = useSetRecoilState(isSiteYChangingAtom);
|
||||
|
||||
const setBigLetterOffSetXCoeff = useSetRecoilState(bigLetterOffsetXCoeffAtom);
|
||||
const setBigLetterPosY = useSetRecoilState(bigLetterPosYAtom);
|
||||
const setBigLetterPosX = useSetRecoilState(bigLetterPosXAtom);
|
||||
const setBigHudText = useSetRecoilState(bigHudTextAtom);
|
||||
|
||||
const setMediumHudText = useSetRecoilState(mediumHudTextAtom);
|
||||
|
||||
// hud toggler (animating hud from left to right)
|
||||
const toggleHud = useCallback(() => {
|
||||
setHudActive((prev: number) => Number(!prev));
|
||||
|
@ -109,30 +117,69 @@ const InputHandler = () => {
|
|||
|
||||
// ===================================== BIG TEXT ANIMATIONS ================================================
|
||||
|
||||
const animateBigText = useCallback(
|
||||
(move: string) => {
|
||||
const animateBigTextWithMove = useCallback(
|
||||
(targetBlueOrbId: string, moveDirection: string) => {
|
||||
const targetHudId = targetBlueOrbId.substr(2);
|
||||
|
||||
setTimeout(() => {
|
||||
switch (moveDirection) {
|
||||
case "up":
|
||||
setBigLetterPosY((prev: number) => prev - 1.5);
|
||||
|
||||
break;
|
||||
case "down":
|
||||
setBigLetterPosY((prev: number) => prev + 1.5);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}, 1300);
|
||||
|
||||
setTimeout(() => {
|
||||
// make current hud big text shrink
|
||||
setBigLetterOffSetXCoeff(-1);
|
||||
}, 2500);
|
||||
|
||||
setTimeout(() => {
|
||||
setBigLetterPosX(
|
||||
(blue_orb_huds as BlueOrbHuds)[targetHudId]["big_text"][0]
|
||||
);
|
||||
setBigLetterPosY(
|
||||
(blue_orb_huds as BlueOrbHuds)[targetHudId]["big_text"][1]
|
||||
);
|
||||
setBigHudText((site_a as SiteData)[targetBlueOrbId]["node_name"]);
|
||||
}, 3000);
|
||||
|
||||
setTimeout(() => {
|
||||
setBigLetterOffSetXCoeff(0);
|
||||
}, 3900);
|
||||
},
|
||||
[
|
||||
setBigHudText,
|
||||
setBigLetterOffSetXCoeff,
|
||||
setBigLetterPosX,
|
||||
setBigLetterPosY,
|
||||
]
|
||||
);
|
||||
|
||||
const animateBigTextStatic = useCallback(
|
||||
(targetBlueOrbId: string, moveDirection: string) => {
|
||||
const targetHudId = targetBlueOrbId.substr(2);
|
||||
// make current hud big text shrink
|
||||
setBigLetterOffSetXCoeff(-1);
|
||||
|
||||
setTimeout(() => {
|
||||
// animate it to new pos x/y
|
||||
setBigLetterPosX(
|
||||
(blue_orb_huds as BlueOrbHuds)[move.substr(2)]["big_text"][0]
|
||||
(blue_orb_huds as BlueOrbHuds)[targetHudId]["big_text"][0]
|
||||
);
|
||||
setBigLetterPosY(
|
||||
(blue_orb_huds as BlueOrbHuds)[move.substr(2)]["big_text"][1]
|
||||
(blue_orb_huds as BlueOrbHuds)[targetHudId]["big_text"][1]
|
||||
);
|
||||
}, 400);
|
||||
|
||||
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
|
||||
toggleHud();
|
||||
}, 500);
|
||||
|
||||
setTimeout(() => {
|
||||
setBigHudText((site_a as SiteData)[move]["node_name"]);
|
||||
setBigHudText((site_a as SiteData)[targetBlueOrbId]["node_name"]);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
|
@ -144,8 +191,6 @@ const InputHandler = () => {
|
|||
setBigLetterOffSetXCoeff,
|
||||
setBigLetterPosX,
|
||||
setBigLetterPosY,
|
||||
setCurrentHUDElement,
|
||||
toggleHud,
|
||||
]
|
||||
);
|
||||
|
||||
|
@ -169,6 +214,9 @@ const InputHandler = () => {
|
|||
);
|
||||
|
||||
const moveMiddleRingDown = useCallback(() => {
|
||||
// set the anim duration value to match that of the site's
|
||||
setMiddleRingAnimDuration(1200);
|
||||
|
||||
// make noise appear again
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.06);
|
||||
|
@ -179,11 +227,27 @@ const InputHandler = () => {
|
|||
setMiddleRingRotating(false);
|
||||
}, 700);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev + 1.5);
|
||||
}, 1300);
|
||||
|
||||
// set ring rotation on x axis to craete motion effect
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0.3);
|
||||
}, 1500);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingAnimDuration(600);
|
||||
}, 2900);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev - 1.7);
|
||||
}, 3000);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev + 0.2);
|
||||
}, 3150);
|
||||
|
||||
// rotate it again, set ring noise to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(-0.1);
|
||||
|
@ -205,7 +269,13 @@ const InputHandler = () => {
|
|||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.03);
|
||||
}, 11600);
|
||||
}, [setMiddleRingNoise, setMiddleRingRotX, setMiddleRingRotating]);
|
||||
}, [
|
||||
setMiddleRingAnimDuration,
|
||||
setMiddleRingNoise,
|
||||
setMiddleRingPosY,
|
||||
setMiddleRingRotX,
|
||||
setMiddleRingRotating,
|
||||
]);
|
||||
|
||||
const moveMiddleRingUp = useCallback(() => {
|
||||
// change noise to 0, make the ring bend downwards
|
||||
|
@ -222,6 +292,13 @@ const InputHandler = () => {
|
|||
// make the ring bend upwards
|
||||
setTimeout(() => {
|
||||
setMiddleRingWobbleStrength(-0.3);
|
||||
// the middle ring stays in place, therefore we animate it
|
||||
// in the same direction as the site, creating that illusion.
|
||||
|
||||
// set the anim duration value to match that of the site's
|
||||
setMiddleRingAnimDuration(1200);
|
||||
// animate it after
|
||||
setMiddleRingPosY((prev: number) => prev - 1.5);
|
||||
}, 1300);
|
||||
|
||||
// reset the ring bend, set the rotation to slightly curve
|
||||
|
@ -233,17 +310,29 @@ const InputHandler = () => {
|
|||
setMiddleRingRotating(true);
|
||||
}, 1500);
|
||||
|
||||
// reset anim duration back to default
|
||||
setTimeout(() => {
|
||||
setMiddleRingAnimDuration(600);
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev + 1.7);
|
||||
}, 2400);
|
||||
|
||||
// reset the rotation value to 0
|
||||
setTimeout(() => {
|
||||
setMiddleRingRotX(0);
|
||||
}, 2500);
|
||||
setMiddleRingPosY((prev: number) => prev - 0.2);
|
||||
}, 2650);
|
||||
|
||||
// enable noise again in about 8~ secs
|
||||
setTimeout(() => {
|
||||
setMiddleRingNoise(0.03);
|
||||
}, 7800);
|
||||
}, [
|
||||
setMiddleRingAnimDuration,
|
||||
setMiddleRingNoise,
|
||||
setMiddleRingPosY,
|
||||
setMiddleRingRotX,
|
||||
setMiddleRingRotating,
|
||||
setMiddleRingWobbleStrength,
|
||||
|
@ -275,28 +364,8 @@ const InputHandler = () => {
|
|||
|
||||
setTimeout(() => {
|
||||
setSitePosY((prev: number) => prev - 1.5);
|
||||
// the middle ring stays in place, therefore we animate it
|
||||
// in the same direction as the site, creating that illusion.
|
||||
|
||||
// set the anim duration value to match that of the site's
|
||||
setMiddleRingAnimDuration(1500);
|
||||
// animate it after
|
||||
setMiddleRingPosY((prev: number) => prev - 1.5);
|
||||
}, 1300);
|
||||
|
||||
// reset anim duration back to default
|
||||
setTimeout(() => {
|
||||
setMiddleRingAnimDuration(500);
|
||||
}, 2300);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev + 1.7);
|
||||
}, 2400);
|
||||
|
||||
setTimeout(() => {
|
||||
setMiddleRingPosY((prev: number) => prev - 0.2);
|
||||
}, 2400);
|
||||
|
||||
moveMiddleRingUp();
|
||||
break;
|
||||
case "right":
|
||||
|
@ -330,16 +399,14 @@ const InputHandler = () => {
|
|||
moveMiddleRingUp,
|
||||
moveMiddleRingDown,
|
||||
rotateMiddleRing,
|
||||
setMiddleRingAnimDuration,
|
||||
setMiddleRingPosY,
|
||||
setSitePosY,
|
||||
setSiteRotY,
|
||||
]
|
||||
);
|
||||
|
||||
const dispatchAction = useCallback(
|
||||
(move: string, key: string) => {
|
||||
switch (move[0]) {
|
||||
(targetBlueOrbId: string, moveDirection: string) => {
|
||||
switch (targetBlueOrbId[0]) {
|
||||
// do nothing / cant move
|
||||
case undefined:
|
||||
break;
|
||||
|
@ -348,38 +415,61 @@ const InputHandler = () => {
|
|||
// will be chosen.
|
||||
case "+":
|
||||
if (!spriteUpdateCooldown) {
|
||||
setIsSiteYChanging(true);
|
||||
// get rid of the +, since its useless after code execution is already here
|
||||
const filteredMove = move.substr(1);
|
||||
const filteredBlueOrbId = targetBlueOrbId.substr(1);
|
||||
const targetHudId = filteredBlueOrbId.substr(2);
|
||||
|
||||
toggleHud();
|
||||
|
||||
// disable glow on current sprite
|
||||
setCurrentBlueOrb("");
|
||||
|
||||
setSpriteUpdateCooldown(true);
|
||||
setAnimationState(key);
|
||||
|
||||
setAnimationState(moveDirection);
|
||||
|
||||
setTimeout(() => {
|
||||
toggleHud();
|
||||
// skip the "+"
|
||||
setCurrentBlueOrb(filteredMove);
|
||||
setCurrentHUDElement(
|
||||
(blue_orb_huds as BlueOrbHuds)[filteredMove.substr(2)]
|
||||
setCurrentBlueOrb(filteredBlueOrbId);
|
||||
setCurrentHUDElement((blue_orb_huds as BlueOrbHuds)[targetHudId]);
|
||||
setMediumHudText(
|
||||
(site_a as SiteData)[filteredBlueOrbId]["green_text"]
|
||||
);
|
||||
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
|
||||
}, (lain_animations as LainAnimations)[moveDirection]["duration"] + 200);
|
||||
|
||||
animateBigText(filteredMove);
|
||||
animateBigTextWithMove(filteredBlueOrbId, moveDirection);
|
||||
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
|
||||
setTimeout(() => {
|
||||
setIsSiteYChanging(false);
|
||||
}, 3000);
|
||||
}
|
||||
break;
|
||||
// only change sprite focus
|
||||
default:
|
||||
if (!spriteUpdateCooldown) {
|
||||
setCurrentBlueOrb(move);
|
||||
const targetHudId = targetBlueOrbId.substr(2);
|
||||
|
||||
setCurrentBlueOrb(targetBlueOrbId);
|
||||
setSpriteUpdateCooldown(true);
|
||||
toggleHud();
|
||||
|
||||
animateBigText(move);
|
||||
setTimeout(() => {
|
||||
// change hud while its hidden
|
||||
setCurrentHUDElement((blue_orb_huds as BlueOrbHuds)[targetHudId]);
|
||||
setMediumHudText(
|
||||
(site_a as SiteData)[targetBlueOrbId]["green_text"]
|
||||
);
|
||||
// toggle it again to be shown in the new position
|
||||
toggleHud();
|
||||
}, 500);
|
||||
|
||||
animateBigTextStatic(targetBlueOrbId, "none");
|
||||
setTimeout(() => {
|
||||
setSpriteUpdateCooldown(false);
|
||||
}, 1000);
|
||||
|
@ -387,12 +477,14 @@ const InputHandler = () => {
|
|||
}
|
||||
},
|
||||
[
|
||||
setAnimationState,
|
||||
toggleHud,
|
||||
spriteUpdateCooldown,
|
||||
setCurrentHUDElement,
|
||||
setIsSiteYChanging,
|
||||
toggleHud,
|
||||
setCurrentBlueOrb,
|
||||
animateBigText,
|
||||
setAnimationState,
|
||||
animateBigTextWithMove,
|
||||
setCurrentHUDElement,
|
||||
animateBigTextStatic,
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -32,5 +32,5 @@ export const middleRingRotZAtom = atom({
|
|||
|
||||
export const middleRingAnimDurationAtom = atom({
|
||||
key: "middleRingAnimDurationAtom",
|
||||
default: 500,
|
||||
default: 600,
|
||||
});
|
||||
|
|
|
@ -8,7 +8,6 @@ import { orthoCamPosYAtom, orthoCamRotYAtom } from "./OrthoCameraAtom";
|
|||
import { useSpring, a } from "@react-spring/three";
|
||||
import { orbVisibilityAtom } from "../Orb/OrbAtom";
|
||||
import { hudVisibilityAtom } from "../HUD/HUDElementAtom";
|
||||
import TextRenderer from "../TextRenderer/TextRenderer";
|
||||
|
||||
const OrthoCamera = memo(() => {
|
||||
const { gl, scene, camera } = useThree();
|
||||
|
|
|
@ -40,6 +40,7 @@ type BlueOrbData = {
|
|||
unlocked_by: string;
|
||||
upgrade_requirement: string;
|
||||
words: Words;
|
||||
green_text: string;
|
||||
};
|
||||
|
||||
type BlueOrbPositionData = {
|
||||
|
|
|
@ -9,3 +9,8 @@ export const sitePosYAtom = atom({
|
|||
key: "sitePosYAtom",
|
||||
default: 0,
|
||||
});
|
||||
|
||||
export const isSiteYChangingAtom = atom({
|
||||
key: "isSiteYChangingAtom",
|
||||
default: false,
|
||||
});
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
import { useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import orangeFont from "../../static/sprites/orange_font_texture.png";
|
||||
import greenFont from "../../static/sprites/white_and_green_texture.png";
|
||||
import yellowFont from "../../static/sprites/yellow_font_texture.png";
|
||||
import orange_font_json from "../../resources/orange_font.json";
|
||||
import medium_font_json from "../../resources/medium_font.json";
|
||||
import { a, useSpring } from "@react-spring/three";
|
||||
import React from "react";
|
||||
import { useRecoilValue } from "recoil";
|
||||
|
@ -26,14 +28,14 @@ type LetterData = {
|
|||
[letter: string]: number[];
|
||||
};
|
||||
|
||||
type BigFontData = {
|
||||
type FontData = {
|
||||
kerning: number;
|
||||
baseline: number;
|
||||
height: number;
|
||||
glyphs: LetterData;
|
||||
};
|
||||
|
||||
const Letter = (props: LetterProps) => {
|
||||
export const BigLetter = (props: LetterProps) => {
|
||||
const bigLetterOffsetXCoeff = useRecoilValue(bigLetterOffsetXCoeffAtom);
|
||||
|
||||
const colorToTexture = (color: string) => {
|
||||
|
@ -63,7 +65,7 @@ const Letter = (props: LetterProps) => {
|
|||
return 1;
|
||||
} else if (lineTwo.includes(letter)) {
|
||||
return 2;
|
||||
} else if (lineThree.includes(letter)){
|
||||
} else if (lineThree.includes(letter)) {
|
||||
return 3;
|
||||
} else {
|
||||
return 4;
|
||||
|
@ -75,9 +77,9 @@ const Letter = (props: LetterProps) => {
|
|||
2: 0.765,
|
||||
3: 0.65,
|
||||
4: 0.47,
|
||||
};
|
||||
};
|
||||
|
||||
const letterData = (orange_font_json as BigFontData)["glyphs"][props.letter];
|
||||
const letterData = (orange_font_json as FontData)["glyphs"][props.letter];
|
||||
|
||||
if (!letterData) debugger;
|
||||
|
||||
|
@ -116,7 +118,7 @@ const Letter = (props: LetterProps) => {
|
|||
position-y={props.kerningOffset === 0 ? -0.03 : 0}
|
||||
scale={props.kerningOffset === 0 ? [1.7, 1, 1.7] : [1, 1, 1]}
|
||||
geometry={geometry}
|
||||
renderOrder={props.kerningOffset === 0 ? 3 : 2}
|
||||
renderOrder={props.kerningOffset === 0 ? 4 : 3}
|
||||
>
|
||||
<meshBasicMaterial
|
||||
map={colorTexture}
|
||||
|
@ -127,4 +129,83 @@ const Letter = (props: LetterProps) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default Letter;
|
||||
export const MediumLetter = (props: LetterProps) => {
|
||||
// for now we only use the green, ill add others as we go
|
||||
const colorToTexture = (color: string) => {
|
||||
return ({ orange: orangeFont, yellow: yellowFont } as ColorToTexture)[
|
||||
color
|
||||
];
|
||||
};
|
||||
|
||||
const colorTexture = useLoader(THREE.TextureLoader, greenFont);
|
||||
// i have yet to figure out a genrealizable way of
|
||||
// calculating the y offset, this shit will do for now
|
||||
// also, we dont have all the lines since i dont need them yet.
|
||||
// also, baseline offsets dont work properly since i dont need them yet either
|
||||
// should be trivial to calculate though, im just lazy
|
||||
const getLineNum = (letter: string) => {
|
||||
const lineOne = "ABCDEFGHIJKLMNOPQQRSTUVW";
|
||||
const lineTwo = "XYZ0123456779abcdefghij";
|
||||
const lineThree = "klmnopqrstuvwxyz,.*";
|
||||
|
||||
if (letter === " ") return 5;
|
||||
|
||||
if (lineOne.includes(letter)) {
|
||||
return 1;
|
||||
} else if (lineTwo.includes(letter)) {
|
||||
return 2;
|
||||
} else if (lineThree.includes(letter)) {
|
||||
return 3;
|
||||
} else {
|
||||
return 4;
|
||||
}
|
||||
};
|
||||
|
||||
// 5th one is just a space, this is my hacky way of doing it.
|
||||
const lineYOffsets: LineYOffsets = {
|
||||
1: 0.355,
|
||||
2: 0.297,
|
||||
3: 0.238,
|
||||
4: 0.18,
|
||||
5: 1
|
||||
};
|
||||
|
||||
const letterData = (medium_font_json as FontData)["glyphs"][props.letter];
|
||||
|
||||
if (!letterData) debugger;
|
||||
|
||||
const geometry = new THREE.PlaneBufferGeometry();
|
||||
|
||||
const uvAttribute = geometry.attributes.uv;
|
||||
|
||||
for (let i = 0; i < uvAttribute.count; i++) {
|
||||
let u = uvAttribute.getX(i);
|
||||
let v = uvAttribute.getY(i);
|
||||
|
||||
u = (u * letterData[2]) / 256 + letterData[0] / 256;
|
||||
|
||||
v =
|
||||
(v * letterData[3]) / 136 +
|
||||
letterData[4] / 136 +
|
||||
lineYOffsets[getLineNum(props.letter)] -
|
||||
letterData[4] / 136;
|
||||
|
||||
uvAttribute.setXY(i, u, v);
|
||||
}
|
||||
|
||||
return (
|
||||
<a.mesh
|
||||
position-x={props.kerningOffset * 1.6}
|
||||
scale={[1.7, 1, 1.7]}
|
||||
geometry={geometry}
|
||||
renderOrder={100}
|
||||
>
|
||||
<meshBasicMaterial
|
||||
map={colorTexture}
|
||||
attach="material"
|
||||
transparent={true}
|
||||
depthTest={false}
|
||||
/>
|
||||
</a.mesh>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -18,7 +18,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.36, 0.13, -8.6]
|
||||
},
|
||||
"big_text": [-0.35, 0.23, -8.7]
|
||||
"big_text": [-0.35, 0.23, -8.7],
|
||||
"medium_text": {
|
||||
"position": [0.18, 0.16, -8.7],
|
||||
"initial_position": [1.18, 0.16, -8.7]
|
||||
}
|
||||
},
|
||||
"14": {
|
||||
"long": {
|
||||
|
@ -39,7 +43,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.36, -0.12, -8.6]
|
||||
},
|
||||
"big_text": [-0.35, -0.05, -8.7]
|
||||
"big_text": [-0.35, -0.05, -8.7],
|
||||
"medium_text": {
|
||||
"position": [0.18, -0.13, -8.7],
|
||||
"initial_position": [1.18, -0.13, -8.7]
|
||||
}
|
||||
},
|
||||
"13": {
|
||||
"long": {
|
||||
|
@ -60,7 +68,11 @@
|
|||
"type": "mirrored",
|
||||
"initial_position": [-1.48, -0.12, -8.6]
|
||||
},
|
||||
"big_text": [0.45, -0.05, -8.7]
|
||||
"big_text": [0.45, -0.05, -8.7],
|
||||
"medium_text": {
|
||||
"position": [-0.65, -0.13, -8.7],
|
||||
"initial_position": [-1.18, -0.13, -8.7]
|
||||
}
|
||||
},
|
||||
"05": {
|
||||
"long": {
|
||||
|
@ -81,7 +93,11 @@
|
|||
"type": "mirrored",
|
||||
"initial_position": [-1.48, -0.12, -8.6]
|
||||
},
|
||||
"big_text": [0.45, -0.32, -8.7]
|
||||
"big_text": [0.45, -0.32, -8.7],
|
||||
"medium_text": {
|
||||
"position": [-0.55, -0.32, -8.7],
|
||||
"initial_position": [-1.18, -0.32, -8.7]
|
||||
}
|
||||
},
|
||||
"06": {
|
||||
"long": {
|
||||
|
@ -102,7 +118,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.48, -0.12, -8.6]
|
||||
},
|
||||
"big_text": [-0.33, -0.32, -8.7]
|
||||
"big_text": [-0.33, -0.32, -8.7],
|
||||
"medium_text": {
|
||||
"position": [0.12, -0.32, -8.7],
|
||||
"initial_position": [1.18, -0.32, -8.7]
|
||||
}
|
||||
},
|
||||
"15": {
|
||||
"long": {
|
||||
|
@ -123,7 +143,11 @@
|
|||
"type": "mirrored",
|
||||
"initial_position": [-1.48, -0.12, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"08": {
|
||||
"long": {
|
||||
|
@ -144,7 +168,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.36, -0.12, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"00": {
|
||||
"long": {
|
||||
|
@ -165,7 +193,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.48, -0.12, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"17": {
|
||||
"long": {
|
||||
|
@ -186,7 +218,11 @@
|
|||
"type": "mirrored",
|
||||
"initial_position": [-1.36, 0.13, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"long": {
|
||||
|
@ -207,7 +243,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.36, -0.12, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"20": {
|
||||
"long": {
|
||||
|
@ -228,7 +268,11 @@
|
|||
"type": "mirrored",
|
||||
"initial_position": [-1.36, 0.13, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"long": {
|
||||
|
@ -249,7 +293,11 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.36, -0.12, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
},
|
||||
"20": {
|
||||
"long": {
|
||||
|
@ -270,6 +318,10 @@
|
|||
"type": "normal",
|
||||
"initial_position": [1.36, 0.13, -8.6]
|
||||
},
|
||||
"big_text": []
|
||||
"big_text": [],
|
||||
"medium_text": {
|
||||
"position": [],
|
||||
"initial_position": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
86
src/resources/medium_font.json
Normal file
86
src/resources/medium_font.json
Normal file
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"kerning": 2,
|
||||
"height": 8,
|
||||
"baseline": 4,
|
||||
"glyphs": {
|
||||
"A": [64, 80, 8, 8, 0],
|
||||
"B": [72, 80, 8, 8, 0],
|
||||
"C": [80, 80, 8, 8, 0],
|
||||
"D": [88, 80, 8, 8, 0],
|
||||
"E": [96, 80, 8, 8, 0],
|
||||
"F": [104, 80, 8, 8, 0],
|
||||
"G": [112, 80, 8, 8, 0],
|
||||
"H": [120, 80, 8, 8, 0],
|
||||
"I": [128, 80, 8, 8, 0],
|
||||
"J": [136, 80, 8, 8, 0],
|
||||
"K": [144, 80, 8, 8, 0],
|
||||
"L": [152, 80, 8, 8, 0],
|
||||
"M": [160, 80, 8, 8, 0],
|
||||
"N": [168, 80, 8, 8, 0],
|
||||
"O": [176, 80, 8, 8, 0],
|
||||
"P": [184, 80, 8, 8, 0],
|
||||
"Q": [192, 80, 8, 8, 0],
|
||||
"R": [200, 80, 8, 8, 0],
|
||||
"S": [208, 80, 8, 8, 0],
|
||||
"T": [216, 80, 8, 8, 0],
|
||||
"U": [224, 80, 8, 8, 0],
|
||||
"V": [232, 80, 8, 8, 0],
|
||||
"W": [240, 80, 8, 8, 0],
|
||||
"X": [65, 88, 8, 8, 0],
|
||||
"Y": [72, 88, 8, 8, 0],
|
||||
"Z": [80, 88, 8, 8, 0],
|
||||
"0": [88, 88, 8, 8, 0],
|
||||
"1": [96, 88, 8, 8, 0],
|
||||
"2": [104, 88, 8, 8, 0],
|
||||
"3": [112, 88, 8, 8, 0],
|
||||
"4": [120, 88, 8, 8, 0],
|
||||
"5": [128, 88, 8, 8, 0],
|
||||
"6": [136, 88, 8, 8, 0],
|
||||
"7": [144, 88, 8, 8, 0],
|
||||
"8": [152, 88, 8, 8, 0],
|
||||
"9": [160, 88, 8, 8, 0],
|
||||
"a": [168, 88, 8, 8, 0],
|
||||
"b": [176, 88, 8, 8, 0],
|
||||
"c": [184, 88, 8, 8, 0],
|
||||
"d": [192, 88, 8, 8, 0],
|
||||
"e": [200, 88, 8, 8, 0],
|
||||
"f": [208, 88, 8, 8, 0],
|
||||
"g": [217, 90, 8, 8, 0],
|
||||
"h": [224, 88, 8, 8, 0],
|
||||
"i": [232, 88, 8, 8, 0],
|
||||
"j": [240, 88, 8, 10, 0],
|
||||
"k": [64, 96, 8, 8, 0],
|
||||
"l": [72, 96, 8, 8, 0],
|
||||
"m": [80, 96, 8, 8, 0],
|
||||
"n": [88, 96, 8, 8, 0],
|
||||
"o": [96, 96, 8, 8, 0],
|
||||
"p": [104, 98, 8, 8, 0],
|
||||
"q": [112, 98, 8, 8, 0],
|
||||
"r": [120, 96, 8, 8, 0],
|
||||
"s": [128, 96, 8, 8, 0],
|
||||
"t": [136, 96, 8, 8, 0],
|
||||
"u": [144, 96, 8, 8, 0],
|
||||
"v": [152, 96, 8, 8, 0],
|
||||
"w": [160, 96, 8, 8, 0],
|
||||
"x": [168, 96, 8, 8, 0],
|
||||
"y": [176, 96, 8, 8, 0],
|
||||
"z": [184, 96, 8, 8, 0],
|
||||
",": [192, 96, 8, 8, 0],
|
||||
".": [200, 96, 8, 8, 0],
|
||||
"*": [208, 96, 8, 8, 0],
|
||||
":": [0, 104, 8, 8, 0],
|
||||
"@": [8, 104, 8, 8, 0],
|
||||
"'": [16, 104, 8, 8, 0],
|
||||
"(": [24, 104, 8, 8, 0],
|
||||
")": [32, 104, 8, 8, 0],
|
||||
"-": [40, 104, 8, 8, 0],
|
||||
"!": [48, 104, 8, 8, 0],
|
||||
"\\": [56, 104, 8, 8, 0],
|
||||
"#": [64, 104, 8, 8, 0],
|
||||
"%": [72, 104, 8, 8, 0],
|
||||
"&": [80, 104, 8, 8, 0],
|
||||
"?": [88, 104, 8, 8, 0],
|
||||
"/": [96, 104, 8, 9, 0],
|
||||
" ": [0, 0, 0, 0, 0, 0]
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue