All files / games/roguelike/src/game game.ts

100% Statements 41/41
100% Branches 2/2
100% Functions 9/9
100% Lines 41/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124  10x 10x 10x 10x 10x 10x 10x 10x     5x 5x 5x   5x 5x 5x 5x         5x 5x 5x                           1x     42x     13x 13x 13x 13x 13x     5x   5x 15x 15x 15x 10x         10x   15x     5x     28x 28x     10x   5x 5x 5x 5x                                                                                      
import { CellularMapGenerator, GameMap } from "jga-games-maps";
 
import { Display, DisplayInterface } from "jga-games-display";
 
import { World, Scheduler } from "jga-games-engine";
 
import { Keys } from "jga-games-commands";
 
import { ScreenInterface } from "jga-games-screens";
 
import { TileFactory } from "jga-games-tiles";
 
import { CommandManager } from "jga-patterns-command";
 
import { ScreenFactoryCreateParamsInterface, ScreenFactory } from "./index";
 
export interface GameInterface {
    getCurrentScreen(): ScreenInterface;
    getDisplay(): DisplayInterface;
    switchScreen(screen: ScreenInterface): void;
}
 
export class Game implements GameInterface {
    protected display: DisplayInterface;
    protected currentScreen: ScreenInterface;
    protected screenFactory: ScreenFactory;
    protected engine: World;
 
    private screenHeight = 24;
    private screenWidth = 80;
 
    public constructor() {
        this.engine = new World(new Scheduler(), createMap(), new CommandManager());
 
        // Create player;
        this.engine.createPlayer();
 
        this.display = new Display(this.screenHeight, this.screenWidth);
        this.screenFactory = new ScreenFactory();
 
        const createParams: ScreenFactoryCreateParamsInterface = {
            engine: this.engine,
            type: "start",
            display: this.display,
        };
 
        this.currentScreen = this.screenFactory.create(createParams);
        this.currentScreen.render();
 
        this.init();
    }
 
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    // public handleInput(eventName: string, event: KeyboardEvent): any {
    //     return (e: KeyboardEvent): void => {
    //         const newScreenName = this.currentScreen.handleInput(event, { code: e.code });
    //         if (null !== newScreenName) {
    //             const newScreen = this.screenFactory.create({ type: newScreenName, engine: this.engine });
    //             this.switchScreen(newScreen);
    //         }
    //         this.currentScreen.render();
    //     };
    // }
 
    public getCurrentScreen(): ScreenInterface {
        return this.currentScreen;
    }
 
    public getDisplay(): DisplayInterface {
        return this.display;
    }
 
    public switchScreen(screen: ScreenInterface): void {
        this.currentScreen.exit();
        this.getDisplay().clear();
 
        this.currentScreen = screen;
 
        this.currentScreen.enter();
        this.refresh();
    }
 
    private init(): void {
        const bindEventToScreen = (eventName: string): void => {
            // @TODO refactor to external method
            window.addEventListener(eventName, (event) => {
                const inputEvent: KeyboardEvent = event as KeyboardEvent;
                const newScreenName = this.currentScreen.handleInput(eventName, { code: inputEvent.code as Keys });
 
                if (null !== newScreenName) {
                    const newScreen = this.screenFactory.create({
                        type: newScreenName,
                        engine: this.engine,
                        display: this.display,
                    });
                    this.switchScreen(newScreen);
                }
                this.refresh();
            });
        };
 
        bindEventToScreen("keydown");
    }
 
    private refresh(): void {
        this.getDisplay().clear();
        this.currentScreen.render();
    }
}
 
function createMap(): GameMap {
    const mapWidth = 80;
    const mapHeight = 60;
 
    const generator = new CellularMapGenerator(mapWidth, mapHeight, new TileFactory());
 
    return new GameMap({
        generator,
        height: mapHeight,
        tileFactory: new TileFactory(),
        width: mapWidth,
    });
}