mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
started working on switching hud and general cursor movement
This commit is contained in:
parent
2d08a67ae6
commit
f318cee7ed
12 changed files with 195 additions and 142 deletions
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -1649,6 +1649,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz",
|
||||||
"integrity": "sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA=="
|
"integrity": "sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA=="
|
||||||
},
|
},
|
||||||
|
"@tweenjs/tween.js": {
|
||||||
|
"version": "18.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.0.tgz",
|
||||||
|
"integrity": "sha512-z45HU0G0e/SenbvGdAlTpUR5Hur5zwZXQcqfI+f7EnVHdeb2oMI2rQghEePu7uXuvBC0nuKWG5YtZ1nWbuvqzQ=="
|
||||||
|
},
|
||||||
"@types/babel__core": {
|
"@types/babel__core": {
|
||||||
"version": "7.1.9",
|
"version": "7.1.9",
|
||||||
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz",
|
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"@testing-library/jest-dom": "^4.2.4",
|
"@testing-library/jest-dom": "^4.2.4",
|
||||||
"@testing-library/react": "^9.5.0",
|
"@testing-library/react": "^9.5.0",
|
||||||
"@testing-library/user-event": "^7.2.1",
|
"@testing-library/user-event": "^7.2.1",
|
||||||
|
"@tweenjs/tween.js": "^18.6.0",
|
||||||
"@types/jest": "^24.9.1",
|
"@types/jest": "^24.9.1",
|
||||||
"@types/node": "^12.12.54",
|
"@types/node": "^12.12.54",
|
||||||
"@types/react": "^16.9.47",
|
"@types/react": "^16.9.47",
|
||||||
|
|
Binary file not shown.
|
@ -1,19 +1,5 @@
|
||||||
import React, {
|
import React, { useState, Suspense, useCallback, useEffect } from "react";
|
||||||
useState,
|
import { Canvas } from "react-three-fiber";
|
||||||
Suspense,
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useMemo,
|
|
||||||
useRef,
|
|
||||||
} from "react";
|
|
||||||
import {
|
|
||||||
useFrame,
|
|
||||||
Canvas,
|
|
||||||
useLoader,
|
|
||||||
useThree,
|
|
||||||
createPortal,
|
|
||||||
useCamera,
|
|
||||||
} from "react-three-fiber";
|
|
||||||
import Lain, {
|
import Lain, {
|
||||||
LainIntro,
|
LainIntro,
|
||||||
LainMoveDown,
|
LainMoveDown,
|
||||||
|
@ -22,24 +8,32 @@ import Lain, {
|
||||||
LainMoveUp,
|
LainMoveUp,
|
||||||
LainStanding,
|
LainStanding,
|
||||||
} from "./Lain";
|
} from "./Lain";
|
||||||
import Hub from "./Hub";
|
import Hub, { PositionAndScaleProps } from "./Hub";
|
||||||
//import Orb from "./Orb";
|
//import Orb from "./Orb";
|
||||||
import {
|
import { OrbitControls, PerspectiveCamera } from "drei";
|
||||||
OrbitControls,
|
|
||||||
PerspectiveCamera,
|
|
||||||
OrthographicCamera,
|
|
||||||
Octahedron,
|
|
||||||
} from "drei";
|
|
||||||
import Lights from "./Lights";
|
import Lights from "./Lights";
|
||||||
import { Matrix4, Scene } from "three";
|
|
||||||
import OrthoCamera from "./OrthoCamera";
|
import OrthoCamera from "./OrthoCamera";
|
||||||
|
import TWEEN from "@tweenjs/tween.js";
|
||||||
|
|
||||||
|
import level_sprite_directions from "../resources/level_sprite_directions.json";
|
||||||
|
import lain_animations from "../resources/lain_animations.json";
|
||||||
|
import level_sprite_huds from "../resources/level_sprite_huds.json";
|
||||||
|
|
||||||
type KeyCodeAssociations = {
|
type KeyCodeAssociations = {
|
||||||
[keyCode: number]: string;
|
[keyCode: number]: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type FrameCounts = {
|
type SpriteDirections = {
|
||||||
[animation: string]: number;
|
[key: string]: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// will fix the typing on this later
|
||||||
|
type SpriteHuds = {
|
||||||
|
[key: string]: Record<string, any>;
|
||||||
|
};
|
||||||
|
|
||||||
|
type LainAnimations = {
|
||||||
|
[key: string]: Record<string, number>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Game = () => {
|
const Game = () => {
|
||||||
|
@ -50,6 +44,25 @@ const Game = () => {
|
||||||
const [cameraPosY, setCameraPosY] = useState(0);
|
const [cameraPosY, setCameraPosY] = useState(0);
|
||||||
const [cameraRotationY, setCameraRotationY] = useState(0);
|
const [cameraRotationY, setCameraRotationY] = useState(0);
|
||||||
|
|
||||||
|
const [currentSprite, setCurrentSprite] = useState("043");
|
||||||
|
|
||||||
|
// we separate positions of the hud sprites into the state since we need to animate thme
|
||||||
|
const [longHudPosition, setLongHudPosition] = useState<
|
||||||
|
PositionAndScaleProps
|
||||||
|
>();
|
||||||
|
const [boringHudPosition, setBoringHudPosition] = useState<
|
||||||
|
PositionAndScaleProps
|
||||||
|
>();
|
||||||
|
const [bigHudPosition, setBigHudPosition] = useState<PositionAndScaleProps>();
|
||||||
|
|
||||||
|
const getMove = (currentLoc: string, key: string): string => {
|
||||||
|
return (level_sprite_directions as SpriteDirections)[currentLoc][key];
|
||||||
|
};
|
||||||
|
|
||||||
|
const getHudData = (sprite: string) => {
|
||||||
|
return (level_sprite_huds as SpriteHuds)[sprite];
|
||||||
|
};
|
||||||
|
|
||||||
const moveCamera = (value: number, duration: number) => {
|
const moveCamera = (value: number, duration: number) => {
|
||||||
const moveInterval = setInterval(() => {
|
const moveInterval = setInterval(() => {
|
||||||
setCameraPosY((prev: number) => prev + value);
|
setCameraPosY((prev: number) => prev + value);
|
||||||
|
@ -71,42 +84,31 @@ const Game = () => {
|
||||||
}, duration);
|
}, duration);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getKeyValue = <U extends keyof T, T extends object>(key: U) => (
|
|
||||||
obj: T
|
|
||||||
) => obj[key];
|
|
||||||
|
|
||||||
const getKeyCodeAssociation = (keyCode: number): string => {
|
const getKeyCodeAssociation = (keyCode: number): string => {
|
||||||
return getKeyValue<keyof KeyCodeAssociations, KeyCodeAssociations>(keyCode)(
|
return ({
|
||||||
{
|
|
||||||
40: "down",
|
40: "down",
|
||||||
37: "left",
|
37: "left",
|
||||||
38: "up",
|
38: "up",
|
||||||
39: "right",
|
39: "right",
|
||||||
}
|
} as KeyCodeAssociations)[keyCode];
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFrameCount = (animation: string): number => {
|
const setAnimationState = useCallback(
|
||||||
return getKeyValue<keyof FrameCounts, FrameCounts>(animation)({
|
(key: string) => {
|
||||||
up: 36,
|
const move = getMove(currentSprite, key);
|
||||||
down: 36,
|
|
||||||
left: 47,
|
|
||||||
right: 47,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// frameCount / FPS * 1000 to turn it into seconds
|
|
||||||
// 0.27 is a proportional value i calculated from the avg duration of an animation
|
|
||||||
// in the original game
|
|
||||||
const getAnimationDuration = (animation: string): number => {
|
|
||||||
const frameCount = getFrameCount(animation);
|
|
||||||
return (frameCount / (frameCount * 0.27)) * 1000;
|
|
||||||
};
|
|
||||||
|
|
||||||
const setAnimationState = (key: string) => {
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "down":
|
case "down":
|
||||||
|
// "+" 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.
|
||||||
|
if (move[0] !== "+") setCurrentSprite(move);
|
||||||
|
else {
|
||||||
setLainMoveState(<LainMoveDown />);
|
setLainMoveState(<LainMoveDown />);
|
||||||
|
setTimeout(() => {
|
||||||
|
setCurrentSprite(move);
|
||||||
|
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "left":
|
case "left":
|
||||||
setLainMoveState(<LainMoveLeft />);
|
setLainMoveState(<LainMoveLeft />);
|
||||||
|
@ -129,18 +131,20 @@ const Game = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLainMoving(false);
|
setLainMoving(false);
|
||||||
setLainMoveState(<LainStanding />);
|
setLainMoveState(<LainStanding />);
|
||||||
}, getAnimationDuration(key));
|
}, (lain_animations as LainAnimations)[key]["duration"]);
|
||||||
};
|
},
|
||||||
|
[currentSprite]
|
||||||
|
);
|
||||||
|
|
||||||
const handleUserKeyPress = useCallback(
|
const handleUserKeyPress = useCallback(
|
||||||
(event) => {
|
(event) => {
|
||||||
const { _, keyCode } = event;
|
const { keyCode } = event;
|
||||||
|
|
||||||
const key = getKeyCodeAssociation(keyCode);
|
const key = getKeyCodeAssociation(keyCode);
|
||||||
|
|
||||||
console.log(key);
|
console.log(key);
|
||||||
|
|
||||||
if (!isLainMoving) {
|
if (!isLainMoving && key) {
|
||||||
setAnimationState(key);
|
setAnimationState(key);
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "left":
|
case "left":
|
||||||
|
@ -168,7 +172,7 @@ const Game = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[isLainMoving]
|
[isLainMoving, setAnimationState]
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -182,6 +186,21 @@ const Game = () => {
|
||||||
};
|
};
|
||||||
}, [handleUserKeyPress]);
|
}, [handleUserKeyPress]);
|
||||||
|
|
||||||
|
const animateSpriteHUDIn = () => {
|
||||||
|
|
||||||
|
//wip
|
||||||
|
const initialLongPos = getHudData(currentSprite)["long"]["initial"];
|
||||||
|
const finalLongPos = getHudData(currentSprite)["long"]["initial"];
|
||||||
|
const pos = getHudData(currentSprite)["long"]["position"];
|
||||||
|
const pos1 = getHudData(currentSprite)["big"]["position"];
|
||||||
|
const pos2 = getHudData(currentSprite)["boring"]["position"];
|
||||||
|
setBigHudPosition(pos1);
|
||||||
|
setLongHudPosition(pos);
|
||||||
|
setBoringHudPosition(pos2);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(animateSpriteHUDIn, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Canvas>
|
<Canvas>
|
||||||
|
@ -198,7 +217,18 @@ const Game = () => {
|
||||||
<Hub />
|
<Hub />
|
||||||
<Lights />
|
<Lights />
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
<OrthoCamera />
|
<OrthoCamera
|
||||||
|
bigHudPosition={bigHudPosition!}
|
||||||
|
boringHudPosition={boringHudPosition!}
|
||||||
|
longHudPosition={longHudPosition!}
|
||||||
|
longHudType={getHudData(currentSprite)["long"]["type"]}
|
||||||
|
boringHudType={getHudData(currentSprite)["boring"]["type"]}
|
||||||
|
bigHudType={getHudData(currentSprite)["big"]["type"]}
|
||||||
|
longHudScale={getHudData(currentSprite)["long"]["scale"]}
|
||||||
|
boringHudScale={getHudData(currentSprite)["boring"]["scale"]}
|
||||||
|
bigHudScale={getHudData(currentSprite)["big"]["scale"]}
|
||||||
|
id={getHudData(currentSprite)["id"]}
|
||||||
|
/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</PerspectiveCamera>
|
</PerspectiveCamera>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
|
|
@ -30,6 +30,7 @@ const GrayRing = (props: any) => {
|
||||||
"/models/ring0.glb",
|
"/models/ring0.glb",
|
||||||
draco("/draco-gltf/")
|
draco("/draco-gltf/")
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<group
|
<group
|
||||||
scale={[1.3, 1.3, 1.3]}
|
scale={[1.3, 1.3, 1.3]}
|
||||||
|
|
|
@ -4,24 +4,21 @@ import * as THREE from "three";
|
||||||
import longHud from "../static/sprites/long_hud.png";
|
import longHud from "../static/sprites/long_hud.png";
|
||||||
import boringHud from "../static/sprites/long_hud_boring.png";
|
import boringHud from "../static/sprites/long_hud_boring.png";
|
||||||
import bigHud from "../static/sprites/big_hud.png";
|
import bigHud from "../static/sprites/big_hud.png";
|
||||||
|
import { PositionAndScaleProps } from "./Hub";
|
||||||
|
|
||||||
type HUDElementProps = {
|
export type HUDElementProps = {
|
||||||
longHudType: string;
|
longHudType: string;
|
||||||
boringHudType: string;
|
boringHudType: string;
|
||||||
bigHudType: string;
|
bigHudType: string;
|
||||||
|
|
||||||
longHudPosition: [number, number, number];
|
longHudPosition: PositionAndScaleProps;
|
||||||
longHudScale: [number, number, number];
|
longHudScale: PositionAndScaleProps;
|
||||||
|
|
||||||
boringHudPosition: [number, number, number];
|
boringHudPosition: PositionAndScaleProps;
|
||||||
boringHudScale: [number, number, number];
|
boringHudScale: PositionAndScaleProps;
|
||||||
|
|
||||||
bigHudPosition: [number, number, number];
|
bigHudPosition: PositionAndScaleProps;
|
||||||
bigHudScale: [number, number, number];
|
bigHudScale: PositionAndScaleProps;
|
||||||
};
|
|
||||||
|
|
||||||
type SpriteTypeToSprite = {
|
|
||||||
[key: string]: string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const HUDElement = (props: HUDElementProps) => {
|
const HUDElement = (props: HUDElementProps) => {
|
||||||
|
@ -51,6 +48,7 @@ const HUDElement = (props: HUDElementProps) => {
|
||||||
THREE.TextureLoader,
|
THREE.TextureLoader,
|
||||||
spriteTypeToSprite(props.boringHudType, "boring")!
|
spriteTypeToSprite(props.boringHudType, "boring")!
|
||||||
);
|
);
|
||||||
|
|
||||||
const bigHudTexture: any = useLoader(
|
const bigHudTexture: any = useLoader(
|
||||||
THREE.TextureLoader,
|
THREE.TextureLoader,
|
||||||
spriteTypeToSprite(props.bigHudType, "big")!
|
spriteTypeToSprite(props.bigHudType, "big")!
|
||||||
|
@ -65,10 +63,7 @@ const HUDElement = (props: HUDElementProps) => {
|
||||||
transparent={true}
|
transparent={true}
|
||||||
/>
|
/>
|
||||||
</sprite>
|
</sprite>
|
||||||
<sprite
|
<sprite position={props.boringHudPosition} scale={props.boringHudScale}>
|
||||||
position={props.boringHudPosition}
|
|
||||||
scale={props.boringHudScale}
|
|
||||||
>
|
|
||||||
<spriteMaterial
|
<spriteMaterial
|
||||||
attach="material"
|
attach="material"
|
||||||
map={longHudBoringTexture}
|
map={longHudBoringTexture}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import PurpleRing from "./PurpleRing";
|
||||||
import LevelSprite from "./LevelSprite";
|
import LevelSprite from "./LevelSprite";
|
||||||
import level_sprites from "../resources/level_sprites.json";
|
import level_sprites from "../resources/level_sprites.json";
|
||||||
|
|
||||||
type PositionAndScaleProps = [number, number, number];
|
export type PositionAndScaleProps = [number, number, number];
|
||||||
type RotationProps = [number, number, number, (string | undefined)?];
|
export type RotationProps = [number, number, number, (string | undefined)?];
|
||||||
|
|
||||||
const Hub = (props: any) => {
|
const Hub = (props: any) => {
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -45,7 +45,6 @@ const LevelSprite = (props: LevelSpriteConstructorProps) => {
|
||||||
>
|
>
|
||||||
<planeBufferGeometry attach="geometry" />
|
<planeBufferGeometry attach="geometry" />
|
||||||
<meshStandardMaterial
|
<meshStandardMaterial
|
||||||
color={0xffffff}
|
|
||||||
side={THREE.DoubleSide}
|
side={THREE.DoubleSide}
|
||||||
attach="material"
|
attach="material"
|
||||||
map={spriteTexture}
|
map={spriteTexture}
|
||||||
|
|
|
@ -18,12 +18,13 @@ import {
|
||||||
import { OrthographicCamera, Octahedron } from "drei";
|
import { OrthographicCamera, Octahedron } from "drei";
|
||||||
import { Matrix4, Scene, BasicDepthPacking } from "three";
|
import { Matrix4, Scene, BasicDepthPacking } from "three";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
import HUDElement from "./HUDElement";
|
import HUDElement, { HUDElementProps } from "./HUDElement";
|
||||||
import level_sprite_huds from "../resources/level_sprite_huds.json";
|
|
||||||
|
|
||||||
type PositionAndScaleProps = [number, number, number];
|
interface OrthoCameraProps extends HUDElementProps {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
const OrthoCamera = () => {
|
const OrthoCamera = (props: OrthoCameraProps) => {
|
||||||
const { gl, scene, camera } = useThree();
|
const { gl, scene, camera } = useThree();
|
||||||
const virtualScene = useMemo(() => new Scene(), []);
|
const virtualScene = useMemo(() => new Scene(), []);
|
||||||
const virtualCam = useRef();
|
const virtualCam = useRef();
|
||||||
|
@ -42,23 +43,18 @@ const OrthoCamera = () => {
|
||||||
makeDefault={false}
|
makeDefault={false}
|
||||||
position={[0, 0, 10]}
|
position={[0, 0, 10]}
|
||||||
>
|
>
|
||||||
{Object.values(level_sprite_huds.level04).map((spriteHud) => {
|
|
||||||
return (
|
|
||||||
<HUDElement
|
<HUDElement
|
||||||
longHudType={spriteHud.long.type}
|
longHudType={props.longHudType}
|
||||||
boringHudType={spriteHud.boring.type}
|
boringHudType={props.boringHudType}
|
||||||
bigHudType={spriteHud.big.type}
|
bigHudType={props.bigHudType}
|
||||||
longHudPosition={spriteHud.long.position as PositionAndScaleProps}
|
longHudPosition={props.longHudPosition}
|
||||||
longHudScale={spriteHud.long.scale as PositionAndScaleProps}
|
longHudScale={props.longHudScale}
|
||||||
boringHudPosition={
|
boringHudPosition={props.boringHudPosition}
|
||||||
spriteHud.boring.position as PositionAndScaleProps
|
boringHudScale={props.boringHudScale}
|
||||||
}
|
bigHudPosition={props.bigHudPosition}
|
||||||
boringHudScale={spriteHud.boring.scale as PositionAndScaleProps}
|
bigHudScale={props.bigHudScale}
|
||||||
bigHudPosition={spriteHud.big.position as PositionAndScaleProps}
|
key={props.id}
|
||||||
bigHudScale={spriteHud.big.scale as PositionAndScaleProps}
|
|
||||||
/>
|
/>
|
||||||
);
|
|
||||||
})}
|
|
||||||
</OrthographicCamera>
|
</OrthographicCamera>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
18
src/resources/lain_animations.json
Normal file
18
src/resources/lain_animations.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"up": {
|
||||||
|
"frame_count": 36,
|
||||||
|
"duration": 3703.704
|
||||||
|
},
|
||||||
|
"down": {
|
||||||
|
"frame_count": 36,
|
||||||
|
"duration": 3703.704
|
||||||
|
},
|
||||||
|
"left": {
|
||||||
|
"frame_count": 47,
|
||||||
|
"duration": 3703.704
|
||||||
|
},
|
||||||
|
"right": {
|
||||||
|
"frame_count": 47,
|
||||||
|
"duration": 3703.704
|
||||||
|
}
|
||||||
|
}
|
8
src/resources/level_sprite_directions.json
Normal file
8
src/resources/level_sprite_directions.json
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"043": {
|
||||||
|
"up": "+",
|
||||||
|
"down": "042",
|
||||||
|
"left": "+",
|
||||||
|
"right": ""
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,10 +1,11 @@
|
||||||
{
|
{
|
||||||
"level04": {
|
|
||||||
"043": {
|
"043": {
|
||||||
|
"id": "043hud",
|
||||||
"long": {
|
"long": {
|
||||||
"position": [-0.45, 0.15, -8.6],
|
"position": [-0.45, 0.15, -8.6],
|
||||||
"scale": [1, 0.03, 1],
|
"scale": [1, 0.03, 1],
|
||||||
"type": "normal"
|
"type": "normal",
|
||||||
|
"initial_position": [-1.45, 0.15, -8.6]
|
||||||
},
|
},
|
||||||
"boring": {
|
"boring": {
|
||||||
"position": [0.48, 0.174, -8.6],
|
"position": [0.48, 0.174, -8.6],
|
||||||
|
@ -17,5 +18,4 @@
|
||||||
"type": "normal"
|
"type": "normal"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue