From 877a15662b9f4253bb85c747a503338a1f5a3787 Mon Sep 17 00:00:00 2001 From: Marco Date: Thu, 3 Dec 2020 12:20:15 +0100 Subject: [PATCH] implement saving and loading for Pong --- .../pong/src/app/frame-transition-handlers.ts | 2 +- examples/pong/src/main.ts | 10 +++--- .../pong/src/{app => models}/game-store.ts | 1 + examples/pong/src/prefabs/menu.ts | 13 ++++++- examples/pong/src/states/game.ts | 12 +++++-- examples/pong/src/states/pause.ts | 5 ++- examples/pong/src/states/score-board.ts | 2 +- examples/pong/src/systems/ball.ts | 2 +- examples/pong/src/systems/input.ts | 2 +- examples/pong/src/systems/menu.ts | 34 ++++++++++++++++--- examples/pong/src/systems/paddle.ts | 2 +- examples/pong/src/systems/pause.ts | 2 +- examples/pong/src/systems/score-board.ts | 2 +- examples/pong/src/systems/score.ts | 2 +- 14 files changed, 70 insertions(+), 21 deletions(-) rename examples/pong/src/{app => models}/game-store.ts (97%) diff --git a/examples/pong/src/app/frame-transition-handlers.ts b/examples/pong/src/app/frame-transition-handlers.ts index 6c16020..1fa99fd 100644 --- a/examples/pong/src/app/frame-transition-handlers.ts +++ b/examples/pong/src/app/frame-transition-handlers.ts @@ -1,4 +1,4 @@ -import {GameStore} from "./game-store"; +import {GameStore} from "../models/game-store"; import {ITransitionActions} from "../ecs"; import {MenuState} from "../states/menu"; diff --git a/examples/pong/src/main.ts b/examples/pong/src/main.ts index 81373ec..afebd50 100644 --- a/examples/pong/src/main.ts +++ b/examples/pong/src/main.ts @@ -2,7 +2,7 @@ import {ECS, IWorld} from "./ecs"; import {PaddleSystem} from "./systems/paddle"; import {afterFrameHandler, beforeFrameHandler} from "./app/frame-transition-handlers"; import {InputSystem} from "./systems/input"; -import {GameStore} from "./app/game-store"; +import {GameStore} from "./models/game-store"; import {MenuState} from "./states/menu"; import {UIItem} from "./components/ui-item"; import {MenuSystem} from "./systems/menu"; @@ -15,6 +15,7 @@ import {BallSystem} from "./systems/ball"; import {ScoreSystem} from "./systems/score"; import {GameItem} from "./components/game-item"; import {ScoreBoardSystem} from "./systems/score-board"; +import {Direction} from "./components/direction"; const cleanup = () => { @@ -37,10 +38,11 @@ const createWorld = () => { .withSystem(MenuSystem, [InputSystem]) .withSystem(PaddleSystem, [InputSystem]) .withSystem(PauseSystem, [InputSystem]) - .withSystem(ScoreBoardSystem) // todo: throw if a system was not registered but is supposed to run + .withSystem(ScoreBoardSystem) .withSystem(ScoreSystem, [InputSystem]) - .withComponents([ + .withComponents( Ball, + Direction, GameItem, MenuItem, Paddle, @@ -48,7 +50,7 @@ const createWorld = () => { Position, ScoreItem, UIItem, - ]) + ) .build(); }; diff --git a/examples/pong/src/app/game-store.ts b/examples/pong/src/models/game-store.ts similarity index 97% rename from examples/pong/src/app/game-store.ts rename to examples/pong/src/models/game-store.ts index b6783f7..d795684 100644 --- a/examples/pong/src/app/game-store.ts +++ b/examples/pong/src/models/game-store.ts @@ -9,6 +9,7 @@ export enum EMovement { export class GameStore { backToMenu = false + continue = false ctx!: CanvasRenderingContext2D currentState?: IState exit = false diff --git a/examples/pong/src/prefabs/menu.ts b/examples/pong/src/prefabs/menu.ts index d07e29b..263e146 100644 --- a/examples/pong/src/prefabs/menu.ts +++ b/examples/pong/src/prefabs/menu.ts @@ -44,6 +44,17 @@ export const menuPrefab: TPrefab = [ top: 270, }, }, + { + MenuItem: {}, + UIItem: { + action: EActions.Continue, + color: '#ddd', + caption: 'Continue', + fontSize: 32, + left: 120, + top: 320, + }, + }, { MenuItem: {}, UIItem: { @@ -52,7 +63,7 @@ export const menuPrefab: TPrefab = [ caption: 'Exit', fontSize: 32, left: 120, - top: 320, + top: 370, }, }, ]; diff --git a/examples/pong/src/states/game.ts b/examples/pong/src/states/game.ts index dea0b68..d6d1760 100644 --- a/examples/pong/src/states/game.ts +++ b/examples/pong/src/states/game.ts @@ -1,4 +1,4 @@ -import {ITransitionActions, State, TPrefabHandle, With} from "../ecs"; +import {ECS, ITransitionActions, State, TPrefabHandle, With} from "../ecs"; import {InputSystem} from "../systems/input"; import {PauseSystem} from "../systems/pause"; import {PaddleSystem} from "../systems/paddle"; @@ -6,7 +6,7 @@ import {gamePrefab} from "../prefabs/game"; import {Paddle} from "../components/paddle"; import {Position} from "../components/position"; import {Ball} from "../components/ball"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; import {BallSystem} from "../systems/ball"; import {Direction} from "../components/direction"; import {ScoreSystem} from "../systems/score"; @@ -18,6 +18,14 @@ export class GameState extends State { create(actions: ITransitionActions) { const gameStore = actions.getResource(GameStore); + if (gameStore.continue) { + actions.fromJSON(localStorage.getItem('save')!); + actions.maintain(); + actions.getResource(GameStore).pointsLeft = parseInt(localStorage.getItem('savePointsLeft')!); + actions.getResource(GameStore).pointsRight = parseInt(localStorage.getItem('savePointsRight')!); + return; + } + this.prefabHandle = actions.loadPrefab(gamePrefab); for (const entity of actions.getEntities([With(Paddle)])) { entity.addComponent(new Position()); diff --git a/examples/pong/src/states/pause.ts b/examples/pong/src/states/pause.ts index d742797..3c95aed 100644 --- a/examples/pong/src/states/pause.ts +++ b/examples/pong/src/states/pause.ts @@ -3,7 +3,7 @@ import {InputSystem} from "../systems/input"; import {PauseSystem} from "../systems/pause"; import {pausePrefab} from "../prefabs/pause"; import {PaddleSystem} from "../systems/paddle"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; import {BallSystem} from "../systems/ball"; export class PauseState extends State { @@ -13,6 +13,9 @@ export class PauseState extends State { activate(actions: ITransitionActions): void | Promise { actions.getResource(GameStore).pause = true; + localStorage.setItem('save', actions.toJSON()); + localStorage.setItem('savePointsLeft', actions.getResource(GameStore).pointsLeft.toString()); + localStorage.setItem('savePointsRight', actions.getResource(GameStore).pointsRight.toString()); } create(actions: ITransitionActions) { diff --git a/examples/pong/src/states/score-board.ts b/examples/pong/src/states/score-board.ts index 3fc8c9f..6d50e40 100644 --- a/examples/pong/src/states/score-board.ts +++ b/examples/pong/src/states/score-board.ts @@ -2,7 +2,7 @@ import {ITransitionActions, State, TPrefabHandle, With} from "../ecs"; import {scorePrefab} from "../prefabs/score"; import {ScoreItem} from "../components/_markers"; import {UIItem} from "../components/ui-item"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; import {ScoreBoardSystem} from "../systems/score-board"; export class ScoreBoardState extends State { diff --git a/examples/pong/src/systems/ball.ts b/examples/pong/src/systems/ball.ts index 054a7dd..a7b87dc 100644 --- a/examples/pong/src/systems/ball.ts +++ b/examples/pong/src/systems/ball.ts @@ -1,5 +1,5 @@ import {ISystemActions, Read, System, SystemData, Write} from "../ecs"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; import {Position} from "../components/position"; import {Ball} from "../components/ball"; import {Direction} from "../components/direction"; diff --git a/examples/pong/src/systems/input.ts b/examples/pong/src/systems/input.ts index b97d80d..1b0ff86 100644 --- a/examples/pong/src/systems/input.ts +++ b/examples/pong/src/systems/input.ts @@ -1,5 +1,5 @@ import {ISystemActions, NoData, System} from "../ecs"; -import {EMovement, GameStore} from "../app/game-store"; +import {EMovement, GameStore} from "../models/game-store"; export enum EKeyState { Down, diff --git a/examples/pong/src/systems/menu.ts b/examples/pong/src/systems/menu.ts index 399e01f..41304da 100644 --- a/examples/pong/src/systems/menu.ts +++ b/examples/pong/src/systems/menu.ts @@ -1,6 +1,6 @@ import {ISystemActions, Read, System, SystemData, With} from "../ecs"; import {UIItem} from "../components/ui-item"; -import {EMovement, GameStore} from "../app/game-store"; +import {EMovement, GameStore} from "../models/game-store"; import {EActions} from "../app/actions"; import {GameState} from "../states/game"; import {MenuItem} from "../components/_markers"; @@ -20,10 +20,26 @@ export class MenuSystem extends System { } run(dataSet: Set) { - if (this.gameStore.input.actions.menuMovement != EMovement.halt) { - this.menuAction = this.menuAction == EActions.Play - ? EActions.Exit - : EActions.Play; + // todo: use index + if (this.gameStore.input.actions.menuMovement == EMovement.down) { + switch (this.menuAction) { + case EActions.Play: this.menuAction = EActions.Continue; break; + case EActions.Continue: this.menuAction = EActions.Exit; break; + case EActions.Exit: this.menuAction = EActions.Play; break; + default: { + throw new Error(`Action ${this.menuAction} not implemented!`); + } + } + } + else if (this.gameStore.input.actions.menuMovement == EMovement.up) { + switch (this.menuAction) { + case EActions.Play: this.menuAction = EActions.Exit; break; + case EActions.Continue: this.menuAction = EActions.Play; break; + case EActions.Exit: this.menuAction = EActions.Continue; break; + default: { + throw new Error(`Action ${this.menuAction} not implemented!`); + } + } } for (const {uiItem} of dataSet) { @@ -34,6 +50,14 @@ export class MenuSystem extends System { if (this.menuAction == EActions.Play) { this.gameStore.PushState = GameState; } + else if (this.menuAction == EActions.Continue) { + if (localStorage.getItem('save') == null) { + return; + } + + this.gameStore.continue = true; + this.gameStore.PushState = GameState; + } else { this.gameStore.exit = true; } diff --git a/examples/pong/src/systems/paddle.ts b/examples/pong/src/systems/paddle.ts index 226fd3d..d8cdf97 100644 --- a/examples/pong/src/systems/paddle.ts +++ b/examples/pong/src/systems/paddle.ts @@ -1,5 +1,5 @@ import {ISystemActions, Read, System, SystemData, Write} from "../ecs"; -import {EMovement, GameStore} from "../app/game-store"; +import {EMovement, GameStore} from "../models/game-store"; import {EPaddleSide, Paddle} from "../components/paddle"; import {Position} from "../components/position"; diff --git a/examples/pong/src/systems/pause.ts b/examples/pong/src/systems/pause.ts index 157b1d7..1872046 100644 --- a/examples/pong/src/systems/pause.ts +++ b/examples/pong/src/systems/pause.ts @@ -1,5 +1,5 @@ import {ISystemActions, Read, System, SystemData, With} from "../ecs"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; import {GameState} from "../states/game"; import {PauseState} from "../states/pause"; import {PauseItem} from "../components/_markers"; diff --git a/examples/pong/src/systems/score-board.ts b/examples/pong/src/systems/score-board.ts index d950844..c1af865 100644 --- a/examples/pong/src/systems/score-board.ts +++ b/examples/pong/src/systems/score-board.ts @@ -1,7 +1,7 @@ import {ISystemActions, Read, System, SystemData, With} from "../ecs"; import {ScoreItem} from "../components/_markers"; import {UIItem} from "../components/ui-item"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; export class Data extends SystemData { _scoreItem = With(ScoreItem) diff --git a/examples/pong/src/systems/score.ts b/examples/pong/src/systems/score.ts index 49e550f..05571c6 100644 --- a/examples/pong/src/systems/score.ts +++ b/examples/pong/src/systems/score.ts @@ -3,7 +3,7 @@ import {Position} from "../components/position"; import {Ball} from "../components/ball"; import {Direction} from "../components/direction"; import {EPaddleSide, Paddle} from "../components/paddle"; -import {GameStore} from "../app/game-store"; +import {GameStore} from "../models/game-store"; import {ScoreBoardState} from "../states/score-board"; import {GameItem} from "../components/game-item";