mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
adding intro animation
This commit is contained in:
parent
3d6524bee2
commit
168fe2cb9f
10 changed files with 157 additions and 105 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -21,3 +21,6 @@
|
|||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
.idea
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import React, { useEffect, useState } from "react";
|
|||
import Game from "./components/Game";
|
||||
import "./static/css/hub.css";
|
||||
import "./static/css/main.css";
|
||||
import { Canvas } from "react-three-fiber";
|
||||
|
||||
const App = () => {
|
||||
const [moveToGame, setMoveToGame] = useState(false);
|
||||
|
@ -18,7 +19,9 @@ const App = () => {
|
|||
<div id="game-root" className="game">
|
||||
{/* {moveToGame ? <Game /> : <Intro setMoveToGame={setMoveToGame} />} */}
|
||||
{/* <Intro /> */}
|
||||
<Game />
|
||||
<Canvas concurrent>
|
||||
<Game />
|
||||
</Canvas>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
import { a, useSpring } from "@react-spring/three";
|
||||
import { OrbitControls } from "drei";
|
||||
import React, { Suspense, useCallback, useEffect, useState } from "react";
|
||||
import { Canvas } from "react-three-fiber";
|
||||
import React, {
|
||||
Suspense,
|
||||
useCallback,
|
||||
useEffect,
|
||||
useRef,
|
||||
useState,
|
||||
} from "react";
|
||||
import { useFrame } from "react-three-fiber";
|
||||
import lain_animations from "../resources/lain_animations.json";
|
||||
import level_sprite_directions from "../resources/level_sprite_directions.json";
|
||||
import level_sprite_huds from "../resources/level_sprite_huds.json";
|
||||
|
@ -12,11 +18,13 @@ import Lain, {
|
|||
LainMoveRight,
|
||||
LainMoveUp,
|
||||
LainStanding,
|
||||
LainIntro,
|
||||
} from "./Lain";
|
||||
import Lights from "./Lights";
|
||||
import OrthoCamera from "./OrthoCamera";
|
||||
import Preloader from "./Preloader";
|
||||
import Starfield from "./Starfield";
|
||||
import * as THREE from "three";
|
||||
|
||||
type KeyCodeAssociations = {
|
||||
[keyCode: number]: string;
|
||||
|
@ -36,12 +44,14 @@ type LainAnimations = {
|
|||
};
|
||||
|
||||
const Game = () => {
|
||||
const [isIntro, setIsIntro] = useState(true);
|
||||
|
||||
const [isLainMoving, setLainMoving] = useState(false);
|
||||
const [lainMoveState, setLainMoveState] = useState(<LainStanding />);
|
||||
|
||||
const [orthoCameraPosY, setOrthoCameraPosY] = useState(0);
|
||||
|
||||
const [currentSprite, setCurrentSprite] = useState("0506");
|
||||
const [currentSprite, setCurrentSprite] = useState("0422");
|
||||
const [currentSpriteHUD, setCurrentSpriteHUD] = useState<SpriteHuds>(
|
||||
(level_sprite_huds as SpriteHuds)[currentSprite.substr(2)]
|
||||
);
|
||||
|
@ -169,8 +179,8 @@ const Game = () => {
|
|||
(key: string) => {
|
||||
switch (key) {
|
||||
case "down":
|
||||
moveCamera(0.3);
|
||||
moveLain(-0.3);
|
||||
moveCamera(0.6);
|
||||
moveLain(-0.6);
|
||||
setLainMoveState(<LainMoveDown />);
|
||||
break;
|
||||
case "left":
|
||||
|
@ -290,21 +300,51 @@ const Game = () => {
|
|||
};
|
||||
}, [handleKeyPress]);
|
||||
|
||||
const groupRef = useRef();
|
||||
|
||||
useFrame(() => {
|
||||
if (isIntro) {
|
||||
if ((groupRef.current as any).rotation.x > 0) {
|
||||
if ((groupRef.current as any).position.z > -1) {
|
||||
(groupRef.current as any).rotation.x -= 0.015;
|
||||
} else {
|
||||
(groupRef.current as any).rotation.x -= 0.01;
|
||||
}
|
||||
}
|
||||
if ((groupRef.current as any).position.y > 0) {
|
||||
(groupRef.current as any).position.y -= 0.015;
|
||||
}
|
||||
if ((groupRef.current as any).position.z < 0) {
|
||||
(groupRef.current as any).position.z += 0.04;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setLainMoving(true);
|
||||
setLainMoveState(<LainIntro />);
|
||||
updateHUD();
|
||||
setTimeout(() => {
|
||||
setLainMoving(false);
|
||||
setLainMoveState(<LainStanding />);
|
||||
setIsIntro(false);
|
||||
updateHUD();
|
||||
}, (lain_animations as LainAnimations)["intro"]["duration"]);
|
||||
}, [updateHUD]);
|
||||
|
||||
// pos-z ? => 3
|
||||
// rot-x 1.5 => 0
|
||||
// grp rot/pos both 0,0,0 => ?
|
||||
return (
|
||||
<Canvas concurrent>
|
||||
<a.perspectiveCamera
|
||||
position-z={3}
|
||||
position-y={camPosY}
|
||||
rotation-y={camRotY}
|
||||
>
|
||||
<a.perspectiveCamera
|
||||
position-z={3}
|
||||
position-y={camPosY}
|
||||
rotation-y={camRotY}
|
||||
>
|
||||
<group rotation={[2.3, 0, 0]} position={[0, 1.5, -7.5]} ref={groupRef}>
|
||||
<Suspense fallback={null}>
|
||||
<OrbitControls />
|
||||
<Preloader />
|
||||
<Lain
|
||||
isLainMoving={isLainMoving}
|
||||
lainMoveState={lainMoveState}
|
||||
lainPosY={lainPosY}
|
||||
/>
|
||||
<Hub currentSprite={currentSprite} />
|
||||
<OrthoCamera
|
||||
longHUDPosX={longHUDPosX}
|
||||
|
@ -330,13 +370,18 @@ const Game = () => {
|
|||
bigHUDScale={currentSpriteHUD!["big"]["scale"]}
|
||||
orthoCameraPosY={orthoCameraPosY}
|
||||
id={currentSpriteHUD!["id"]}
|
||||
orbVisibility={!isIntro}
|
||||
/>
|
||||
<OrbitControls />
|
||||
<Starfield starfieldPosY={camPosY} />
|
||||
<Lights />
|
||||
</Suspense>
|
||||
</a.perspectiveCamera>
|
||||
</Canvas>
|
||||
</group>
|
||||
<Lain
|
||||
isLainMoving={isLainMoving}
|
||||
lainMoveState={lainMoveState}
|
||||
lainPosY={lainPosY}
|
||||
/>
|
||||
</a.perspectiveCamera>
|
||||
);
|
||||
};
|
||||
export default Game;
|
||||
|
|
|
@ -8,6 +8,7 @@ import moveUpSpriteSheet from "../static/sprites/jump_up.png";
|
|||
import moveLeftSpriteSheet from "../static/sprites/move_left.png";
|
||||
import moveRightSpriteSheet from "../static/sprites/move_right.png";
|
||||
import standingSpriteSheet from "../static/sprites/standing.png";
|
||||
import introSpriteSheet from "../static/sprites/intro.png";
|
||||
|
||||
type LainProps = {
|
||||
isLainMoving: boolean;
|
||||
|
@ -47,10 +48,10 @@ const LainConstructor = (props: LainConstructorProps) => {
|
|||
export const LainIntro = () => {
|
||||
return (
|
||||
<LainConstructor
|
||||
sprite={standingSpriteSheet}
|
||||
frameCount={1}
|
||||
framesHorizontal={8}
|
||||
framesVertical={6}
|
||||
sprite={introSpriteSheet}
|
||||
frameCount={50}
|
||||
framesHorizontal={10}
|
||||
framesVertical={5}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -7,7 +7,11 @@ import orbSprite from "../static/sprites/orb.png";
|
|||
let orbIdx = 0;
|
||||
let orbDirectionChangeCount = 0;
|
||||
|
||||
const Orb = memo(() => {
|
||||
type OrbProps = {
|
||||
orbVisibility: boolean;
|
||||
};
|
||||
|
||||
const Orb = memo((props: OrbProps) => {
|
||||
const orbRef = useRef();
|
||||
const [orbDirection, setOrbDirection] = useState("left");
|
||||
const [currentCurve, setCurrentCurve] = useState("first");
|
||||
|
@ -29,79 +33,81 @@ const Orb = memo(() => {
|
|||
);
|
||||
|
||||
useFrame(() => {
|
||||
let orbPosFirst = firstCurve.getPoint(orbIdx / 250);
|
||||
let orbPosSecond = secondCurve.getPoint(orbIdx / 250);
|
||||
if (props.orbVisibility) {
|
||||
let orbPosFirst = firstCurve.getPoint(orbIdx / 250);
|
||||
let orbPosSecond = secondCurve.getPoint(orbIdx / 250);
|
||||
|
||||
if (orbPosFirst.x < -1.4) {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
setOrbDirection("right");
|
||||
break;
|
||||
case "second":
|
||||
setOrbDirection("left");
|
||||
break;
|
||||
if (orbPosFirst.x < -1.4) {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
setOrbDirection("right");
|
||||
break;
|
||||
case "second":
|
||||
setOrbDirection("left");
|
||||
break;
|
||||
}
|
||||
orbDirectionChangeCount++;
|
||||
}
|
||||
orbDirectionChangeCount++;
|
||||
}
|
||||
|
||||
if (orbPosFirst.x > 1.4) {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
setOrbDirection("left");
|
||||
break;
|
||||
case "second":
|
||||
setOrbDirection("right");
|
||||
break;
|
||||
if (orbPosFirst.x > 1.4) {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
setOrbDirection("left");
|
||||
break;
|
||||
case "second":
|
||||
setOrbDirection("right");
|
||||
break;
|
||||
}
|
||||
orbDirectionChangeCount++;
|
||||
}
|
||||
orbDirectionChangeCount++;
|
||||
}
|
||||
|
||||
if (orbDirection === "left") {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
orbIdx++;
|
||||
break;
|
||||
case "second":
|
||||
orbIdx--;
|
||||
break;
|
||||
if (orbDirection === "left") {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
orbIdx++;
|
||||
break;
|
||||
case "second":
|
||||
orbIdx--;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
orbIdx--;
|
||||
break;
|
||||
case "second":
|
||||
orbIdx++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
orbIdx--;
|
||||
break;
|
||||
case "second":
|
||||
orbIdx++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (orbDirectionChangeCount % 6 === 0 && orbDirectionChangeCount !== 0) {
|
||||
orbDirectionChangeCount = 0;
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
orbIdx = 250;
|
||||
setCurrentCurve("second");
|
||||
break;
|
||||
case "second":
|
||||
orbIdx = 0;
|
||||
setCurrentCurve("first");
|
||||
break;
|
||||
if (orbDirectionChangeCount % 6 === 0 && orbDirectionChangeCount !== 0) {
|
||||
orbDirectionChangeCount = 0;
|
||||
switch (currentCurve) {
|
||||
case "first":
|
||||
orbIdx = 250;
|
||||
setCurrentCurve("second");
|
||||
break;
|
||||
case "second":
|
||||
orbIdx = 0;
|
||||
setCurrentCurve("first");
|
||||
break;
|
||||
}
|
||||
setOrbDirection("left");
|
||||
}
|
||||
setOrbDirection("left");
|
||||
}
|
||||
|
||||
if (currentCurve === "first") {
|
||||
(orbRef.current as any).position.x = orbPosFirst.x;
|
||||
(orbRef.current as any).position.y = orbPosFirst.y;
|
||||
} else {
|
||||
(orbRef.current as any).position.x = orbPosSecond.x;
|
||||
(orbRef.current as any).position.y = orbPosSecond.y;
|
||||
if (currentCurve === "first") {
|
||||
(orbRef.current as any).position.x = orbPosFirst.x;
|
||||
(orbRef.current as any).position.y = orbPosFirst.y;
|
||||
} else {
|
||||
(orbRef.current as any).position.x = orbPosSecond.x;
|
||||
(orbRef.current as any).position.y = orbPosSecond.y;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<group position={[0, -0.1, -9]}>
|
||||
<group position={[0, -0.1, -9]} visible={props.orbVisibility}>
|
||||
<sprite scale={[0.5, 0.5, 0.5]} ref={orbRef}>
|
||||
<spriteMaterial attach="material" map={orbSpriteTexture} />
|
||||
</sprite>
|
||||
|
|
|
@ -7,6 +7,7 @@ import Orb from "./Orb";
|
|||
interface OrthoCameraProps extends HUDElementProps {
|
||||
id: string;
|
||||
orthoCameraPosY: number;
|
||||
orbVisibility:boolean;
|
||||
}
|
||||
|
||||
const OrthoCamera = (props: OrthoCameraProps) => {
|
||||
|
@ -43,7 +44,7 @@ const OrthoCamera = (props: OrthoCameraProps) => {
|
|||
bigHUDScale={props.bigHUDScale}
|
||||
key={props.id}
|
||||
/>
|
||||
<Orb />
|
||||
<Orb orbVisibility={props.orbVisibility}/>
|
||||
</orthographicCamera>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { a, useSpring } from "@react-spring/three";
|
||||
import { draco } from "drei";
|
||||
import React, { memo } from "react";
|
||||
import React, { memo, useRef } from "react";
|
||||
import { useFrame, useLoader } from "react-three-fiber";
|
||||
import * as THREE from "three";
|
||||
import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
|
||||
|
@ -17,13 +16,7 @@ type GLTFResult = GLTF & {
|
|||
};
|
||||
|
||||
const PurpleRing = memo((props: PurpleRingProps) => {
|
||||
const [{ purpleRingRotationY }, setPurpleRingRotationY] = useSpring(
|
||||
() => ({
|
||||
purpleRingRotationY: 0,
|
||||
config: { precision: 0.0001, duration: 1200 },
|
||||
}),
|
||||
[]
|
||||
);
|
||||
const purpleRingRef = useRef();
|
||||
|
||||
const { nodes } = useLoader<GLTFResult>(
|
||||
GLTFLoader,
|
||||
|
@ -32,18 +25,14 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
);
|
||||
|
||||
useFrame(() => {
|
||||
setPurpleRingRotationY(() => ({
|
||||
purpleRingRotationY: purpleRingRotationY.get() + 0.15,
|
||||
}));
|
||||
(purpleRingRef.current as any).rotation.y += 0.01;
|
||||
});
|
||||
|
||||
const purpleRingRotY = purpleRingRotationY.to([0, 1], [0, Math.PI]);
|
||||
|
||||
return (
|
||||
<a.group
|
||||
<group
|
||||
position={[0, props.purpleRingPosY, 0]}
|
||||
rotation-y={purpleRingRotY}
|
||||
scale={[1.3, 1.3, 1.3]}
|
||||
ref={purpleRingRef}
|
||||
>
|
||||
<mesh geometry={nodes.Circle002.geometry} rotation={[0, Math.PI / 4, 0]}>
|
||||
<meshLambertMaterial
|
||||
|
@ -52,7 +41,7 @@ const PurpleRing = memo((props: PurpleRingProps) => {
|
|||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
</a.group>
|
||||
</group>
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ const Starfield = memo((props: StarfieldProps) => {
|
|||
});
|
||||
|
||||
return (
|
||||
<group position={[-0.7, -1.5, -4]} >
|
||||
<group position={[-0.7, -1.5, -4]} rotation={[0,0,0]}>
|
||||
{posesBlueFromRight.map((pos: any, idx: number) => {
|
||||
return (
|
||||
<mesh
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
{
|
||||
"intro": {
|
||||
"frame_count": 50,
|
||||
"duration": 3944.033
|
||||
},
|
||||
"up": {
|
||||
"frame_count": 36,
|
||||
"duration": 3703.704
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
},
|
||||
"0506": {
|
||||
"up": "0413",
|
||||
"down": "0422",
|
||||
"down": "+0422",
|
||||
"left": "0405",
|
||||
"right": "0513"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue