puzzlescript
Version:
Play PuzzleScript games in your terminal!
186 lines (185 loc) • 6.86 kB
TypeScript
import { EventEmitter2 } from 'eventemitter2';
import { CollisionLayer } from './models/collisionLayer';
import { GameData } from './models/game';
import { A11Y_MESSAGE, IMutation, SimpleRuleGroup } from './models/rule';
import { GameSprite, IGameTile } from './models/tile';
import { Command, SoundItem } from './parser/astTypes';
import { SpriteBitSet } from './spriteBitSet';
import { Cellish, GameEngineHandler, INPUT_BUTTON, Optional, RULE_DIRECTION } from './util';
interface ITickResult {
changedCells: Set<Cell>;
didWinGame: boolean;
didLevelChange: boolean;
wasAgainTick: boolean;
}
/**
* The state of sprites in one position of the current level being played.
*
* This stores all the sprites and which direction those sprites want to move.
*
* The [[TerminalUI]] uses this object to render and the [[GameEngine]] uses this to maintain the state
* of one position of the current level.
*/
export declare class Cell implements Cellish {
readonly rowIndex: number;
readonly colIndex: number;
readonly spriteBitSet: SpriteBitSet;
private readonly level;
private readonly state;
private cacheCollisionLayers;
private cachedKeyValue;
constructor(level: Optional<Level>, sprites: Set<GameSprite>, rowIndex: number, colIndex: number);
_setWantsToMove(sprite: GameSprite, wantsToMove: Optional<RULE_DIRECTION>): boolean;
_deleteWantsToMove(sprite: GameSprite): boolean;
setWantsToMoveCollisionLayer(collisionLayer: CollisionLayer, wantsToMove: RULE_DIRECTION): boolean;
getSpriteByCollisionLayer(collisionLayer: CollisionLayer): GameSprite | null;
getCollisionLayers(): CollisionLayer[];
getSprites(): GameSprite[];
getSpritesAsSet(): Set<GameSprite>;
getSpriteAndWantsToMoves(): Map<any, any>;
getCollisionLayerWantsToMove(collisionLayer: CollisionLayer): RULE_DIRECTION | null;
hasSprite(sprite: GameSprite): boolean;
getNeighbor(direction: string): Cell | null;
getWantsToMove(sprite: GameSprite): RULE_DIRECTION | null;
hasCollisionWithSprite(otherSprite: GameSprite): boolean;
clearWantsToMove(sprite: GameSprite): void;
addSprite(sprite: GameSprite, wantsToMove: Optional<RULE_DIRECTION>): boolean;
updateSprite(sprite: GameSprite, wantsToMove: RULE_DIRECTION): boolean;
removeSprite(sprite: GameSprite): boolean;
toString(): string;
toKey(): string;
toSnapshot(): Set<GameSprite>;
fromSnapshot(newSprites: Set<GameSprite>): void;
protected replaceSpriteInLevel(cellSprite: Optional<GameSprite>, newSprite: GameSprite): void;
private _setState;
private getLevel;
private getStateForCollisionLayer;
private getRelativeNeighbor;
private removeSprites;
private addSprites;
private invalidateKey;
}
export declare class Level {
private cells;
private rowCache;
private colCache;
constructor();
setCells(cells: Cell[][]): void;
getCells(): Cell[][];
getCellOrNull(rowIndex: number, colIndex: number): Cell | null;
getCell(rowIndex: number, colIndex: number): Cell;
replaceSprite(cell: Cell, oldSprite: Optional<GameSprite>, newSprite: Optional<GameSprite>): void;
rowContainsSprites(rowIndex: number, spritesPresent: SpriteBitSet, anySpritesPresent: SpriteBitSet): boolean;
colContainsSprites(colIndex: number, sprites: SpriteBitSet, anySpritesPresent: SpriteBitSet): boolean;
private computeRowCache;
private computeColCache;
}
/**
* Internal class that ise used to maintain the state of a level.
*
* This should not be called directly. Instead, use [[GameEngine]] .
*/
export declare class LevelEngine extends EventEmitter2 {
readonly gameData: GameData;
pendingPlayerWantsToMove: Optional<INPUT_BUTTON>;
hasAgainThatNeedsToRun: boolean;
private currentLevel;
private tempOldLevel;
private undoStack;
constructor(gameData: GameData);
setLevel(levelNum: number): Cell[];
setMessageLevel(sprites: Array<Array<Set<GameSprite>>>): void;
restoreFromMessageLevel(): void;
getCurrentLevel(): Level;
toSnapshot(): string[][][];
tick(): {
changedCells: Set<Cell>;
soundToPlay: null;
messageToShow: null;
hasCheckpoint: boolean;
hasRestart: boolean;
isWinning: boolean;
mutations: never[];
a11yMessages: never[];
} | {
changedCells: Set<Cell>;
hasCheckpoint: boolean;
soundToPlay: Optional<SoundItem<IGameTile>>;
messageToShow: Optional<string>;
hasRestart: boolean;
isWinning: boolean;
mutations: Set<IMutation>;
a11yMessages: never[] | A11Y_MESSAGE<Cell, GameSprite>[];
};
hasAgain(): boolean;
canUndo(): boolean;
press(button: INPUT_BUTTON): void;
tickUpdateCells(): {
evaluatedRules: SimpleRuleGroup[];
changedCells: Set<Cell>;
commands: Set<Command<SoundItem<IGameTile>>>;
mutations: Set<IMutation>;
a11yMessages: A11Y_MESSAGE<Cell, GameSprite>[];
};
tickMoveSprites(changedCells: Set<Cell>): {
movedCells: Set<Cell>;
a11yMessages: A11Y_MESSAGE<Cell, GameSprite>[];
};
createSnapshot(): Set<GameSprite>[][];
private pressDir;
private doRestart;
private doUndo;
private _setLevel;
private getCells;
private tickUpdateCellsLate;
private _tickUpdateCells;
private tickNormal;
private getRealA11yMessages;
private getRealChangedCells;
private isWinning;
private takeSnapshot;
private applySnapshot;
private doSnapshotsDiffer;
}
export interface ILoadingCellsEvent {
cellStart: number;
cellEnd: number;
cellTotal: number;
key: string;
}
export declare type ILoadingProgressHandler = (info: ILoadingCellsEvent) => void;
export declare type CellSaveState = string[][][];
/**
* Maintains the state of the game. Here is an example flow:
*
* ```js
* const engine = new GameEngine(gameData)
* engine.setLevel(0)
* engine.pressRight()
* engine.tick()
* engine.tick()
* engine.pressUp()
* engine.tick()
* engine.pressUndo()
* engine.tick()
* ```
*/
export declare class GameEngine {
private levelEngine;
private currentLevelNum;
private handler;
constructor(gameData: GameData, handler: GameEngineHandler);
on(eventName: string, handler: ILoadingProgressHandler): void;
getGameData(): GameData;
getCurrentLevelCells(): Cell[][];
getCurrentLevel(): import("./parser/astTypes").Level<IGameTile>;
getCurrentLevelNum(): number;
hasAgain(): boolean;
setLevel(levelNum: number, checkpoint: Optional<CellSaveState>): void;
tick(): Promise<ITickResult>;
press(direction: INPUT_BUTTON): void;
saveSnapshotToJSON(): CellSaveState;
loadSnapshotFromJSON(json: CellSaveState): void;
isCurrentLevelAMessage(): boolean;
}
export {};