Migration
Migrating from v0.28.x to v0.29.0
-
ex.Entity.tags
is now a javascriptSet
instead of anArray
this will affect methods that inspected tags as an array before. -
ex.SpriteSheet.getSprite(...)
will now throw on invalid sprite coordinates, this is likely always an error and a warning is inappropriate. This also has the side benefit that you will always get a definite type out of the method. -
Changed the
Font
default base align toTop
this is more in line with user expectations. This does change the default rendering to the top left corner of the font instead of the bottom left. -
ex.Physics
static is marked as deprecated, configuring these setting will move to theex.Engine({...})
constructortypescriptconst engine = new ex.Engine({...physics: {solver: ex.SolverStrategy.Realistic,gravity: ex.vec(0, 20),arcade: {contactSolveBias: ex.ContactSolveBias.VerticalFirst},}})typescriptconst engine = new ex.Engine({...physics: {solver: ex.SolverStrategy.Realistic,gravity: ex.vec(0, 20),arcade: {contactSolveBias: ex.ContactSolveBias.VerticalFirst},}}) -
ex.Engine.goToScene
's second argument now takesGoToOptions
instead of just scene activation datatypescriptgame.goToScene('myscene', {/*** Optionally supply scene activation data passed to Scene.onActivate*/sceneActivationData?: TActivationData,/*** Optionally supply destination scene "in" transition, this will override any previously defined transition*/destinationIn?: Transition,/*** Optionally supply source scene "out" transition, this will override any previously defined transition*/sourceOut?: Transition,/*** Optionally supply a different loader for the destination scene, this will override any previously defined loader*/loader?: DefaultLoader});typescriptgame.goToScene('myscene', {/*** Optionally supply scene activation data passed to Scene.onActivate*/sceneActivationData?: TActivationData,/*** Optionally supply destination scene "in" transition, this will override any previously defined transition*/destinationIn?: Transition,/*** Optionally supply source scene "out" transition, this will override any previously defined transition*/sourceOut?: Transition,/*** Optionally supply a different loader for the destination scene, this will override any previously defined loader*/loader?: DefaultLoader}); -
ECS components and system are now simplified to not require a string type name, now they just use the runtime type name instead.
- On your components remove the type argument
class MyComponent extends Component<'mycomponent'>
toclass MyComponent extends Component
- On your systems remove the type arguments
class MySystem extends System<MyComponent>
toclass MySystem extends System
- Systems no longer get magically passed the entities in
System.update()
you now must create an explicitquery
. Queries automatically get updatedtypescriptexport class MyComponent extends Component {data = 'foo';}class MySystem extends System {systemType = SystemType.Update;query: Query<typeof MyComponent>;constructor(world: World) {super();this.query = world.query([MyComponent]);}update(elapsedMs: number): void {for (let entity of this.query.entities) {const myComponent = entity.get(MyComponent);console.log(myComponent.data);}}}typescriptexport class MyComponent extends Component {data = 'foo';}class MySystem extends System {systemType = SystemType.Update;query: Query<typeof MyComponent>;constructor(world: World) {super();this.query = world.query([MyComponent]);}update(elapsedMs: number): void {for (let entity of this.query.entities) {const myComponent = entity.get(MyComponent);console.log(myComponent.data);}}}
- On your components remove the type argument
-
Graphics components no longer support layering built in, they now ONLY hold 1 graphic at a time. WIth this
actor.graphics.show()
is now deprecated. This change simplifies usage of graphics for folks building games and removes complexity caused by supporting layering and multiple graphics in Excalibur.- To use layering use
- A GraphicsGroup, you can specify a list of graphics in painter order (first is draw first, then so on)
typescriptconst actor = new ex.Actor({...});const graphicsGroup = new ex.GraphicsGroup({members: [new ex.Rectangle({width: 100, height: 100, color: ex.Color.Red}),{ offset: ex.vec(100, 100), graphic: new ex.Circle({radius: 100, color: ex.Color.Blue})}]});actor.graphics.use(graphicsGroup);typescriptconst actor = new ex.Actor({...});const graphicsGroup = new ex.GraphicsGroup({members: [new ex.Rectangle({width: 100, height: 100, color: ex.Color.Red}),{ offset: ex.vec(100, 100), graphic: new ex.Circle({radius: 100, color: ex.Color.Blue})}]});actor.graphics.use(graphicsGroup);
- Child actors if you need more control over graphic movement, transform, or behavior
typescriptconst actor = new ex.Actor({...});const child = new ex.Actor({pos: ex.vec(100, 100),rotation: Math.PI / 4,scale: ex.vec(3, 3)});actor.addChild(child);actor.graphics.use(new ex.Rectangle({width: 100, height: 100, color: ex.Color.Red}));child.graphics.use(new ex.Rectangle({width: 10, height: 10, color: ex.Color.Blue}));typescriptconst actor = new ex.Actor({...});const child = new ex.Actor({pos: ex.vec(100, 100),rotation: Math.PI / 4,scale: ex.vec(3, 3)});actor.addChild(child);actor.graphics.use(new ex.Rectangle({width: 100, height: 100, color: ex.Color.Red}));child.graphics.use(new ex.Rectangle({width: 10, height: 10, color: ex.Color.Blue}));
- A GraphicsGroup, you can specify a list of graphics in painter order (first is draw first, then so on)
- To use layering use
Migrating from v0.26.0 to v0.27.0
-
ex.Engine.snapToPixel
now defaults tofalse
, it was unexpected to have pixel snapping on by default it has now been switched. You may need to explicitly switch it depending on your desired effect. -
The
ex.Physics.useRealisticPhysics()
physics solver has been updated to fix a bug in bounciness to be more physically accurate, this does change how physics behaves. Settingex.Body.bounciness = 0
will simulate the old behavior. -
ex.TransformComponent.getGlobalMatrix()
has been removed, use this insteadtypescriptconst actor = new ex.Actor({...});const transform = actor.get(TransformComponent);const matrix = transform.get().matrix;typescriptconst actor = new ex.Actor({...});const transform = actor.get(TransformComponent);const matrix = transform.get().matrix; -
ex.TransformComponent.posChanged$
has been removed, it incurs a steep performance cost. -
ex.EventDispatcher
meta events 'subscribe' and 'unsubscribe' were unused and undocumented and have been removed. -
ex.TileMap
tiles are now drawn from the lower left by default to match withex.IsometricMap
and Tiled, but can be configured withrenderFromTopOfGraphic
to restore the previous behavior.typescriptconst tilemap = new ex.TileMap({...renderFromTopOfGraphic: true})typescriptconst tilemap = new ex.TileMap({...renderFromTopOfGraphic: true}) -
Scene
onActivate
andonDeactivate
methods have been changed to receive a single context parameter, an object containing thepreviousScene
,nextScene
, and optionaldata
passed in fromgoToScene()
. Update anyonActivate
oronDeactivate
handlerstypescriptonActivate(ctx: SceneActivationContext<TActivationData>) {...}typescriptonActivate(ctx: SceneActivationContext<TActivationData>) {...}
Migrating from v0.25.3 to v0.26.0
The old drawing API had been removed from excalibur, this should not affect you unless you were using the ex.Flags.useLegacyDrawing()
. If so you must switch to the new graphics api.
ex.TileMap
has several breaking changes around naming, but brings it consistent with Tiled terminology and the new ex.IsometricMap
. Additionally the new names are easier to follow.
- Constructor has been changed to the following
typescriptnew ex.TileMap({pos: ex.vec(100, 100),tileWidth: 64,tileHeight: 48,rows: 20,columns: 20,})typescriptnew ex.TileMap({pos: ex.vec(100, 100),tileWidth: 64,tileHeight: 48,rows: 20,columns: 20,})
ex.Cell
has been renamed toex.Tile
ex.Tile
now usesaddGraphic(...)
,removeGraphic(...)
,clearGraphics()
andgetGraphics()
instead of having an accessibleex.Tile.graphics
array.
ex.TileMap.data
has been renamed toex.TileMap.tiles
ex.TileMap.getCell(..)
has been renamed toex.TileMap.getTile(...)
ex.TileMap.getCellByIndex(...)
has been renamed toex.TileMap.getTileByIndex(...)
ex.TileMap.getCellByPoint(...)
has been renamed toex.TileMap.getTileByPoint(...)
The following types have been removed:
ex.SortedList
old sorted list is removed, use the built in browser Array.sortex.Collection
old collection type is removed, use the built in browser Arrayex.Util
import site, exported code promotedex.*
ex.DisplayMode.Position
is removed, use CSS to position the canvasex.Trait
interface, traits are not longer supportedex.Promises
old promise implementation is removed in favor of browser promises
Notable method & property removals
ex.Actor
.getZIndex()
and.setZIndex()
removed use.z
ex.Scene
.screenElements
removed in favor of.entities
.addScreenElement(...)
removed use.add(...)
.addTileMap(...)
removed use.add(...)
.removeTileMap(...)
removed use.remove(...)
ex.Timer
.unpause()
removed use.resume()
ex.Camera
.rx
removed use.angularVelocity
ex.BodyComponent
.sx
removed use.scaleFactor
.rx
removed use.angularVelocity
ex.ActionsComponent
.asPromise()
removed use.toPromise()
ex.ActionContext
.asPromise()
removed use.toPromise()
ex.Color
- Misspellings corrected
Migrating from v0.25.1 to v0.25.2
- EventEmitter no longer tampers with
this
on the event callbacks which may be a breaking change for some people. Change callbacks's to be an arrow function to capturethis
typescript
class MyActor extends ex.Actor {constructor() {super()// Change from thisthis.on('precollision', this.onPreCollision)// To thisthis.on('precollision', (evt) => this.onPreCollision(evt))}}
typescript
class MyActor extends ex.Actor {constructor() {super()// Change from thisthis.on('precollision', this.onPreCollision)// To thisthis.on('precollision', (evt) => this.onPreCollision(evt))}}
Migrating from v0.24.5 to v0.25.0
Graphics
-
Replace
ex.Texture
withex.ImageSource
-
Replace
ex.Texture.asSprite()
withex.ImageSource.toSprite()
typescript
const image = new ex.ImageSource('./img/myimage.png')// keep in mind this wont work until the image source is loadedconst sprite = image.toSprite()
typescript
const image = new ex.ImageSource('./img/myimage.png')// keep in mind this wont work until the image source is loadedconst sprite = image.toSprite()
- Update
ex.Sprite
constructor arguments
typescript
const image = new ex.ImageSource('./path/to/image.png')const sprite = new ex.Sprite({image: image,sourceView: {// Take a small slice of the source image starting at pixel (10, 10) with dimension 20 pixels x 20 pixelsx: 10,y: 10,width: 20,height: 20,},destSize: {// Optionally specify a different projected size, otherwise use the sourcewidth: 100,height: 100,},})
typescript
const image = new ex.ImageSource('./path/to/image.png')const sprite = new ex.Sprite({image: image,sourceView: {// Take a small slice of the source image starting at pixel (10, 10) with dimension 20 pixels x 20 pixelsx: 10,y: 10,width: 20,height: 20,},destSize: {// Optionally specify a different projected size, otherwise use the sourcewidth: 100,height: 100,},})
- Update
new ex.SpriteSheet()
constructor withex.SpriteSheet.fromImageSource()
typescript
const runImage = new ex.ImageSource(runImageSrc)const runSheet = ex.SpriteSheet.fromImageSource({image: runImage,grid: {rows: 1,columns: 21,spriteWidth: 96,spriteHeight: 96,},})
typescript
const runImage = new ex.ImageSource(runImageSrc)const runSheet = ex.SpriteSheet.fromImageSource({image: runImage,grid: {rows: 1,columns: 21,spriteWidth: 96,spriteHeight: 96,},})
-
Replace Legacy Drawing Usage
ex.Actor.addDrawing()
withex.Actor.graphics.add()
ex.Actor.setDrawing()
withex.Actor.graphics.use()
orex.Actor.graphics.show()
-
Replace Legacy
ex.Actor.onPostDraw
andex.Actor.onPreDraw
withactor.graphics
orex.Canvas
typescript
const canvas = new ex.Canvas({cache: true,draw: (ctx: CanvasRenderingContext2D) => {// custom drawing with CanvasRenderingContext2D},})actor.use(canvas)actor.graphics.onPreDraw = (exctx: ExcaliburGraphicsContext) => {// custom drawing with ExcaliburGraphicsContext}actor.graphics.onPostDraw = (exctx: ExcaliburGraphicsContext) => {// custom drawing with ExcaliburGraphicsContext}
typescript
const canvas = new ex.Canvas({cache: true,draw: (ctx: CanvasRenderingContext2D) => {// custom drawing with CanvasRenderingContext2D},})actor.use(canvas)actor.graphics.onPreDraw = (exctx: ExcaliburGraphicsContext) => {// custom drawing with ExcaliburGraphicsContext}actor.graphics.onPostDraw = (exctx: ExcaliburGraphicsContext) => {// custom drawing with ExcaliburGraphicsContext}
Actors
- Actor only supports the option bag constructor
new ex.Actor({...})
- Label only supports the option bag constructor
new ex.Label({...})
- Replace
ex.Actor.rx
withex.Actor.angularVelocity
Camera
ex.Camera.z
has been renamed to propertyex.Camera.zoom
which is the zoom factorex.Camera.zoom(...)
has been renamed to functionex.Camera.zoomOverTime()
Engine
-
DisplayMode
's have changed (#1733) & (#1928):DisplayMode.FitContainer
fits the screen to the available width/height in the canvas parent element, while maintaining aspect ratio and resolutionDisplayMode.FillContainer
update the resolution and viewport dynamically to fill the available space in the canvas parent element, DOES NOT preserveaspectRatio
DisplayMode.FitScreen
fits the screen to the available browser window space, while maintaining aspect ratio and resolutionDisplayMode.FillScreen
now does whatDisplayMode.FullScreen
used to do, the resolution and viewport dynamically adjust to fill the available space in the window, DOES NOT preserveaspectRatio
(#1733)DisplayMode.FullScreen
is now removed, useScreen.goFullScreen()
.
Physics
- Rename
ex.Edge
toex.EdgeCollider
andex.ConvexPolygon
toex.PolygonCollider
Timer
- Timers must be added to a scene and
Timer.start()
called for them to start Timer.unpause()
has be deprecated in favor ofTimer.resume()
(#1864)
Actions
- Rewrite
ex.Actor.actions.repeat()
andex.Actor.actions.repeatForever()
to use thectx
to define the set of repeating actions
typescript
const actor = new ex.Actor()actor.actions// Move up in a zig-zag by repeating 5 times.repeat((ctx) => {ctx.moveBy(10, 0, 10)ctx.moveBy(0, 10, 10)}, 5).callMethod(() => {console.log('Done repeating!')})
typescript
const actor = new ex.Actor()actor.actions// Move up in a zig-zag by repeating 5 times.repeat((ctx) => {ctx.moveBy(10, 0, 10)ctx.moveBy(0, 10, 10)}, 5).callMethod(() => {console.log('Done repeating!')})
TileMap
- TileMap no longer needs registered SpriteSheets,
Sprite
's can be added directly toCell
's withaddGraphic
- The confusing
TileSprite
type is removed (Related to TileMap plugin updates https://github.com/excaliburjs/excalibur-tiled/issues/4, https://github.com/excaliburjs/excalibur-tiled/issues/23, https://github.com/excaliburjs/excalibur-tiled/issues/108)
- The confusing