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
TypeScript
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;
}