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.

287 lines (286 loc) • 9.24 kB
import { Graphic, GraphicOptions } from './Graphic'; import { ExcaliburGraphicsContext } from './Context/ExcaliburGraphicsContext'; import { GetSpriteOptions, SpriteSheet } from './SpriteSheet'; import { EventEmitter } from '../EventEmitter'; export interface HasTick { /** * * @param elapsed The amount of real world time in milliseconds that has elapsed that must be updated in the animation * @param idempotencyToken Optional idempotencyToken prevents a ticking animation from updating twice per frame */ tick(elapsed: number, idempotencyToken?: number): void; } export declare enum AnimationDirection { /** * Animation is playing forwards */ Forward = "forward", /** * Animation is playing backwards */ Backward = "backward" } export declare enum AnimationStrategy { /** * Animation ends without displaying anything */ End = "end", /** * Animation loops to the first frame after the last frame */ Loop = "loop", /** * Animation plays to the last frame, then backwards to the first frame, then repeats */ PingPong = "pingpong", /** * Animation ends stopping on the last frame */ Freeze = "freeze" } /** * Frame of animation */ export interface Frame { /** * Optionally specify a graphic to show, no graphic shows an empty frame */ graphic?: Graphic; /** * Optionally specify the number of ms the frame should be visible, overrides the animation duration (default 100 ms) */ duration?: number; } export interface FrameEvent extends Frame { frameIndex: number; } /** * Animation options for building an animation via constructor. */ export interface AnimationOptions { /** * List of frames in the order you wish to play them */ frames: Frame[]; /** * Optionally set a positive speed multiplier on the animation. * * By default 1, meaning 1x speed. If set to 2, it will play the animation twice as fast. */ speed?: number; /** * Optionally reverse the direction of play */ reverse?: boolean; /** * Optionally specify a default frame duration in ms (Default is 100) */ frameDuration?: number; /** * Optionally specify a total duration of the animation in ms to calculate each frame's duration */ totalDuration?: number; /** * Optionally specify the {@apilink AnimationStrategy} for the Animation */ strategy?: AnimationStrategy; } export type AnimationEvents = { frame: FrameEvent; loop: Animation; end: Animation; }; export declare const AnimationEvents: { Frame: string; Loop: string; End: string; }; export interface FromSpriteSheetOptions { /** * {@apilink SpriteSheet} to source the animation frames from */ spriteSheet: SpriteSheet; /** * The list of (x, y) positions of sprites in the {@apilink SpriteSheet} of each frame, for example (0, 0) * is the the top left sprite, (0, 1) is the sprite directly below that, and so on. * * You may optionally specify a duration for the frame in milliseconds as well, this will override * the default duration. */ frameCoordinates: { x: number; y: number; duration?: number; options?: GetSpriteOptions; }[]; /** * Optionally specify a default duration for frames in milliseconds * @deprecated use `durationPerFrame` */ durationPerFrameMs?: number; /** * Optionally specify a default duration for frames in milliseconds */ durationPerFrame?: number; /** * Optionally set a positive speed multiplier on the animation. * * By default 1, meaning 1x speed. If set to 2, it will play the animation twice as fast. */ speed?: number; /** * Optionally specify the animation strategy for this animation, by default animations loop {@apilink AnimationStrategy.Loop} */ strategy?: AnimationStrategy; /** * Optionally specify the animation should be reversed */ reverse?: boolean; } /** * Create an Animation given a list of {@apilink Frame | `frames`} in {@apilink AnimationOptions} * * To create an Animation from a {@apilink SpriteSheet}, use {@apilink Animation.fromSpriteSheet} */ export declare class Animation extends Graphic implements HasTick { private static _LOGGER; events: EventEmitter<AnimationEvents>; frames: Frame[]; strategy: AnimationStrategy; frameDuration: number; private _idempotencyToken; private _firstTick; private _currentFrame; private _timeLeftInFrame; private _pingPongDirection; private _done; private _playing; private _speed; constructor(options: GraphicOptions & AnimationOptions); clone(): Animation; get width(): number; get height(): number; /** * Create an Animation from a {@apilink SpriteSheet}, a list of indices into the sprite sheet, a duration per frame * and optional {@apilink AnimationStrategy} * * Example: * ```typescript * const spriteSheet = SpriteSheet.fromImageSource({...}); * * const anim = Animation.fromSpriteSheet(spriteSheet, range(0, 5), 200, AnimationStrategy.Loop); * ``` * @param spriteSheet ex.SpriteSheet * @param spriteSheetIndex 0 based index from left to right, top down (row major order) of the ex.SpriteSheet * @param durationPerFrame duration per frame in milliseconds * @param strategy Optional strategy, default AnimationStrategy.Loop */ static fromSpriteSheet(spriteSheet: SpriteSheet, spriteSheetIndex: number[], durationPerFrame: number, strategy?: AnimationStrategy): Animation; /** * Create an {@apilink Animation} from a {@apilink SpriteSheet} given a list of coordinates * * Example: * ```typescript * const spriteSheet = SpriteSheet.fromImageSource({...}); * * const anim = Animation.fromSpriteSheetCoordinates({ * spriteSheet, * frameCoordinates: [ * {x: 0, y: 5, duration: 100, options { flipHorizontal: true }}, * {x: 1, y: 5, duration: 200}, * {x: 2, y: 5}, * {x: 3, y: 5} * ], * strategy: AnimationStrategy.PingPong * }); * ``` * @param options * @returns Animation */ static fromSpriteSheetCoordinates(options: FromSpriteSheetOptions): Animation; /** * Current animation speed * * 1 meaning normal 1x speed. * 2 meaning 2x speed and so on. */ get speed(): number; /** * Current animation speed * * 1 meaning normal 1x speed. * 2 meaning 2x speed and so on. */ set speed(val: number); /** * Returns the current Frame of the animation * * Use {@apilink Animation.currentFrameIndex} to get the frame number and * {@apilink Animation.goToFrame} to set the current frame index */ get currentFrame(): Frame | null; /** * Returns the current frame index of the animation * * Use {@apilink Animation.currentFrame} to grab the current {@apilink Frame} object */ get currentFrameIndex(): number; /** * Returns the amount of time in milliseconds left in the current frame */ get currentFrameTimeLeft(): number; /** * Returns `true` if the animation is playing */ get isPlaying(): boolean; private _reversed; get isReversed(): boolean; /** * Reverses the play direction of the Animation, this preserves the current frame */ reverse(): void; /** * Returns the current play direction of the animation */ get direction(): AnimationDirection; /** * Plays or resumes the animation from the current frame */ play(): void; /** * Pauses the animation on the current frame */ pause(): void; /** * Reset the animation back to the beginning, including if the animation were done */ reset(): void; /** * Returns `true` if the animation can end */ get canFinish(): boolean; /** * Returns `true` if the animation is done, for looping type animations * `ex.AnimationStrategy.PingPong` and `ex.AnimationStrategy.Loop` this will always return `false` * * See the `ex.Animation.canFinish()` method to know if an animation type can end */ get done(): boolean; /** * Jump the animation immediately to a specific frame if it exists * * Optionally specify an override for the duration of the frame, useful for * keeping multiple animations in sync with one another. * @param frameNumber * @param duration */ goToFrame(frameNumber: number, duration?: number): void; private _nextFrame; /** * Called internally by Excalibur to update the state of the animation potential update the current frame * @param elapsed Milliseconds elapsed * @param idempotencyToken Prevents double ticking in a frame by passing a unique token to the frame */ tick(elapsed: number, idempotencyToken?: number): void; protected _drawImage(ctx: ExcaliburGraphicsContext, x: number, y: number): void; }