diff --git a/CHANGELOG.md b/CHANGELOG.md index a3900860d..b35ccf17c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,12 +15,16 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Added new `transitionstart` and `transitionend` events to `ex.Scenes` +- Pipe `navigation*` events to `ex.Engine` - Added ability to use `ex.Vector` to specify offset and margin in `SpriteSheet.fromImageSource({..})` - New PostProcessor.onDraw() hook to handle uploading textures - Adds contact solve bias to RealisticSolver, this allows customization on which direction contacts are solved first. By default there is no bias set to 'none'. ### Fixed +- Fixed `onTransition` on the initial scene transition +- Fixed `ex.TriggerOptions` type to all optional parameters - Fixed issue where the ActorArgs type hint would not error when providing a color causing confusion when it didn't produce a default graphic. - Fixed false positive warning when adding timers - Fixed issue where gamepad buttons wouldn't progress the default loader play button diff --git a/sandbox/src/game.ts b/sandbox/src/game.ts index 3337e9e66..e30db4fda 100644 --- a/sandbox/src/game.ts +++ b/sandbox/src/game.ts @@ -85,15 +85,43 @@ var game = new ex.Engine({ threshold: { fps: 20, numberOfFrames: 100 } } }); + +game.currentScene.onTransition = () => { + console.log('initial scene transition'); +}; + +game.on('navigation', (evt) => { + console.log('navigation', evt); +}); + +game.on('navigationstart', (evt) => { + console.log('navigationstart', evt); +}); + +game.on('navigationend', (evt) => { + console.log('navigationend', evt); +}); + game.screen.events.on('fullscreen', (evt) => { console.log('fullscreen', evt); }); + game.screen.events.on('resize', (evt) => { console.log('resize', evt); }); + game.screen.events.on('pixelratio', (evt) => { console.log('pixelratio', evt); }); + +game.currentScene.on('transitionstart', (evt) => { + console.log('transitionstart', evt); +}); + +game.currentScene.on('transitionend', (evt) => { + console.log('transitionend', evt); +}); + game.currentScene.onPreDraw = (ctx: ex.ExcaliburGraphicsContext) => { ctx.save(); ctx.z = 99; @@ -879,6 +907,15 @@ player.on('pointerwheel', () => { }); var newScene = new ex.Scene(); + +newScene.on('transitionstart', (evt) => { + console.log('transitionstart', evt); +}); + +newScene.on('transitionend', (evt) => { + console.log('transitionend', evt); +}); + newScene.backgroundColor = ex.Color.ExcaliburBlue; newScene.add(new ex.Label({ text: 'MAH LABEL!', x: 200, y: 100 })); newScene.on('activate', (evt?: ex.ActivateEvent) => { diff --git a/src/engine/Actor.ts b/src/engine/Actor.ts index 73fe61521..cf4a6263c 100644 --- a/src/engine/Actor.ts +++ b/src/engine/Actor.ts @@ -253,7 +253,7 @@ export const ActorEvents = { ExitViewPort: 'exitviewport', ActionStart: 'actionstart', ActionComplete: 'actioncomplete' -}; +} as const; /** * The most important primitive in Excalibur is an `Actor`. Anything that diff --git a/src/engine/Director/Director.ts b/src/engine/Director/Director.ts index 51cf05d65..6e5d7624f 100644 --- a/src/engine/Director/Director.ts +++ b/src/engine/Director/Director.ts @@ -24,7 +24,7 @@ export const DirectorEvents = { NavigationStart: 'navigationstart', Navigation: 'navigation', NavigationEnd: 'navigationend' -}; +} as const; export interface SceneWithOptions { /** @@ -233,6 +233,7 @@ export class Director { // eslint-disable-next-line @typescript-eslint/no-floating-promises maybeStartTransition._addToTargetScene(this._engine, startSceneInstance); this.swapScene(this.startScene).then(() => { + startSceneInstance.onTransition('in'); // eslint-disable-next-line @typescript-eslint/no-floating-promises return this.playTransition(maybeStartTransition, startSceneInstance); }); @@ -541,8 +542,10 @@ export class Director { targetScene.input?.toggleEnabled(!transition.blockInput); this._engine.input?.toggleEnabled(!transition.blockInput); + targetScene.events.emit('transitionstart', transition); this.currentTransition._addToTargetScene(this._engine, targetScene); await this.currentTransition._play(); + targetScene.events.emit('transitionend', transition); targetScene.input?.toggleEnabled(sceneInputEnabled); } diff --git a/src/engine/Engine.ts b/src/engine/Engine.ts index d3c216e05..baaa5a598 100644 --- a/src/engine/Engine.ts +++ b/src/engine/Engine.ts @@ -48,7 +48,7 @@ import { ImageFiltering } from './Graphics/Filtering'; import { GraphicsDiagnostics } from './Graphics/GraphicsDiagnostics'; import { Toaster } from './Util/Toaster'; import { InputMapper } from './Input/InputMapper'; -import { GoToOptions, SceneMap, Director, StartOptions, SceneWithOptions, WithRoot } from './Director/Director'; +import { GoToOptions, SceneMap, Director, StartOptions, SceneWithOptions, WithRoot, DirectorEvents } from './Director/Director'; import { InputHost } from './Input/InputHost'; import { getDefaultPhysicsConfig, PhysicsConfig } from './Collision/PhysicsConfig'; import { DeepRequired } from './Util/Required'; @@ -56,7 +56,7 @@ import { Context, createContext, useContext } from './Context'; import { DefaultGarbageCollectionOptions, GarbageCollectionOptions, GarbageCollector } from './GarbageCollector'; import { mergeDeep } from './Util/Util'; -export type EngineEvents = { +export type EngineEvents = DirectorEvents & { fallbackgraphicscontext: ExcaliburGraphicsContext2DCanvas; initialize: InitializeEvent; visible: VisibleEvent; @@ -83,7 +83,8 @@ export const EngineEvents = { PreFrame: 'preframe', PostFrame: 'postframe', PreDraw: 'predraw', - PostDraw: 'postdraw' + PostDraw: 'postdraw', + ...DirectorEvents } as const; /** @@ -1052,6 +1053,7 @@ O|===|* >________________>\n\ this.debug = new DebugConfig(this); this.director = new Director(this, options.scenes); + this.director.events.pipe(this.events); this._initialize(options); diff --git a/src/engine/Scene.ts b/src/engine/Scene.ts index 0ce3ce2ed..354ab383a 100644 --- a/src/engine/Scene.ts +++ b/src/engine/Scene.ts @@ -55,6 +55,8 @@ export type SceneEvents = { predebugdraw: PreDebugDrawEvent; postdebugdraw: PostDebugDrawEvent; preload: PreLoadEvent; + transitionstart: Transition; + transitionend: Transition; }; export const SceneEvents = { @@ -67,8 +69,10 @@ export const SceneEvents = { PostDraw: 'postdraw', PreDebugDraw: 'predebugdraw', PostDebugDraw: 'postdebugdraw', - PreLoad: 'preload' -}; + PreLoad: 'preload', + TransitionStart: 'transitionstart', + TransitionEnd: 'transitionend' +} as const; export type SceneConstructor = new (...args: any[]) => Scene; /**