• Public
  • Public/Protected
  • All

Class Pointers

Handles pointer events (mouse, touch, stylus, etc.) and normalizes to W3C Pointer Events.

There is always at least one Pointer available (Pointers.primary) and you can request multiple pointers to support multi-touch scenarios.

Since Pointers.primary normalizes both mouse and touch events, your game automatically supports touch for the primary pointer by default. When you handle the events, you can customize what your game does based on the type of pointer, if applicable.

Excalibur handles mouse/touch events and normalizes them to a PointerEvent that your game can subscribe to and handle (engine.input.pointers).


You can subscribe to pointer events through engine.input.pointers.on. A PointerEvent object is passed to your handler which offers information about the pointer input being received.

  • down - When a pointer is pressed down (any mouse button or finger press)
  • up - When a pointer is lifted
  • move - When a pointer moves (be wary of performance issues when subscribing to this)
  • cancel - When a pointer event is canceled for some reason
engine.input.pointers.primary.on("down", function (evt) { });
engine.input.pointers.primary.on("up", function (evt) { });
engine.input.pointers.primary.on("move", function (evt) { });
engine.input.pointers.primary.on("cancel", function (evt) { });

Pointer scope (window vs. canvas)

You have the option to handle all pointer events in the browser by setting IEngineOptions.pointerScope to PointerScope.Document. If this is enabled,

Excalibur will handle every pointer event in the browser. This is useful for handling complex input and having control over every interaction.

You can also use PointerScope.Canvas to only scope event handling to the game canvas. This is useful if you don't care about events that occur outside the game.

One real-world example is dragging and gestures. Sometimes a player will drag their finger outside your game and then into it, expecting it to work. If PointerScope is set to Canvas this will not work. If it is set to Document, it will.

Responding to input

The primary pointer can be a mouse, stylus, or single finger touch event. You can inspect what type of pointer it is from the PointerEvent handled.

