adding level selection

This commit is contained in:
ad044 2020-11-27 19:22:19 +04:00
parent 46d9c421c8
commit 00de2883a8
7 changed files with 205 additions and 30 deletions

View file

@ -0,0 +1,152 @@
import React, { useCallback, useEffect, useMemo } from "react";
import level_selection_font from "../../static/sprite/select_level_font.png";
import verticalHud from "../../static/sprite/select_level_hud_vertical.png";
import horizontalHud from "../../static/sprite/select_level_hud_horizontal.png";
import levelSelectionText from "../../static/sprite/select_level_text.png";
import upArrow from "../../static/sprite/select_level_up_arrow.png";
import downArrow from "../../static/sprite/select_level_down_arrow.png";
import { useLevelSelectionStore } from "../../store";
import { useLoader } from "react-three-fiber";
import * as THREE from "three";
import { a, useSpring } from "@react-spring/three";
const LevelSelection = () => {
const levelSelectionFontTex = useLoader(
THREE.TextureLoader,
level_selection_font
);
const verticalHudTex = useLoader(THREE.TextureLoader, verticalHud);
const horizontalHudTex = useLoader(THREE.TextureLoader, horizontalHud);
const levelSelectionTextTex = useLoader(
THREE.TextureLoader,
levelSelectionText
);
const upArrowTex = useLoader(THREE.TextureLoader, upArrow);
const downArrowTex = useLoader(THREE.TextureLoader, downArrow);
const selectedLevelIdx = useLevelSelectionStore(
(state) => state.selectedLevelIdx
);
const selectedLevel = useLevelSelectionStore(
useCallback((state) => state.availableLevels[selectedLevelIdx], [
selectedLevelIdx,
])
)
.toString()
.padStart(2, "0");
const levelSelectionToggled = useLevelSelectionStore(
(state) => state.levelSelectionToggled
);
const { levelSelectionToggle } = useSpring({
levelSelectionToggle: levelSelectionToggled,
config: { duration: 500 },
});
const verticalHudPosY = levelSelectionToggle.to([0, 1], [-2.5, 0]);
const horizontalHudPosX = levelSelectionToggle.to([0, 1], [-4, -0.6]);
const generateGeom = useCallback((number: number) => {
const geometry = new THREE.PlaneBufferGeometry();
const uvAttribute = geometry.attributes.uv;
for (let i = 0; i < uvAttribute.count; i++) {
let u = uvAttribute.getX(i);
let v = uvAttribute.getY(i);
u = (u * 22) / 240 + number / 10;
uvAttribute.setXY(i, u, v);
}
return geometry;
}, []);
return (
<>
<a.group position-y={verticalHudPosY} renderOrder={5}>
<mesh
scale={[0.3, 0.4, 0]}
position={[0.95, 0, 0]}
renderOrder={5}
geometry={generateGeom(parseInt(selectedLevel[0]))}
>
<meshBasicMaterial
map={levelSelectionFontTex}
attach="material"
transparent={true}
depthTest={false}
/>
</mesh>
<mesh
scale={[0.3, 0.4, 0]}
position={[1.23, 0, 0]}
renderOrder={5}
geometry={generateGeom(parseInt(selectedLevel[1]))}
>
<meshBasicMaterial
map={levelSelectionFontTex}
attach="material"
transparent={true}
depthTest={false}
/>
</mesh>
<sprite scale={[0.65, 3, 0]} position={[1.1, -0.8, 0]} renderOrder={4}>
<spriteMaterial
map={verticalHudTex}
attach="material"
transparent={true}
depthTest={false}
/>
</sprite>
<sprite scale={[0.5, 0.12, 0]} position={[1.1, 0.3, 0]} renderOrder={4}>
<spriteMaterial
map={levelSelectionTextTex}
attach="material"
transparent={true}
depthTest={false}
/>
</sprite>
<sprite
scale={[0.3, 0.15, 0]}
position={[1.1, -0.35, 0]}
renderOrder={4}
>
<spriteMaterial
map={downArrowTex}
attach="material"
transparent={true}
depthTest={false}
/>
</sprite>
<sprite scale={[0.3, 0.15, 0]} position={[1.1, 0.5, 0]} renderOrder={4}>
<spriteMaterial
map={upArrowTex}
attach="material"
transparent={true}
depthTest={false}
/>
</sprite>
</a.group>
<a.sprite
scale={[3, 0.3, 0]}
position={[-0.6, 0, 0]}
renderOrder={4}
position-x={horizontalHudPosX}
>
<spriteMaterial
map={horizontalHudTex}
attach="material"
transparent={true}
depthTest={false}
/>
</a.sprite>
</>
);
};
export default LevelSelection;

View file

@ -1,14 +0,0 @@
import React, { memo } from "react";
const Lights = memo(() => {
return (
<>
<pointLight color={0xffffff} position={[0, 0, 7]} intensity={1} />
<pointLight color={0x7f7f7f} position={[0, 10, 0]} intensity={1.5} />
<pointLight color={0xffffff} position={[8, 0, 0]} intensity={0.2} />
<pointLight color={0xffffff} position={[-8, 0, 0]} intensity={0.2} />
</>
);
});
export default Lights;

View file

