Skip to content

Commit

Permalink
feat: [#3283] Add tile enter/leave events to IsometricMap
Browse files Browse the repository at this point in the history
closes: #3283
  • Loading branch information
eonarheim committed Nov 24, 2024
1 parent 1e5e9f1 commit b06f3ff
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Added

- Added `pointerenter` and `pointerleave` events to `ex.TileMap` tiles!
- Added `pointerenter` and `pointerleave` events to `ex.IsometricMap` tiles!
- Added new `ex.BezierCurve` type for drawing cubic bezier curves
- Added 2 new actions `actor.actions.curveTo(...)` and `actor.actions.curveBy(...)`
- Added new `ex.lerp(...)`, `ex.inverseLerp(...)`, and `ex.remap(...)` for numbers
Expand Down
8 changes: 7 additions & 1 deletion sandbox/tests/isometric/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ isoMap2.tiles.forEach((t) => t.addGraphic(isoTileSprite));
game.currentScene.add(isoMap2);
for (const tile of isoMap2.tiles) {
tile.on('pointerdown', (evt: ex.PointerEvent) => {
console.log(tile.x, tile.y);
console.log('down', tile.x, tile.y);
});
tile.on('pointerenter', (evt: ex.PointerEvent) => {
console.log('enter', tile.x, tile.y);
});
tile.on('pointerleave', (evt: ex.PointerEvent) => {
console.log('leave', tile.x, tile.y);
});
}

Expand Down
40 changes: 26 additions & 14 deletions src/engine/TileMap/IsometricMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import { DebugConfig } from '../Debug';
import { PointerComponent } from '../Input/PointerComponent';
import { PointerEvent } from '../Input/PointerEvent';
import { EventEmitter } from '../EventEmitter';
import { HasNestedPointerEvents, PointerEventsToObjectDispatcher } from '../Input/PointerEventsToObjectDispatcher';
import { PointerEventReceiver } from '../Input/PointerEventReceiver';

export type IsometricTilePointerEvents = {
pointerup: PointerEvent;
pointerdown: PointerEvent;
pointermove: PointerEvent;
pointercancel: PointerEvent;
pointerenter: PointerEvent;
pointerleave: PointerEvent;
};

export class IsometricTile extends Entity {
Expand Down Expand Up @@ -258,7 +262,7 @@ export interface IsometricMapOptions {
* Please refer to the docs https://excaliburjs.com for more details calculating what your tile width and height should be given
* your art assets.
*/
export class IsometricMap extends Entity {
export class IsometricMap extends Entity implements HasNestedPointerEvents {
public readonly elevation: number = 0;

/**
Expand Down Expand Up @@ -313,6 +317,7 @@ export class IsometricMap extends Entity {
public pointer: PointerComponent;

private _composite!: CompositeCollider;
private _pointerEventDispatcher: PointerEventsToObjectDispatcher<IsometricTile>;

constructor(options: IsometricMapOptions) {
super(
Expand Down Expand Up @@ -350,6 +355,8 @@ export class IsometricMap extends Entity {
this.columns = width;
this.rows = height;

this._pointerEventDispatcher = new PointerEventsToObjectDispatcher();

this.tiles = new Array(width * height);

// build up tile representation
Expand All @@ -358,6 +365,11 @@ export class IsometricMap extends Entity {
const tile = new IsometricTile(x, y, this.graphicsOffset, this);
this.tiles[x + y * width] = tile;
this.addChild(tile);
this._pointerEventDispatcher.addObject(
tile,
(p) => this.getTileByPoint(p.worldPos) === tile,
() => true
);
}
}

Expand All @@ -366,29 +378,29 @@ export class IsometricMap extends Entity {
tileHeight * height * this.transform.scale.y,
vec(0.5, 0)
);

this._setupPointerToTile();
}

private _forwardPointerEventToTile = (eventType: string) => (evt: PointerEvent) => {
const tile = this.getTileByPoint(evt.worldPos);
if (tile) {
tile.events.emit(eventType, evt);
}
};
/**
* @internal
*/
public _processPointerToObject(receiver: PointerEventReceiver) {
this._pointerEventDispatcher.processPointerToObject(receiver, this.tiles);
}

private _setupPointerToTile() {
this.events.on('pointerup', this._forwardPointerEventToTile('pointerup') as any);
this.events.on('pointerdown', this._forwardPointerEventToTile('pointerdown') as any);
this.events.on('pointermove', this._forwardPointerEventToTile('pointermove') as any);
this.events.on('pointercancel', this._forwardPointerEventToTile('pointercancel') as any);
/**
* @internal
*/
public _dispatchPointerEvents(receiver: PointerEventReceiver) {
this._pointerEventDispatcher.dispatchEvents(receiver, this.tiles);
}

public update(): void {
if (this._collidersDirty) {
this.updateColliders();
this._collidersDirty = false;
}

this._pointerEventDispatcher.clear();
}

private _collidersDirty = false;
Expand Down
2 changes: 1 addition & 1 deletion src/engine/TileMap/TileMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export class TileMap extends Entity implements HasNestedPointerEvents {
public meshingLookBehind = 10;

private _collidersDirty = true;
private _pointerEventDispatcher: PointerEventsToObjectDispatcher<{ events: EventEmitter }>;
private _pointerEventDispatcher: PointerEventsToObjectDispatcher<Tile>;
public flagCollidersDirty() {
this._collidersDirty = true;
}
Expand Down

0 comments on commit b06f3ff

Please sign in to comment.