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

84.61% Statements 33/39
0% Branches 0/1
88.88% Functions 8/9
84.61% Lines 33/39

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 11111x   11x   11x           11x   11x   11x               11x           5x 5x     5x     5x   5x 5x   5x           5x 5x   5x       1x       7x       3x 3x   3x   3x 3x       5x 5x                               5x       3x 3x         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 { EntityFactory, 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 readonly screenHeight = 24;
    private readonly screenWidth = 80;
 
    public constructor() {
        this.engine = new World(new Scheduler(), createMap(), new CommandManager(), new EntityFactory());
 
        // 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();
    }
 
    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 => {
            window.addEventListener(eventName, (event) => {
                const inputEvent: KeyboardEvent = event as KeyboardEvent;
                const newScreenName = this.currentScreen.handleInput(eventName, { code: inputEvent.code as Keys });
 
                Iif (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,
    });
}