Scene switching powered by Redux!
This commit is contained in:
parent
efb127dedd
commit
0b30af51c8
11 changed files with 58 additions and 46 deletions
|
@ -1,32 +1,16 @@
|
|||
import React, { Fragment } from "react";
|
||||
import useLoader from "~game/lib/Loader";
|
||||
import InGameSpaceBG from "./backgrounds/InGameSpaceBG";
|
||||
|
||||
// Resources, this will make TS go crazy!
|
||||
|
||||
//@ts-expect-error Image resource
|
||||
import NoiseSpaceFine from "~/../assets/images/noise/space_fine.png";
|
||||
//@ts-expect-error Image resource
|
||||
import NoiseSpaceSparse from "~/../assets/images/noise/space_sparse.png";
|
||||
import { useSelector } from "react-redux";
|
||||
import { SceneStore } from "~store/scene/reducer";
|
||||
import { GameStore } from "~store/state";
|
||||
import MapEditor from "~game/scenes/MapEditor";
|
||||
|
||||
export default function Game() {
|
||||
const { loaded, resources } = useLoader({
|
||||
bg_fine: NoiseSpaceFine,
|
||||
bg_sparse: NoiseSpaceSparse,
|
||||
});
|
||||
|
||||
if (!loaded) {
|
||||
const scene = useSelector<GameStore, SceneStore>((state) => state.scene);
|
||||
switch (scene.type) {
|
||||
case "MapEditor":
|
||||
return <MapEditor />;
|
||||
default:
|
||||
// Bad case, should have something to show just in case!
|
||||
return <Fragment></Fragment>;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<InGameSpaceBG
|
||||
textures={{
|
||||
noise_fine: resources.bg_fine,
|
||||
noise_sparse: resources.bg_sparse,
|
||||
}}
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,11 @@ import NoiseSpaceSparse from "~/../assets/images/noise/space_sparse.png";
|
|||
import LoadingScreen from "./LoadingScreen";
|
||||
import useUILayer from "~ui/utils/useLayer";
|
||||
|
||||
// Scene switcher entry
|
||||
export interface MapEditorScene {
|
||||
type: "MapEditor";
|
||||
}
|
||||
|
||||
export default function MapEditor() {
|
||||
const { loaded, resources } = useLoader({
|
||||
bg_fine: NoiseSpaceFine,
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Stage } from "@inlet/react-pixi";
|
|||
import { configureStore } from "@reduxjs/toolkit";
|
||||
import UI from "~ui/UI";
|
||||
import reducer from "~store/reducer";
|
||||
import MapEditor from "~game/scenes/MapEditor";
|
||||
import Game from "~game/scenes/Game";
|
||||
|
||||
PIXI.settings.SCALE_MODE = PIXI.SCALE_MODES.NEAREST;
|
||||
|
||||
|
@ -23,7 +23,7 @@ ReactDOM.render(
|
|||
<React.Fragment>
|
||||
<Stage options={{ resolution: 1, resizeTo: window }} onMount={mounted}>
|
||||
<Provider store={store}>
|
||||
<MapEditor />
|
||||
<Game />
|
||||
</Provider>
|
||||
</Stage>
|
||||
<Provider store={store}>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { combineReducers } from "@reduxjs/toolkit";
|
||||
import uiReducer from "./ui/reducer";
|
||||
import sceneReducer from "./scene/reducer";
|
||||
|
||||
const reducer = combineReducers({ ui: uiReducer });
|
||||
const reducer = combineReducers({ ui: uiReducer, scene: sceneReducer });
|
||||
|
||||
export default reducer;
|
||||
|
|
17
src/store/scene/reducer.ts
Normal file
17
src/store/scene/reducer.ts
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { MapEditorScene } from "~game/scenes/MapEditor";
|
||||
|
||||
export type SceneStore = MapEditorScene;
|
||||
|
||||
const initialState: SceneStore = {
|
||||
type: "MapEditor",
|
||||
};
|
||||
|
||||
const sceneSlice = createSlice({
|
||||
name: "scene",
|
||||
initialState,
|
||||
reducers: {},
|
||||
});
|
||||
|
||||
export const {} = sceneSlice.actions;
|
||||
export default sceneSlice.reducer;
|
|
@ -1,5 +1,7 @@
|
|||
import { SceneStore } from "./scene/reducer";
|
||||
import UIStore from "./ui/state";
|
||||
|
||||
export interface GameStore {
|
||||
ui: UIStore;
|
||||
scene: SceneStore;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { UILayer } from "~ui/UI";
|
||||
import UIStore from "./state";
|
||||
import UIStore, { UILayer } from "./state";
|
||||
|
||||
const initialState: UIStore = {
|
||||
layers: [],
|
||||
|
@ -38,7 +37,8 @@ const uiSlice = createSlice({
|
|||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
state.layers[index].visible = true;
|
||||
|
||||
state.layers[index] = { ...state.layers[index], visible: true };
|
||||
},
|
||||
hideLayer(state, action: PayloadAction<LayerActionPayload>) {
|
||||
const index = state.layers.findIndex(
|
||||
|
@ -47,7 +47,7 @@ const uiSlice = createSlice({
|
|||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
state.layers[index].visible = false;
|
||||
state.layers[index] = { ...state.layers[index], visible: false };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { LayerList } from "~ui/UI";
|
||||
import { MapEditorLayer } from "~ui/MapEditor";
|
||||
|
||||
export type UILayer = MapEditorLayer;
|
||||
|
||||
export type LayerList = { id: string; data: UILayer; visible: boolean }[];
|
||||
|
||||
export default interface UIStore {
|
||||
layers: LayerList;
|
||||
|
|
|
@ -4,7 +4,7 @@ export interface MapEditorLayer {
|
|||
type: "MapEditor";
|
||||
}
|
||||
|
||||
export default function MapEditor() {
|
||||
export default function MapEditorUI() {
|
||||
return (
|
||||
<div>
|
||||
<p>HEY HEY</p>
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import React from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { GameStore } from "~store/state";
|
||||
import MapEditor, { MapEditorLayer } from "./MapEditor";
|
||||
|
||||
export type UILayer = MapEditorLayer;
|
||||
|
||||
export type LayerList = { id: string; data: UILayer; visible: boolean }[];
|
||||
import { UILayer, LayerList } from "~store/ui/state";
|
||||
import MapEditorUI from "./MapEditor";
|
||||
|
||||
function renderLayer(data: UILayer) {
|
||||
switch (data.type) {
|
||||
case "MapEditor":
|
||||
return <MapEditor />;
|
||||
return <MapEditorUI />;
|
||||
default:
|
||||
throw new Error("unknown or invalid ui layer");
|
||||
}
|
||||
|
@ -20,8 +17,10 @@ export default function UI() {
|
|||
const layers = useSelector<GameStore, LayerList>((state) => state.ui.layers);
|
||||
return (
|
||||
<div id="ui">
|
||||
{layers.map(({ id, data }) => (
|
||||
<div key={id}>{renderLayer(data)}</div>
|
||||
{layers.map(({ id, data, visible }) => (
|
||||
<div key={id} style={{ display: visible ? "" : "none" }}>
|
||||
{renderLayer(data)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { useDispatch } from "react-redux";
|
||||
import { UILayer } from "~ui/UI";
|
||||
import { addLayer, removeLayer, showLayer, hideLayer } from "~store/ui/reducer";
|
||||
import { UILayer } from "~store/ui/state";
|
||||
|
||||
export default function useUILayer(data: UILayer, show: boolean) {
|
||||
const dispatch = useDispatch();
|
||||
const id = data.type + "-" + Math.random().toString(32).slice(2);
|
||||
|
||||
const [id] = useState(data.type + "-" + Math.random().toString(32).slice(2));
|
||||
const [visible, setVisible] = useState(show);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
Reference in a new issue