diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f34e15ba..48f8b1980 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/sandbox/tests/isometric/index.ts b/sandbox/tests/isometric/index.ts index dd3b07146..d6fce2584 100644 --- a/sandbox/tests/isometric/index.ts +++ b/sandbox/tests/isometric/index.ts @@ -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); }); } diff --git a/src/engine/TileMap/IsometricMap.ts b/src/engine/TileMap/IsometricMap.ts index faa9fc2ce..e861c8a17 100644 --- a/src/engine/TileMap/IsometricMap.ts +++ b/src/engine/TileMap/IsometricMap.ts @@ -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 { @@ -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; /** @@ -313,6 +317,7 @@ export class IsometricMap extends Entity { public pointer: PointerComponent; private _composite!: CompositeCollider; + private _pointerEventDispatcher: PointerEventsToObjectDispatcher; constructor(options: IsometricMapOptions) { super( @@ -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 @@ -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 + ); } } @@ -366,22 +378,20 @@ 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 { @@ -389,6 +399,8 @@ export class IsometricMap extends Entity { this.updateColliders(); this._collidersDirty = false; } + + this._pointerEventDispatcher.clear(); } private _collidersDirty = false; diff --git a/src/engine/TileMap/TileMap.ts b/src/engine/TileMap/TileMap.ts index 5a985e32e..fbebaaeaf 100644 --- a/src/engine/TileMap/TileMap.ts +++ b/src/engine/TileMap/TileMap.ts @@ -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; public flagCollidersDirty() { this._collidersDirty = true; }