Skip to content

Commit

Permalink
feat: New graphics events (#2877)
Browse files Browse the repository at this point in the history
This PR adds new graphics events and hooks that allow you to hook into graphics drawing before or after any drawing transformations have been applied
  * `Actor.graphics.onPreTransformDraw` with the corresponding event `.on('pretransformdraw')`
  * `Actor.graphics.onPostTransformDraw` with the corresponding event `.on('posttransformdraw')`

This is useful if you want to make changes to the transform or totally influence the draw transform DURING the draw step
  • Loading branch information
eonarheim authored Jan 11, 2024
1 parent c329263 commit eefe202
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Added

- New graphics events and hooks that allow you to hook into graphics drawing before or after any drawing transformations have been applied
* `Actor.graphics.onPreTransformDraw` with the corresponding event `.on('pretransformdraw')`
* `Actor.graphics.onPostTransformDraw` with the corresponding event `.on('posttransformdraw')`
- New property and methods overloads to `ex.Animation`
* `ex.Animation.currentFrameTimeLeft` will return the current time in milliseconds left in the current
* `ex.Animation.goToFrame(frameNumber: number, duration?: number)` now accepts an optional duration for the target frame
Expand Down
4 changes: 4 additions & 0 deletions src/engine/Actor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ export type ActorEvents = EntityEvents & {
postkill: PostKillEvent;
predraw: PreDrawEvent;
postdraw: PostDrawEvent;
pretransformdraw: PreDrawEvent;
posttransformdraw: PostDrawEvent;
predebugdraw: PreDebugDrawEvent;
postdebugdraw: PostDebugDrawEvent;
pointerup: PointerEvent;
Expand Down Expand Up @@ -182,6 +184,8 @@ export const ActorEvents = {
PostKill: 'postkill',
PreDraw: 'predraw',
PostDraw: 'postdraw',
PreTransformDraw: 'pretransformdraw',
PostTransformDraw: 'posttransformdraw',
PreDebugDraw: 'predebugdraw',
PostDebugDraw: 'postdebugdraw',
PointerUp: 'pointerup',
Expand Down
23 changes: 23 additions & 0 deletions src/engine/Events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,29 @@ export class PostDrawEvent extends GameEvent<Entity | Scene | Engine | TileMap>
}
}

/**
* The 'pretransformdraw' event is emitted on actors/entities before any graphics transforms have taken place.
* Useful if you need to completely customize the draw or modify the transform before drawing in the draw step (for example needing
* latest camera positions)
*
*/
export class PreTransformDrawEvent extends GameEvent<Entity> {
constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) {
super();
}
}

/**
* The 'posttransformdraw' event is emitted on actors/entities after all graphics have been draw and transforms reset.
* Useful if you need to completely custom the draw after everything is done.
*
*/
export class PostTransformDrawEvent extends GameEvent<Entity> {
constructor(public ctx: ExcaliburGraphicsContext, public delta: number, public target: Entity) {
super();
}
}

/**
* The 'predebugdraw' event is emitted on actors, scenes, and engine before debug drawing starts.
*/
Expand Down
12 changes: 11 additions & 1 deletion src/engine/Graphics/GraphicsComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ export class GraphicsComponent extends Component<'ex.graphics'> {
}

/**
* Draws after the entity transform has bene applied, but before graphics component graphics have been drawn
* Draws after the entity transform has been applied, but before graphics component graphics have been drawn
*/
public onPreDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;

Expand All @@ -287,6 +287,16 @@ export class GraphicsComponent extends Component<'ex.graphics'> {
*/
public onPostDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;

/**
* Draws before the entity transform has been applied before any any graphics component drawing
*/
public onPreTransformDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;

/**
* Draws after the entity transform has been applied, and after all graphics component drawing
*/
public onPostTransformDraw: (ctx: ExcaliburGraphicsContext, elapsedMilliseconds: number) => void;

/**
* Sets or gets wether any drawing should be visible in this component
*/
Expand Down
15 changes: 14 additions & 1 deletion src/engine/Graphics/GraphicsSystem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { ParallaxComponent } from './ParallaxComponent';
import { CoordPlane } from '../Math/coord-plane';
import { BodyComponent } from '../Collision/BodyComponent';
import { FontCache } from './FontCache';
import { PostDrawEvent, PreDrawEvent, Transform } from '..';
import { PostDrawEvent, PostTransformDrawEvent, PreDrawEvent, PreTransformDrawEvent } from '../Events';
import { Transform } from '../Math/transform';
import { blendTransform } from './TransformInterpolation';

export class GraphicsSystem extends System<TransformComponent | GraphicsComponent> {
Expand Down Expand Up @@ -92,6 +93,12 @@ export class GraphicsSystem extends System<TransformComponent | GraphicsComponen
continue;
}

// Optionally run the onPreTransformDraw graphics lifecycle draw
if (graphics.onPreTransformDraw) {
graphics.onPreTransformDraw(this._graphicsContext, delta);
}
entity.events.emit('pretransformdraw', new PreTransformDrawEvent(this._graphicsContext, delta, entity));

// This optionally sets our camera based on the entity coord plan (world vs. screen)
if (transform.coordPlane === CoordPlane.Screen) {
this._graphicsContext.restore();
Expand Down Expand Up @@ -152,6 +159,12 @@ export class GraphicsSystem extends System<TransformComponent | GraphicsComponen
this._camera.draw(this._graphicsContext);
}
}

// Optionally run the onPreTransformDraw graphics lifecycle draw
if (graphics.onPostTransformDraw) {
graphics.onPostTransformDraw(this._graphicsContext, delta);
}
entity.events.emit('posttransformdraw', new PostTransformDrawEvent(this._graphicsContext, delta, entity));
}
this._graphicsContext.restore();
}
Expand Down

0 comments on commit eefe202

Please sign in to comment.