UNPKG

excalibur

Version:

Excalibur.js is a simple JavaScript game engine with TypeScript bindings for making 2D games in HTML5 Canvas. Our mission is to make web game development as simple as possible.

341 lines (340 loc) • 11.3 kB
import { BoundingBox } from '../Collision/BoundingBox'; import { Engine } from '../Engine'; import { Vector } from '../Math/vector'; import { Logger } from '../Util/Log'; import { Entity, EntityEvents } from '../EntityComponentSystem/Entity'; import { TransformComponent } from '../EntityComponentSystem/Components/TransformComponent'; import { ExcaliburGraphicsContext, Graphic } from '../Graphics'; import { ColliderComponent } from '../Collision/ColliderComponent'; import { Collider } from '../Collision/Colliders/Collider'; import { PostDrawEvent, PostUpdateEvent, PreDrawEvent, PreUpdateEvent } from '../Events'; import { EventEmitter, EventKey, Handler, Subscription } from '../EventEmitter'; import { DebugConfig } from '../Debug'; import { PointerComponent } from '../Input/PointerComponent'; import { PointerEvent } from '../Input/PointerEvent'; import { PointerEventReceiver } from '../Input/PointerEventReceiver'; import { HasNestedPointerEvents } from '../Input/PointerEventsToObjectDispatcher'; export interface TileMapOptions { /** * Optionally name the tile map */ name?: string; /** * Optionally specify the position of the tile map */ pos?: Vector; /** * Width of an individual tile in pixels */ tileWidth: number; /** * Height of an individual tile in pixels */ tileHeight: number; /** * The number of tile columns, or the number of tiles wide */ columns: number; /** * The number of tile rows, or the number of tiles high */ rows: number; /** * Optionally render from the top of the graphic, by default tiles are rendered from the bottom */ renderFromTopOfGraphic?: boolean; /** * Optionally configure the meshing lookbehind for Tilemap, Tilemaps combine solid tiles into optimal * geometry and the lookbehind configures how far back the Tilemap to look for geometry when combining. Meshing * is an expensive operation, so when the Tilemap geometry is invalidated it must be recalculated. * * Default is 10 slots, but if your Tilemap does not change positions or solid tiles often you can increase this to * Infinity. */ meshingLookBehind?: number; } export type TilePointerEvents = { pointerup: PointerEvent; pointerdown: PointerEvent; pointermove: PointerEvent; pointercancel: PointerEvent; pointerenter: PointerEvent; pointerleave: PointerEvent; }; export type TileMapEvents = EntityEvents & TilePointerEvents & { preupdate: PreUpdateEvent<TileMap>; postupdate: PostUpdateEvent<TileMap>; predraw: PreDrawEvent; postdraw: PostDrawEvent; }; export declare const TileMapEvents: { PreUpdate: string; PostUpdate: string; PreDraw: string; PostDraw: string; PointerUp: string; PointerDown: string; PointerMove: string; PointerCancel: string; }; /** * The TileMap provides a mechanism for doing flat 2D tiles rendered in a grid. * * TileMaps are useful for top down or side scrolling grid oriented games. */ export declare class TileMap extends Entity implements HasNestedPointerEvents { events: EventEmitter<TileMapEvents>; private _token; private _engine; logger: Logger; readonly tiles: Tile[]; private _rows; private _cols; readonly tileWidth: number; readonly tileHeight: number; readonly rows: number; readonly columns: number; renderFromTopOfGraphic: boolean; meshingLookBehind: number; private _collidersDirty; private _pointerEventDispatcher; flagCollidersDirty(): void; flagTilesDirty(): void; pointer: PointerComponent; transform: TransformComponent; private _motion; private _graphics; collider: ColliderComponent; private _composite; get x(): number; set x(val: number); get y(): number; set y(val: number); get z(): number; set z(val: number); private _oldRotation; get rotation(): number; set rotation(val: number); private _oldScale; get scale(): Vector; set scale(val: Vector); private _oldPos; get pos(): Vector; set pos(val: Vector); get vel(): Vector; set vel(val: Vector); /** * Width of the whole tile map in pixels */ get width(): number; /** * Height of the whole tilemap in pixels */ get height(): number; emit<TEventName extends EventKey<TileMapEvents>>(eventName: TEventName, event: TileMapEvents[TEventName]): void; emit(eventName: string, event?: any): void; on<TEventName extends EventKey<TileMapEvents>>(eventName: TEventName, handler: Handler<TileMapEvents[TEventName]>): Subscription; on(eventName: string, handler: Handler<unknown>): Subscription; once<TEventName extends EventKey<TileMapEvents>>(eventName: TEventName, handler: Handler<TileMapEvents[TEventName]>): Subscription; once(eventName: string, handler: Handler<unknown>): Subscription; off<TEventName extends EventKey<TileMapEvents>>(eventName: TEventName, handler: Handler<TileMapEvents[TEventName]>): void; off(eventName: string, handler: Handler<unknown>): void; off(eventName: string): void; /** * @param options */ constructor(options: TileMapOptions); _initialize(engine: Engine): void; private _originalOffsets; private _getOrSetColliderOriginalOffset; /** * Tiles colliders based on the solid tiles in the tilemap. */ private _updateColliders; /** * Returns the {@apilink Tile} by index (row major order) * * Returns null if out of bounds */ getTileByIndex(index: number): Tile | null; /** * Returns the {@apilink Tile} by its x and y integer coordinates * * Returns null if out of bounds * * For example, if I want the tile in fifth column (x), and second row (y): * `getTile(4, 1)` 0 based, so 0 is the first in row/column */ getTile(x: number, y: number): Tile | null; /** * Returns the {@apilink Tile} by testing a point in world coordinates, * returns `null` if no Tile was found. */ getTileByPoint(point: Vector): Tile | null; private _getTileCoordinates; getRows(): readonly Tile[][]; getColumns(): readonly Tile[][]; /** * Returns the on screen tiles for a tilemap, this will overshoot by a small amount because of the internal quad tree data structure. * * Useful if you need to perform specific logic on onscreen tiles */ getOnScreenTiles(): readonly Tile[]; /** * @internal */ _processPointerToObject(receiver: PointerEventReceiver): void; /** * @internal */ _dispatchPointerEvents(receiver: PointerEventReceiver): void; update(engine: Engine, elapsed: number): void; /** * Draws the tile map to the screen. Called by the {@apilink Scene}. * @param ctx ExcaliburGraphicsContext * @param elapsed The number of milliseconds since the last draw */ draw(ctx: ExcaliburGraphicsContext, elapsed: number): void; debug(gfx: ExcaliburGraphicsContext, debugFlags: DebugConfig): void; } export interface TileOptions { /** * Integer tile x coordinate */ x: number; /** * Integer tile y coordinate */ y: number; map: TileMap; solid?: boolean; graphics?: Graphic[]; } /** * TileMap Tile * * A light-weight object that occupies a space in a collision map. Generally * created by a {@apilink TileMap}. * * Tiles can draw multiple sprites. Note that the order of drawing is the order * of the sprites in the array so the last one will be drawn on top. You can * use transparency to create layers this way. */ export declare class Tile { private _bounds; private _geometry; private _pos; private _posDirty; events: EventEmitter<TilePointerEvents>; /** * Return the world position of the top left corner of the tile */ get pos(): Vector; /** * Integer x coordinate of the tile */ readonly x: number; /** * Integer y coordinate of the tile */ readonly y: number; private _width; /** * Width of the tile in pixels */ get width(): number; private _height; /** * Height of the tile in pixels */ get height(): number; /** * Reference to the TileMap this tile is associated with */ map: TileMap; private _solid; /** * Wether this tile should be treated as solid by the tilemap */ get solid(): boolean; /** * Wether this tile should be treated as solid by the tilemap */ set solid(val: boolean); private _graphics; private _offsets; /** * Current list of graphics for this tile */ getGraphics(): readonly Graphic[]; /** * Current list of offsets for this tile's graphics */ getGraphicsOffsets(): readonly Vector[]; /** * Add another {@apilink Graphic} to this TileMap tile * @param graphic */ addGraphic(graphic: Graphic, options?: { offset?: Vector; }): void; /** * Remove an instance of a {@apilink Graphic} from this tile */ removeGraphic(graphic: Graphic): void; /** * Clear all graphics from this tile */ clearGraphics(): void; /** * Current list of colliders for this tile */ private _colliders; /** * Returns the list of colliders */ getColliders(): readonly Collider[]; /** * Adds a custom collider to the {@apilink Tile} to use instead of it's bounds * * If no collider is set but {@apilink Tile.solid} is set, the tile bounds are used as a collider. * * **Note!** the {@apilink Tile.solid} must be set to true for it to act as a "fixed" collider * @param collider */ addCollider(collider: Collider): void; /** * Removes a collider from the {@apilink Tile} * @param collider */ removeCollider(collider: Collider): void; /** * Clears all colliders from the {@apilink Tile} */ clearColliders(): void; /** * Arbitrary data storage per tile, useful for any game specific data */ data: Map<string, any>; constructor(options: TileOptions); flagDirty(): boolean; private _recalculate; /** * Tile bounds in world space */ get bounds(): BoundingBox; get defaultGeometry(): BoundingBox; /** * Tile position in world space */ get center(): Vector; emit<TEventName extends EventKey<TilePointerEvents>>(eventName: TEventName, event: TilePointerEvents[TEventName]): void; emit(eventName: string, event?: any): void; on<TEventName extends EventKey<TilePointerEvents>>(eventName: TEventName, handler: Handler<TilePointerEvents[TEventName]>): Subscription; on(eventName: string, handler: Handler<unknown>): Subscription; once<TEventName extends EventKey<TilePointerEvents>>(eventName: TEventName, handler: Handler<TilePointerEvents[TEventName]>): Subscription; once(eventName: string, handler: Handler<unknown>): Subscription; off<TEventName extends EventKey<TilePointerEvents>>(eventName: TEventName, handler: Handler<TilePointerEvents[TEventName]>): void; off(eventName: string, handler: Handler<unknown>): void; off(eventName: string): void; }