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"
+ }
+ }
+}