engine.input.pointers.primary.on("down", function (pe) {
  if (pe.pointerType === ex.Input.PointerType.Mouse) {
    ex.Logger.getInstance().info("Mouse event:", pe);
  } else if (pe.pointerType === ex.Input.PointerType.Touch) {
    ex.Logger.getInstance().info("Touch event:", pe);

Multiple Pointers (Multi-Touch)

When there is more than one pointer detected on the screen, this is considered multi-touch. For example, pressing one finger, then another, will create two pointers. If you lift a finger, the first one remains and the second one disappears.

You can handle multi-touch by subscribing to however many pointers you would like to support. If a pointer doesn't yet exist, it will be created. You do not need to check if a pointer exists. If it does exist, it will propogate events, otherwise it will remain idle.

Excalibur does not impose a limit to the amount of pointers you can subscribe to, so by all means, support all 10 fingers.

Note: There is no way to identify touches after they happen; you can only know that there are n touches on the screen at once.

function paint(color) {
  // create a handler for the event
  return function (pe) {
    if (pe.pointerType === ex.Input.PointerType.Touch) {
      engine.canvas.fillStyle = color;
      engine.canvas.fillRect(pe.x, pe.y, 5, 5);
engine.input.pointers.at(0).on("move", paint("blue"));  // 1st finger
engine.input.pointers.at(1).on("move", paint("red"));   // 2nd finger
engine.input.pointers.at(2).on("move", paint("green")); // 3rd finger

Actor pointer events

By default, Actors do not participate in pointer events. In other words, when you "click" an Actor, it will not throw an event for that Actor, only a generic pointer event for the game. This is to keep performance high and allow actors to "opt-in" to handling pointer events. Actors will automatically opt-in if a pointer related event handler is set on them actor.on("pointerdown", () => {}) for example.

To opt-in manually, set Actor.enableCapturePointer to true and the Actor will start publishing pointerup and pointerdown events. pointermove events will not be published by default due to performance implications. If you want an actor to receive move events, set ICapturePointerConfig.captureMoveEvents to true.

Actor pointer events will be prefixed with pointer.

var player = new ex.Actor();
// enable propagating pointer events
player.enableCapturePointer = true;
// enable move events, warning: performance intensive!
player.capturePointer.captureMoveEvents = true;
// subscribe to input
player.on("pointerup", function (ev) {
  player.logger.info("Player selected!", ev);







Private _activePointers

_activePointers: number[] = []

Private _engine

_engine: Engine

Private _pointerCancel

_pointerCancel: PointerEvent[] = []

Private _pointerDown

_pointerDown: PointerEvent[] = []

Private _pointerMove

_pointerMove: PointerEvent[] = []

Private _pointerUp

_pointerUp: PointerEvent[] = []

Private _pointers

_pointers: Pointer[] = []


eventDispatcher: EventDispatcher

Direct access to the game object event dispatcher.


primary: Pointer

Primary pointer (mouse, 1 finger, stylus, etc.)


Private _getPointerIndex

  • _getPointerIndex(pointerId: number): any
  • Gets the index of the pointer specified for the given pointer ID or finds the next empty pointer slot available. This is required because IE10/11 uses incrementing pointer IDs so we need to store a mapping of ID => idx


    • pointerId: number

    Returns any

Private _handleMouseEvent

  • _handleMouseEvent(eventName: string, eventArr: PointerEvent[]): (Anonymous function)
  • Parameters

    Returns (Anonymous function)

Private _handlePointerEvent

  • _handlePointerEvent(eventName: string, eventArr: PointerEvent[]): (Anonymous function)
  • Parameters

    Returns (Anonymous function)

Private _handleTouchEvent

  • _handleTouchEvent(eventName: string, eventArr: PointerEvent[]): (Anonymous function)
  • Parameters

    Returns (Anonymous function)

Private _stringToPointerType

  • Parameters

    • s: any

    Returns PointerType


  • Safely gets a Pointer at a specific index and initializes one if it doesn't yet exist


    • index: number

      The pointer index to retrieve

    Returns Pointer


  • count(): number
  • Get number of pointers being watched

    Returns number


  • emit(eventName: string, eventObject?: GameEvent): void
  • Emits a new event


    • eventName: string

      Name of the event to emit

    • Optional eventObject: GameEvent

      Data associated with this event

    Returns void


  • Initializes pointer event listeners


    • Default value scope: PointerScope = PointerScope.Document

    Returns void


  • off(eventName: string, handler?: function): void
  • Alias for removeEventListener. If only the eventName is specified it will remove all handlers registered for that specific event. If the eventName and the handler instance are specified only that handler will be removed.


    • eventName: string

      Name of the event to listen for

    • Optional handler: function

      Event handler for the thrown event

    Returns void


  • on(eventName: up, handler: function): any
  • on(eventName: down, handler: function): any
  • on(eventName: move, handler: function): any
  • on(eventName: cancel, handler: function): any
  • on(eventName: string, handler: function): any
  • Parameters

    Returns any

  • Parameters

    Returns any

  • Parameters

    Returns any

  • Parameters

    Returns any

  • Parameters

    • eventName: string
    • handler: function

    Returns any


  • propogate(actor: any): void
  • Propogates events to actor if necessary


    • actor: any

    Returns void


  • update(delta: number): void
  • Parameters

    • delta: number

    Returns void

Static extend

  • extend(methods: any): any
  • You may wish to extend native Excalibur functionality in vanilla Javascript. Any method on a class inheriting Class may be extended to support additional functionality. In the example below we create a new type called MyActor.

    var MyActor = Actor.extend({
       constructor: function() {
          this.newprop = 'something';
          Actor.apply(this, arguments);
       update: function(engine, delta) {
          // Implement custom update
          // Call super constructor update
          Actor.prototype.update.call(this, engine, delta);
          console.log("Something cool!");
    var myActor = new MyActor(100, 100, 100, 100, Color.Azure);

    In TypeScript, you only need to use the extends syntax, you do not need to use this method of extension.


    • methods: any

      A JSON object contain any methods/properties you want to extend

    Returns any