diff --git a/public/index.html b/public/index.html index d7dc60c..beed347 100644 --- a/public/index.html +++ b/public/index.html @@ -12,7 +12,10 @@ - +
diff --git a/src/components/Ring0.tsx b/src/components/GrayRing.tsx similarity index 92% rename from src/components/Ring0.tsx rename to src/components/GrayRing.tsx index be5fe91..6c59641 100644 --- a/src/components/Ring0.tsx +++ b/src/components/GrayRing.tsx @@ -12,7 +12,7 @@ import Lain from "./Lain"; import { Mesh, MeshLambertMaterial, DoubleSide } from "three"; import * as THREE from "three"; -type Ring0Props = { +type GrayRingProps = { lowerRingPositionY: number; lowerRingRotationY: number; }; @@ -24,7 +24,7 @@ type GLTFResult = GLTF & { materials: {}; }; -const Ring0 = (props: any) => { +const GrayRing = (props: any) => { const { nodes, materials } = useLoader( GLTFLoader, "/models/ring0.glb", @@ -48,4 +48,4 @@ const Ring0 = (props: any) => { ); }; -export default Ring0; +export default GrayRing; diff --git a/src/components/Hub.tsx b/src/components/Hub.tsx index bf2d3c7..c619df6 100644 --- a/src/components/Hub.tsx +++ b/src/components/Hub.tsx @@ -1,13 +1,29 @@ import React, { Suspense } from "react"; -import Ring0 from "./Ring0"; -import Ring1 from "./Ring1"; +import GrayRing from "./GrayRing"; +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) => { return ( <> loading...}> - - + + + {Object.values(level_sprites.level04).map((sprite) => { + return ( + + ); + })} ); diff --git a/src/components/Lain.tsx b/src/components/Lain.tsx index 2f387de..c285ac5 100644 --- a/src/components/Lain.tsx +++ b/src/components/Lain.tsx @@ -41,9 +41,7 @@ const LainConstructor = (props: LainConstructorProps) => { animator.animate(); }); - return ( - - ); + return ; }; export const LainIntro = () => { @@ -115,7 +113,7 @@ export const LainMoveUp = () => { const Lain = (props: LainProps) => { return ( loading...}> - + {props.isLainMoving ? props.lainMoveState : } diff --git a/src/components/LevelSprite.tsx b/src/components/LevelSprite.tsx new file mode 100644 index 0000000..0e0ac72 --- /dev/null +++ b/src/components/LevelSprite.tsx @@ -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 ( + + + + + ); +}; + +export default LevelSprite; diff --git a/src/components/Ring1.tsx b/src/components/PurpleRing.tsx similarity index 85% rename from src/components/Ring1.tsx rename to src/components/PurpleRing.tsx index c5df198..352d034 100644 --- a/src/components/Ring1.tsx +++ b/src/components/PurpleRing.tsx @@ -11,7 +11,7 @@ type GLTFResult = GLTF & { materials: {}; }; -const Ring1 = (props: JSX.IntrinsicElements["group"]) => { +const PurpleRing = (props: JSX.IntrinsicElements["group"]) => { const [higherRingRotation, setHigherRingRotation] = useState(0); const { nodes, materials } = useLoader( @@ -20,12 +20,12 @@ const Ring1 = (props: JSX.IntrinsicElements["group"]) => { draco("/draco-gltf/") ); - const ring1PermaRotation = () => { + const purpleRingPermaRotation = () => { setHigherRingRotation((prev) => prev + 0.002); }; useEffect(() => { - setInterval(ring1PermaRotation, 1); + setInterval(purpleRingPermaRotation, 1); }, []); return ( @@ -46,4 +46,4 @@ const Ring1 = (props: JSX.IntrinsicElements["group"]) => { ); }; -export default Ring1; +export default PurpleRing; diff --git a/src/resources/level_sprites.json b/src/resources/level_sprites.json new file mode 100644 index 0000000..afb7c6c --- /dev/null +++ b/src/resources/level_sprites.json @@ -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" + } + } +}