Step 4 - Flying the Bird
We can take user input in Excalibur from keyboard, pointers (mouse, touch), and gamepads!
Let's setup an input handler to have the Bird jump when ever we hit the keyboard space bar or tap the screen.
For added flair, we can adjust the Bird's rotation by the speed that the level will be moving past 200 pixels per second.
typescript// bird.tsimport * as ex from 'excalibur';export class Bird extends ex.Actor {...jumping = false;private isInputActive(engine: ex.Engine) {// if the space bar or the first pointer was downreturn (engine.input.keyboard.isHeld(ex.Keys.Space) ||engine.input.pointers.isDown(0))}override onPostUpdate(engine: ex.Engine): void {if (!this.jumping && this.isInputActive(engine)) {this.vel.y += -800; // negative is UPthis.jumping = true;}if (!this.isInputActive(engine)) {this.jumping = false;}// keep velocity from getting too bigthis.vel.y = ex.clamp(this.vel.y, -500, 500);// The "speed" the bird will move relative to pipesthis.rotation = ex.vec(200, this.vel.y).toAngle();}...}
typescript// bird.tsimport * as ex from 'excalibur';export class Bird extends ex.Actor {...jumping = false;private isInputActive(engine: ex.Engine) {// if the space bar or the first pointer was downreturn (engine.input.keyboard.isHeld(ex.Keys.Space) ||engine.input.pointers.isDown(0))}override onPostUpdate(engine: ex.Engine): void {if (!this.jumping && this.isInputActive(engine)) {this.vel.y += -800; // negative is UPthis.jumping = true;}if (!this.isInputActive(engine)) {this.jumping = false;}// keep velocity from getting too bigthis.vel.y = ex.clamp(this.vel.y, -500, 500);// The "speed" the bird will move relative to pipesthis.rotation = ex.vec(200, this.vel.y).toAngle();}...}
Heads up!
After adding the flap/jump logic, you may notice a strange behavior:
if the Bird hits the ground and "dies," pressing the jump key one more time will cause the Bird to shoot upward infinitely.
This happens because we haven't added any game-over or collision-lockout logic yet—so the Bird is still allowed to receive input even after crashing.
Don't worry! This is expected at this stage of the tutorial.
We'll fix this behavior later once we introduce proper game-over handling.