@ -37,6 +37,7 @@ const getKeyCodeAssociation = (keyCode: number): string => {
39: "right", // right arrow
88: "select", // x key
90: "back", // z key
69: "toggle_level_selection", // e key
};
return keyCodeAssocs[keyCode as keyof typeof keyCodeAssocs];
};

View file

@ -1,9 +1,12 @@
import { useCallback, useEffect } from "react";
import { StateManagerProps } from "./EventManager";
import { useLevelStore } from "../../store";
import { useLevelSelectionStore, useLevelStore } from "../../store";
const LevelManager = (props: StateManagerProps) => {
const setActiveLevel = useLevelStore((state) => state.setActiveLevel);
const toggleLevelSelection = useLevelSelectionStore(
(state) => state.toggleLevelSelection
);
const dispatchObject = useCallback(
(event: string, newLevel: string) => {
@ -14,9 +17,13 @@ const LevelManager = (props: StateManagerProps) => {
action: setActiveLevel,
value: newLevel,
};
case "toggle_level_selection":
return {
action: toggleLevelSelection,
};
}
},
[setActiveLevel]
[setActiveLevel, toggleLevelSelection]
);
useEffect(() => {
@ -26,7 +33,10 @@ const LevelManager = (props: StateManagerProps) => {
const dispatchedObject = dispatchObject(eventAction, newLevel);
if (dispatchedObject) {
dispatchedObject.action(dispatchedObject.value);
(dispatchedObject.action as any).apply(
null,
dispatchedObject.value as any
);
}
}
}, [props.eventState, dispatchObject]);

View file

@ -113,6 +113,9 @@ const handleMainSceneEvent = (gameContext: any) => {
newScene = "sskn";
break;
}
break;
case "toggle_level_selection":
return { event: "toggle_level_selection" };
}
const newActiveNodeId =

View file

@ -3,7 +3,6 @@ import { OrbitControls } from "@react-three/drei";
import React, { Suspense, useEffect } from "react";
import Site from "../components/MainScene/Site";
import Lain from "../components/MainScene/Lain";
import Lights from "../components/MainScene/Lights";
import Preloader from "../components/Preloader";
import MainSceneIntro from "../components/MainSceneIntro";
import GrayPlanes from "../components/MainScene/GrayPlanes";
@ -15,6 +14,7 @@ import HUD from "../components/MainScene/HUD";
import YellowOrb from "../components/MainScene/YellowOrb";
import ActiveLevelNodes from "../components/MainScene/ActiveLevelNodes";
import YellowTextRenderer from "../components/TextRenderer/YellowTextRenderer";
import LevelSelection from "../components/MainScene/LevelSelection";
const MainScene = () => {
const setLainMoveState = useLainStore((state) => state.setLainMoveState);
@ -30,18 +30,22 @@ const MainScene = () => {
<Suspense fallback={null}>
<MainSceneIntro />
<a.group>
<Preloader />
<Site />
<ActiveLevelNodes />
<HUD />
<TextRenderer />
<YellowTextRenderer />
<YellowOrb />
<Starfield />
<GrayPlanes />
<Lights />
<MiddleRing />
{/*<Preloader />*/}
{/*<Site />*/}
{/*<ActiveLevelNodes />*/}
{/*<HUD />*/}
{/*<TextRenderer />*/}
{/*<YellowTextRenderer />*/}
{/*<YellowOrb />*/}
{/*<Starfield />*/}
{/*<GrayPlanes />*/}
{/*<MiddleRing />*/}
<LevelSelection />
<OrbitControls />
<pointLight color={0xffffff} position={[0, 0, 7]} intensity={1} />
<pointLight color={0x7f7f7f} position={[0, 10, 0]} intensity={1.5} />
<pointLight color={0xffffff} position={[8, 0, 0]} intensity={0.2} />
<pointLight color={0xffffff} position={[-8, 0, 0]} intensity={0.2} />
</a.group>
<Lain />
</Suspense>

View file

@ -3,6 +3,14 @@ import { combine } from "zustand/middleware";
import * as THREE from "three";
import authorize_user_letters from "./resources/authorize_user_letters.json";
type LevelSelectionState = {
availableLevels: number[];
selectedLevelIdx: number;
levelSelectionToggled: number;
setSelectedLevelIdx: (to: number) => void;
toggleLevelSelection: () => void;
};
type SceneState = {
currentScene: string;
setScene: (to: string) => void;
@ -381,7 +389,7 @@ export const useSSknStore = create<SSknState>((set) => ({
}));
export const useSceneStore = create<SceneState>((set) => ({
currentScene: "polytan",
currentScene: "main",
setScene: (to) => set(() => ({ currentScene: to })),
}));
@ -457,3 +465,14 @@ export const useGateStore = create<GateState>((set) => ({
gateLvl: 4,
incrementGateLvl: () => set((state) => ({ gateLvl: state.gateLvl + 1 })),
}));
export const useLevelSelectionStore = create<LevelSelectionState>((set) => ({
availableLevels: Array.from({ length: 24 }, (x, i) => i + 1),
selectedLevelIdx: 23,
levelSelectionToggled: 0,
setSelectedLevelIdx: (to) => set(() => ({ selectedLevelIdx: to })),
toggleLevelSelection: () =>
set((state) => ({
levelSelectionToggled: Number(!state.levelSelectionToggled),
})),
}));