• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

excaliburjs / Excalibur / 14804036802

02 May 2025 09:58PM UTC coverage: 5.927% (-83.4%) from 89.28%
14804036802

Pull #3404

github

web-flow
Merge 5c103d7f8 into 0f2ccaeb2
Pull Request #3404: feat: added Graph module to Math

234 of 8383 branches covered (2.79%)

229 of 246 new or added lines in 1 file covered. (93.09%)

13145 existing lines in 208 files now uncovered.

934 of 15759 relevant lines covered (5.93%)

4.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

4.35
/src/engine/Trigger.ts
1
import { Vector } from './Math/vector';
2
import { ExitTriggerEvent, EnterTriggerEvent, CollisionEndEvent, CollisionStartEvent } from './Events';
3
import { CollisionType } from './Collision/CollisionType';
4
import { Entity } from './EntityComponentSystem';
5
import { Actor, ActorArgs, ActorEvents } from './Actor';
6
import { EventEmitter } from './EventEmitter';
7

8
export type TriggerEvents = ActorEvents & {
9
  exit: ExitTriggerEvent;
10
  enter: EnterTriggerEvent;
11
};
12

13
export const TriggerEvents = {
1✔
14
  ExitTrigger: 'exit',
15
  EnterTrigger: 'enter'
16
};
17

18
/**
19
 * TriggerOptions
20
 */
21
export interface TriggerOptions {
22
  // position of the trigger
23
  pos?: Vector;
24
  // width of the trigger
25
  width?: number;
26
  // height of the trigger
27
  height?: number;
28
  // whether the trigger is visible or not
29
  visible?: boolean;
30
  // action to take when triggered
31
  action?: (entity: Entity) => void;
32
  // if specified the trigger will only fire on a specific entity and overrides any filter
33
  target?: Entity;
34
  // Returns true if the triggers should fire on the collided entity
35
  filter?: (entity: Entity) => boolean;
36
  // -1 if it should repeat forever
37
  repeat?: number;
38
}
39

40
/**
41
 * Triggers are a method of firing arbitrary code on collision. These are useful
42
 * as 'buttons', 'switches', or to trigger effects in a game. By default triggers
43
 * are invisible, and can only be seen when {@apilink Trigger.visible} is set to `true`.
44
 */
45
export class Trigger extends Actor {
UNCOV
46
  public events = new EventEmitter<TriggerEvents & ActorEvents>();
×
47
  public target?: Entity;
48
  /**
49
   * Action to fire when triggered by collision
50
   */
51
  public action: (entity: Entity) => void;
52
  /**
53
   * Filter to add additional granularity to action dispatch, if a filter is specified the action will only fire when
54
   * filter return true for the collided entity.
55
   */
56
  public filter: (entity: Entity) => boolean;
57
  /**
58
   * Number of times to repeat before killing the trigger,
59
   */
60
  public repeat: number;
61

62
  /**
63
   * @param options Trigger options
64
   */
65
  constructor(options: TriggerOptions & ActorArgs) {
UNCOV
66
    super({ ...options });
×
67

UNCOV
68
    this.filter = options.filter ?? (() => true);
×
UNCOV
69
    this.repeat = options.repeat ?? -1;
×
UNCOV
70
    this.action = options.action ?? (() => undefined);
×
UNCOV
71
    this.target = options.target;
×
72

UNCOV
73
    this.graphics.isVisible = options.visible ?? false;
×
UNCOV
74
    this.body.collisionType = CollisionType.Passive;
×
75

UNCOV
76
    this.events.on('collisionstart', ({ other: collider }: CollisionStartEvent) => {
×
UNCOV
77
      if (!this._matchesTarget(collider.owner)) {
×
UNCOV
78
        return;
×
79
      }
80

81
      this.events.emit('enter', new EnterTriggerEvent(this, collider.owner));
×
82
      this._dispatchAction(collider.owner);
×
83
      // remove trigger if its done, -1 repeat forever
84
      if (this.repeat === 0) {
×
85
        this.kill();
×
86
      }
87
    });
88

UNCOV
89
    this.events.on('collisionend', ({ other: collider }: CollisionEndEvent) => {
×
90
      if (this._matchesTarget(collider.owner)) {
×
91
        this.events.emit('exit', new ExitTriggerEvent(this, collider.owner));
×
92
      }
93
    });
94
  }
95

96
  private _matchesTarget(entity: Entity): boolean {
UNCOV
97
    return this.filter(entity) && (this.target === undefined || this.target === entity);
×
98
  }
99

100
  private _dispatchAction(target: Entity) {
101
    if (this.repeat !== 0) {
×
102
      this.action.call(this, target);
×
103
      this.repeat--;
×
104
    }
105
  }
106
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc