started working on switching hud and general cursor movement

This commit is contained in:
ad044 2020-08-28 17:49:58 +04:00
parent 2d08a67ae6
commit f318cee7ed
12 changed files with 195 additions and 142 deletions

5
package-lock.json generated
View file

@ -1649,6 +1649,11 @@
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-7.2.1.tgz",
"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": {
"version": "7.1.9",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz",

View file

@ -6,6 +6,7 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"@tweenjs/tween.js": "^18.6.0",
"@types/jest": "^24.9.1",
"@types/node": "^12.12.54",
"@types/react": "^16.9.47",

Binary file not shown.

View file

@ -1,19 +1,5 @@
import React, {
useState,
Suspense,
useCallback,
useEffect,
useMemo,
useRef,
} from "react";
import {
useFrame,
Canvas,
useLoader,
useThree,
createPortal,
useCamera,
} from "react-three-fiber";
import React, { useState, Suspense, useCallback, useEffect } from "react";
import { Canvas } from "react-three-fiber";
import Lain, {
LainIntro,
LainMoveDown,
@ -22,24 +8,32 @@ import Lain, {
LainMoveUp,
LainStanding,
} from "./Lain";
import Hub from "./Hub";
import Hub, { PositionAndScaleProps } from "./Hub";
//import Orb from "./Orb";
import {
OrbitControls,
PerspectiveCamera,
OrthographicCamera,
Octahedron,
} from "drei";
import { OrbitControls, PerspectiveCamera } from "drei";
import Lights from "./Lights";
import { Matrix4, Scene } from "three";
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 = {
[keyCode: number]: string;
};
type FrameCounts = {
[animation: string]: number;
type SpriteDirections = {
[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 = () => {
@ -50,6 +44,25 @@ const Game = () => {
const [cameraPosY, setCameraPosY] = 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 moveInterval = setInterval(() => {
setCameraPosY((prev: number) => prev + value);
@ -71,76 +84,67 @@ const Game = () => {
}, duration);
};
const getKeyValue = <U extends keyof T, T extends object>(key: U) => (
obj: T
) => obj[key];
const getKeyCodeAssociation = (keyCode: number): string => {
return getKeyValue<keyof KeyCodeAssociations, KeyCodeAssociations>(keyCode)(
{
40: "down",
37: "left",
38: "up",
39: "right",
return ({
40: "down",
37: "left",
38: "up",
39: "right",
} as KeyCodeAssociations)[keyCode];
};
const setAnimationState = useCallback(
(key: string) => {
const move = getMove(currentSprite, key);
switch (key) {
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 />);
setTimeout(() => {
setCurrentSprite(move);
}, (lain_animations as LainAnimations)[key]["duration"] + 200);
}
break;
case "left":
setLainMoveState(<LainMoveLeft />);
break;
case "up":
setLainMoveState(<LainMoveUp />);
break;
case "right":
setLainMoveState(<LainMoveRight />);
break;
default:
break;
}
);
};
const getFrameCount = (animation: string): number => {
return getKeyValue<keyof FrameCounts, FrameCounts>(animation)({
up: 36,
down: 36,
left: 47,
right: 47,
});
};
// set moving to true to avoid player from overlapping animations and stuff
// by waiting for the anim to finish
setLainMoving(true);
// 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) {
case "down":
setLainMoveState(<LainMoveDown />);
break;
case "left":
setLainMoveState(<LainMoveLeft />);
break;
case "up":
setLainMoveState(<LainMoveUp />);
break;
case "right":
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(() => {
setLainMoving(false);
setLainMoveState(<LainStanding />);
}, getAnimationDuration(key));
};
// wait for the anim to finish, set lain to standing state, release the move lock
setTimeout(() => {
setLainMoving(false);
setLainMoveState(<LainStanding />);
}, (lain_animations as LainAnimations)[key]["duration"]);
},
[currentSprite]
);
const handleUserKeyPress = useCallback(
(event) => {
const { _, keyCode } = event;
const { keyCode } = event;
const key = getKeyCodeAssociation(keyCode);
console.log(key);
if (!isLainMoving) {
if (!isLainMoving && key) {
setAnimationState(key);
switch (key) {
case "left":
@ -168,7 +172,7 @@ const Game = () => {
}
}
},
[isLainMoving]
[isLainMoving, setAnimationState]
);
useEffect(() => {
@ -182,6 +186,21 @@ const Game = () => {
};
}, [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 (
<>
<Canvas>
@ -198,7 +217,18 @@ const Game = () => {
<Hub />
<Lights />
<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>
</PerspectiveCamera>
</Canvas>

View file

@ -30,6 +30,7 @@ const GrayRing = (props: any) => {
"/models/ring0.glb",
draco("/draco-gltf/")
);
return (
<group
scale={[1.3, 1.3, 1.3]}

View file

@ -4,24 +4,21 @@ import * as THREE from "three";
import longHud from "../static/sprites/long_hud.png";
import boringHud from "../static/sprites/long_hud_boring.png";
import bigHud from "../static/sprites/big_hud.png";
import { PositionAndScaleProps } from "./Hub";
type HUDElementProps = {
export type HUDElementProps = {
longHudType: string;
boringHudType: string;
bigHudType: string;
longHudPosition: [number, number, number];
longHudScale: [number, number, number];
longHudPosition: PositionAndScaleProps;
longHudScale: PositionAndScaleProps;
boringHudPosition: [number, number, number];
boringHudScale: [number, number, number];
boringHudPosition: PositionAndScaleProps;
boringHudScale: PositionAndScaleProps;
bigHudPosition: [number, number, number];
bigHudScale: [number, number, number];
};
type SpriteTypeToSprite = {
[key: string]: string;
bigHudPosition: PositionAndScaleProps;
bigHudScale: PositionAndScaleProps;
};
const HUDElement = (props: HUDElementProps) => {
@ -51,6 +48,7 @@ const HUDElement = (props: HUDElementProps) => {
THREE.TextureLoader,
spriteTypeToSprite(props.boringHudType, "boring")!
);
const bigHudTexture: any = useLoader(
THREE.TextureLoader,
spriteTypeToSprite(props.bigHudType, "big")!
@ -65,10 +63,7 @@ const HUDElement = (props: HUDElementProps) => {
transparent={true}
/>
</sprite>
<sprite
position={props.boringHudPosition}
scale={props.boringHudScale}
>
<sprite position={props.boringHudPosition} scale={props.boringHudScale}>
<spriteMaterial
attach="material"
map={longHudBoringTexture}

View file

@ -4,8 +4,8 @@ import PurpleRing from "./PurpleRing";
import LevelSprite from "./LevelSprite";
import level_sprites from "../resources/level_sprites.json";
type PositionAndScaleProps = [number, number, number];
type RotationProps = [number, number, number, (string | undefined)?];
export type PositionAndScaleProps = [number, number, number];
export type RotationProps = [number, number, number, (string | undefined)?];
const Hub = (props: any) => {
return (

View file

@ -45,7 +45,6 @@ const LevelSprite = (props: LevelSpriteConstructorProps) => {
>
<planeBufferGeometry attach="geometry" />
<meshStandardMaterial
color={0xffffff}
side={THREE.DoubleSide}
attach="material"
map={spriteTexture}

View file

@ -18,12 +18,13 @@ import {
import { OrthographicCamera, Octahedron } from "drei";
import { Matrix4, Scene, BasicDepthPacking } from "three";
import * as THREE from "three";
import HUDElement from "./HUDElement";
import level_sprite_huds from "../resources/level_sprite_huds.json";
import HUDElement, { HUDElementProps } from "./HUDElement";
type PositionAndScaleProps = [number, number, number];
interface OrthoCameraProps extends HUDElementProps {
id: string;
}
const OrthoCamera = () => {
const OrthoCamera = (props: OrthoCameraProps) => {
const { gl, scene, camera } = useThree();
const virtualScene = useMemo(() => new Scene(), []);
const virtualCam = useRef();
@ -42,23 +43,18 @@ const OrthoCamera = () => {
makeDefault={false}
position={[0, 0, 10]}
>
{Object.values(level_sprite_huds.level04).map((spriteHud) => {
return (
<HUDElement
longHudType={spriteHud.long.type}
boringHudType={spriteHud.boring.type}
bigHudType={spriteHud.big.type}
longHudPosition={spriteHud.long.position as PositionAndScaleProps}
longHudScale={spriteHud.long.scale as PositionAndScaleProps}
boringHudPosition={
spriteHud.boring.position as PositionAndScaleProps
}
boringHudScale={spriteHud.boring.scale as PositionAndScaleProps}
bigHudPosition={spriteHud.big.position as PositionAndScaleProps}
bigHudScale={spriteHud.big.scale as PositionAndScaleProps}
/>
);
})}
<HUDElement
longHudType={props.longHudType}
boringHudType={props.boringHudType}
bigHudType={props.bigHudType}
longHudPosition={props.longHudPosition}
longHudScale={props.longHudScale}
boringHudPosition={props.boringHudPosition}
boringHudScale={props.boringHudScale}
bigHudPosition={props.bigHudPosition}
bigHudScale={props.bigHudScale}
key={props.id}
/>
</OrthographicCamera>
);
};

View 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
}
}

View file

@ -0,0 +1,8 @@
{
"043": {
"up": "+",
"down": "042",
"left": "+",
"right": ""
}
}

View file

@ -1,21 +1,21 @@
{
"level04": {
"043": {
"long": {
"position": [-0.45, 0.15, -8.6],
"scale": [1, 0.03, 1],
"type": "normal"
},
"boring": {
"position": [0.48, 0.174, -8.6],
"scale": [1, 0.03, 1],
"type": "normal"
},
"big": {
"position": [0.36, 0.13, -8.6],
"scale": [0.5, 0.06, 1],
"type": "normal"
}
"043": {
"id": "043hud",
"long": {
"position": [-0.45, 0.15, -8.6],
"scale": [1, 0.03, 1],
"type": "normal",
"initial_position": [-1.45, 0.15, -8.6]
},
"boring": {
"position": [0.48, 0.174, -8.6],
"scale": [1, 0.03, 1],
"type": "normal"
},
"big": {
"position": [0.36, 0.13, -8.6],
"scale": [0.5, 0.06, 1],
"type": "normal"
}
}
}