From 0b30af51c8a6031fb134d61ccd7a26a31324595a Mon Sep 17 00:00:00 2001 From: Hamcha Date: Tue, 29 Sep 2020 11:31:55 +0200 Subject: [PATCH] Scene switching powered by Redux! --- src/game/scenes/Game.tsx | 38 ++++++++++------------------------- src/game/scenes/MapEditor.tsx | 5 +++++ src/index.tsx | 4 ++-- src/store/reducer.ts | 3 ++- src/store/scene/reducer.ts | 17 ++++++++++++++++ src/store/state.ts | 2 ++ src/store/ui/reducer.ts | 8 ++++---- src/store/ui/state.ts | 6 +++++- src/ui/MapEditor.tsx | 2 +- src/ui/UI.tsx | 15 +++++++------- src/ui/utils/useLayer.ts | 4 ++-- 11 files changed, 58 insertions(+), 46 deletions(-) create mode 100644 src/store/scene/reducer.ts diff --git a/src/game/scenes/Game.tsx b/src/game/scenes/Game.tsx index 5fb1c6a..31e8849 100644 --- a/src/game/scenes/Game.tsx +++ b/src/game/scenes/Game.tsx @@ -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) { - return ; + const scene = useSelector((state) => state.scene); + switch (scene.type) { + case "MapEditor": + return ; + default: + // Bad case, should have something to show just in case! + return ; } - - return ( - - - - ); } diff --git a/src/game/scenes/MapEditor.tsx b/src/game/scenes/MapEditor.tsx index 023d186..d7f606c 100644 --- a/src/game/scenes/MapEditor.tsx +++ b/src/game/scenes/MapEditor.tsx @@ -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, diff --git a/src/index.tsx b/src/index.tsx index 88a5411..2c12b7a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -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( - + diff --git a/src/store/reducer.ts b/src/store/reducer.ts index 714c993..a3a1407 100644 --- a/src/store/reducer.ts +++ b/src/store/reducer.ts @@ -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; diff --git a/src/store/scene/reducer.ts b/src/store/scene/reducer.ts new file mode 100644 index 0000000..6e3d252 --- /dev/null +++ b/src/store/scene/reducer.ts @@ -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; diff --git a/src/store/state.ts b/src/store/state.ts index d3fa593..fb26be7 100644 --- a/src/store/state.ts +++ b/src/store/state.ts @@ -1,5 +1,7 @@ +import { SceneStore } from "./scene/reducer"; import UIStore from "./ui/state"; export interface GameStore { ui: UIStore; + scene: SceneStore; } diff --git a/src/store/ui/reducer.ts b/src/store/ui/reducer.ts index 6508b7c..b5d248b 100644 --- a/src/store/ui/reducer.ts +++ b/src/store/ui/reducer.ts @@ -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) { 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 }; }, }, }); diff --git a/src/store/ui/state.ts b/src/store/ui/state.ts index 8a8cd40..93b9c21 100644 --- a/src/store/ui/state.ts +++ b/src/store/ui/state.ts @@ -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; diff --git a/src/ui/MapEditor.tsx b/src/ui/MapEditor.tsx index 9206fb5..1fa9edb 100644 --- a/src/ui/MapEditor.tsx +++ b/src/ui/MapEditor.tsx @@ -4,7 +4,7 @@ export interface MapEditorLayer { type: "MapEditor"; } -export default function MapEditor() { +export default function MapEditorUI() { return (

HEY HEY

diff --git a/src/ui/UI.tsx b/src/ui/UI.tsx index 263580c..3ed0cff 100644 --- a/src/ui/UI.tsx +++ b/src/ui/UI.tsx @@ -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 ; + return ; default: throw new Error("unknown or invalid ui layer"); } @@ -20,8 +17,10 @@ export default function UI() { const layers = useSelector((state) => state.ui.layers); return (
- {layers.map(({ id, data }) => ( -
{renderLayer(data)}
+ {layers.map(({ id, data, visible }) => ( +
+ {renderLayer(data)} +
))}
); diff --git a/src/ui/utils/useLayer.ts b/src/ui/utils/useLayer.ts index f7e9d61..8665879 100644 --- a/src/ui/utils/useLayer.ts +++ b/src/ui/utils/useLayer.ts @@ -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(() => {