mirror of
https://github.com/ad044/lainTSX.git
synced 2024-10-22 23:19:06 +00:00
added floating sprites
This commit is contained in:
parent
af26c3563c
commit
c226845717
7 changed files with 119 additions and 16 deletions
|
@ -12,7 +12,10 @@
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript
|
||||||
|
>do you actually believe i could rewrite this in plain html css or
|
||||||
|
smoetihng</noscript
|
||||||
|
>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -12,7 +12,7 @@ import Lain from "./Lain";
|
||||||
import { Mesh, MeshLambertMaterial, DoubleSide } from "three";
|
import { Mesh, MeshLambertMaterial, DoubleSide } from "three";
|
||||||
import * as THREE from "three";
|
import * as THREE from "three";
|
||||||
|
|
||||||
type Ring0Props = {
|
type GrayRingProps = {
|
||||||
lowerRingPositionY: number;
|
lowerRingPositionY: number;
|
||||||
lowerRingRotationY: number;
|
lowerRingRotationY: number;
|
||||||
};
|
};
|
||||||
|
@ -24,7 +24,7 @@ type GLTFResult = GLTF & {
|
||||||
materials: {};
|
materials: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const Ring0 = (props: any) => {
|
const GrayRing = (props: any) => {
|
||||||
const { nodes, materials } = useLoader<GLTFResult>(
|
const { nodes, materials } = useLoader<GLTFResult>(
|
||||||
GLTFLoader,
|
GLTFLoader,
|
||||||
"/models/ring0.glb",
|
"/models/ring0.glb",
|
||||||
|
@ -48,4 +48,4 @@ const Ring0 = (props: any) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Ring0;
|
export default GrayRing;
|
|
@ -1,13 +1,29 @@
|
||||||
import React, { Suspense } from "react";
|
import React, { Suspense } from "react";
|
||||||
import Ring0 from "./Ring0";
|
import GrayRing from "./GrayRing";
|
||||||
import Ring1 from "./Ring1";
|
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)?];
|
||||||
|
|
||||||
const Hub = (props: any) => {
|
const Hub = (props: any) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Suspense fallback={<>loading...</>}>
|
<Suspense fallback={<>loading...</>}>
|
||||||
<Ring1 />
|
<PurpleRing />
|
||||||
<Ring0 />
|
<GrayRing />
|
||||||
|
{Object.values(level_sprites.level04).map((sprite) => {
|
||||||
|
return (
|
||||||
|
<LevelSprite
|
||||||
|
position={sprite.position as PositionAndScaleProps}
|
||||||
|
scale={sprite.scale as PositionAndScaleProps}
|
||||||
|
rotation={sprite.rotation as RotationProps}
|
||||||
|
sprite={sprite.sprite}
|
||||||
|
key={sprite.id}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -41,9 +41,7 @@ const LainConstructor = (props: LainConstructorProps) => {
|
||||||
animator.animate();
|
animator.animate();
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return <spriteMaterial attach="material" map={spriteTexture} />;
|
||||||
<spriteMaterial attach="material" map={spriteTexture}></spriteMaterial>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LainIntro = () => {
|
export const LainIntro = () => {
|
||||||
|
@ -115,7 +113,7 @@ export const LainMoveUp = () => {
|
||||||
const Lain = (props: LainProps) => {
|
const Lain = (props: LainProps) => {
|
||||||
return (
|
return (
|
||||||
<Suspense fallback={<>loading...</>}>
|
<Suspense fallback={<>loading...</>}>
|
||||||
<sprite position={[0.1, props.lainPosY, 0]} scale={[4.3, 4.3, 4.3]}>
|
<sprite position={[0.1, props.lainPosY, 0]} scale={[4.9, 4.9, 4.9]}>
|
||||||
{props.isLainMoving ? props.lainMoveState : <LainStanding />}
|
{props.isLainMoving ? props.lainMoveState : <LainStanding />}
|
||||||
</sprite>
|
</sprite>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
|
|
54
src/components/LevelSprite.tsx
Normal file
54
src/components/LevelSprite.tsx
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import React, { Suspense } from "react";
|
||||||
|
import { useFrame, useLoader, useThree } from "react-three-fiber";
|
||||||
|
import * as THREE from "three";
|
||||||
|
import movie from "../static/sprites/movie.png";
|
||||||
|
import touko from "../static/sprites/touko.png";
|
||||||
|
import s from "../static/sprites/s.png";
|
||||||
|
import copland from "../static/sprites/copland.png";
|
||||||
|
|
||||||
|
type LevelSpriteConstructorProps = {
|
||||||
|
sprite: string;
|
||||||
|
position: [number, number, number];
|
||||||
|
scale: [number, number, number];
|
||||||
|
rotation: [number, number, number, (string | undefined)?];
|
||||||
|
};
|
||||||
|
|
||||||
|
type SpriteToPath = {
|
||||||
|
[key: string]: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LevelSprite = (props: LevelSpriteConstructorProps) => {
|
||||||
|
// 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
|
||||||
|
// (yes, imbad at naming them)
|
||||||
|
const spriteToPath = (sprite: string) => {
|
||||||
|
return ({
|
||||||
|
movie: movie,
|
||||||
|
touko: touko,
|
||||||
|
s: s,
|
||||||
|
copland: copland,
|
||||||
|
} as SpriteToPath)[sprite];
|
||||||
|
};
|
||||||
|
|
||||||
|
const spriteTexture: any = useLoader(THREE.TextureLoader, spriteToPath(props.sprite));
|
||||||
|
|
||||||
|
return (
|
||||||
|
<mesh
|
||||||
|
position={props.position}
|
||||||
|
scale={props.scale}
|
||||||
|
rotation={props.rotation}
|
||||||
|
>
|
||||||
|
<planeBufferGeometry attach="geometry" />
|
||||||
|
<meshStandardMaterial
|
||||||
|
side={THREE.DoubleSide}
|
||||||
|
attach="material"
|
||||||
|
map={spriteTexture}
|
||||||
|
transparent={true}
|
||||||
|
/>
|
||||||
|
</mesh>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LevelSprite;
|
|
@ -11,7 +11,7 @@ type GLTFResult = GLTF & {
|
||||||
materials: {};
|
materials: {};
|
||||||
};
|
};
|
||||||
|
|
||||||
const Ring1 = (props: JSX.IntrinsicElements["group"]) => {
|
const PurpleRing = (props: JSX.IntrinsicElements["group"]) => {
|
||||||
const [higherRingRotation, setHigherRingRotation] = useState(0);
|
const [higherRingRotation, setHigherRingRotation] = useState(0);
|
||||||
|
|
||||||
const { nodes, materials } = useLoader<GLTFResult>(
|
const { nodes, materials } = useLoader<GLTFResult>(
|
||||||
|
@ -20,12 +20,12 @@ const Ring1 = (props: JSX.IntrinsicElements["group"]) => {
|
||||||
draco("/draco-gltf/")
|
draco("/draco-gltf/")
|
||||||
);
|
);
|
||||||
|
|
||||||
const ring1PermaRotation = () => {
|
const purpleRingPermaRotation = () => {
|
||||||
setHigherRingRotation((prev) => prev + 0.002);
|
setHigherRingRotation((prev) => prev + 0.002);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInterval(ring1PermaRotation, 1);
|
setInterval(purpleRingPermaRotation, 1);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -46,4 +46,4 @@ const Ring1 = (props: JSX.IntrinsicElements["group"]) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Ring1;
|
export default PurpleRing;
|
32
src/resources/level_sprites.json
Normal file
32
src/resources/level_sprites.json
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"level04": {
|
||||||
|
"0": {
|
||||||
|
"position": [0.4, -0.25, 1.3],
|
||||||
|
"scale": [0.25, 0.15, 0.25],
|
||||||
|
"rotation": [0, 0.2, 0],
|
||||||
|
"sprite": "movie",
|
||||||
|
"id": "040"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"position": [0.4, 0, 1.3],
|
||||||
|
"scale": [0.25, 0.15, 0.25],
|
||||||
|
"rotation": [0, 0.09, 0],
|
||||||
|
"sprite": "s",
|
||||||
|
"id": "041"
|
||||||
|
},
|
||||||
|
"2": {
|
||||||
|
"position": [-0.35, 0, 1.3],
|
||||||
|
"scale": [0.25, 0.15, 0.25],
|
||||||
|
"rotation": [0, -0.1, 0],
|
||||||
|
"sprite": "copland",
|
||||||
|
"id": "042"
|
||||||
|
},
|
||||||
|
"3": {
|
||||||
|
"position": [-0.35, 0.25, 1.3],
|
||||||
|
"scale": [0.25, 0.15, 0.25],
|
||||||
|
"rotation": [0, -0.1, 0],
|
||||||
|
"sprite": "touko",
|
||||||
|
"id": "043"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue