Options
All
  • Public
  • Public/Protected
  • All
Menu

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).

Events

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) {});

Wheel Event

You can also subscribe to the mouse wheel event through engine.input.pointers.on. A WheelEvent object is passed to your handler which offers information about the wheel event being received.

  • wheel - When a mousewheel is activated (trackpad scroll or mouse wheel)
engine.input.pointers.on('wheel', function(evt) {});

Last position querying

If you don't wish to subscribe to events, you can also access the Pointer.lastPagePos, Pointer.lastScreenPos or Pointer.lastWorldPos coordinates (Vector) on the pointer you're targeting.

engine.input.pointers.primary.lastPagePos;
engine.input.pointers.primary.lastScreenPos;
engine.input.pointers.primary.lastWorldPos;

Note that the value may be null if the Pointer was not active the last frame.

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

Hierarchy

Implements

Index

Constructors

constructor

Properties

eventDispatcher

eventDispatcher: EventDispatcher

Direct access to the game object event dispatcher.

primary

primary: Pointer

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

Methods

at

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

    Parameters

    • index: number

      The pointer index to retrieve

    Returns Pointer

count

  • count(): number

emit

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

    Parameters

    • eventName: string

      Name of the event to emit

    • Optional eventObject: GameEvent<any>

      Data associated with this event

    Returns void

init

  • init(target?: GlobalEventHandlers): void
  • Initializes pointer event listeners

    Parameters

    • Optional target: GlobalEventHandlers

    Returns void

off

  • 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.

    Parameters

    • eventName: string

      Name of the event to listen for

    • Optional handler: function

      Event handler for the thrown event

    Returns void

on

  • on(eventName: Events.up, handler: function): void
  • on(eventName: Events.down, handler: function): void
  • on(eventName: Events.move, handler: function): void
  • on(eventName: Events.enter, handler: function): void
  • on(eventName: Events.leave, handler: function): void
  • on(eventName: Events.cancel, handler: function): void
  • on(eventName: Events.wheel, handler: function): void
  • on(eventName: string, handler: function): void

once

  • once(eventName: string, handler: function): void
  • Once listens to an event one time, then unsubscribes from that event

    Parameters

    • eventName: string

      The name of the event to subscribe to once

    • handler: function

      The handler of the event that will be auto unsubscribed

    Returns void

propagate

  • propagate(): void
  • Propogates events through ancestors chain if necessary

    Returns void

revisePointerEventsPaths

  • revisePointerEventsPaths(actor: Actor): void
  • Revises pointer events paths accordingly to actor provided

    Parameters

    • actor: Actor

      Actor to be revised

    Returns void

update

  • update(): 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.

    Parameters

    • methods: any

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

    Returns any