Skip to main content

Step 6 - Refactor to a Scene

Up to this point we've been using the default scene, which is great for small prototypes. However we want to keep main.ts clean so we'll move our game composition and initialization logic into a ex.Scene.

Create a new file called level.ts, we can put our initialization logic in onInitialize this will be called once before the scene is shown for the first time. If you need to have logic run when the scene is shown every time look at onActivate and onDeactivate.

It is often useful to stash common logic for your game in a scene, for example restarting, game over, saving state, etc.

typescript
// level.ts
import * as ex from 'excalibur';
import { Bird } from './bird';
import { Ground } from './ground';
import { Pipe } from './pipe';
export class Level extends ex.Scene {
bird: Bird = new Bird();
ground!: Ground;
override onInitialize(engine: ex.Engine): void {
this.add(this.bird);
this.ground = new Ground(ex.vec(0, engine.screen.drawHeight - 64))
this.add(this.ground);
const topPipe = new Pipe(ex.vec(engine.screen.drawWidth, 150), 'top');
this.add(topPipe);
const bottomPipe = new Pipe(ex.vec(engine.screen.drawWidth, 300), 'bottom');
this.add(bottomPipe);
}
}
typescript
// level.ts
import * as ex from 'excalibur';
import { Bird } from './bird';
import { Ground } from './ground';
import { Pipe } from './pipe';
export class Level extends ex.Scene {
bird: Bird = new Bird();
ground!: Ground;
override onInitialize(engine: ex.Engine): void {
this.add(this.bird);
this.ground = new Ground(ex.vec(0, engine.screen.drawHeight - 64))
this.add(this.ground);
const topPipe = new Pipe(ex.vec(engine.screen.drawWidth, 150), 'top');
this.add(topPipe);
const bottomPipe = new Pipe(ex.vec(engine.screen.drawWidth, 300), 'bottom');
this.add(bottomPipe);
}
}

Now in our main.ts we register the scene and go to the named scene after we start

typescript
// main.ts
import * as ex from 'excalibur';
import { Level } from './level';
const game = new ex.Engine({
...
scenes: { Level: Level }
});
game.start().then(() => {
game.goToScene('Level');
});
typescript
// main.ts
import * as ex from 'excalibur';
import { Level } from './level';
const game = new ex.Engine({
...
scenes: { Level: Level }
});
game.start().then(() => {
game.goToScene('Level');
});