Phaser 3 Example #2

In this example, I want to create a larger Phaser 3 scene – world with a background image.

This scene uses the prior example ( Phase 3 Examples Project – Sprite Control Example ).

BackGroundScene

class BackGroundScene extends Phaser.Scene {
private cursors: Phaser.Types.Input.Keyboard.CursorKeys;
private spaceship: Phaser.Physics.Arcade.Sprite;
private pointer: Phaser.Input.Pointer;
private touch: Phaser.Input.Pointer;
constructor() {
super({
key: 'BackGroundScene'
});
}
preload() {
this.load.image('ship', 'assets/sh2.png'); //the space ship 
this.load.image('background', 'assets/sb.jpg');//the back ground image for the scene
}
create() {
console.log('BackGroundScene scene create');
/*
setting camera bound to the same as the world bounds will keep the camera from showing
blank canvas outside of the background image/
*/
this.cameras.main.setBounds(0, 0, 4000, 4000);
this.physics.world.setBounds(0, 0, 4000, 4000);
/*
background images is 500x500 world is 4000x4000
This image does not scael well, another option
would be to display it not scaled 4 times 0,0 0,500 500,0 500,500
*/
this.add.image(0, 0, 'background').setOrigin(0).setScale(8);
this.spaceship = this.physics.add.sprite(this.game.scale.parentSize.width / 2, this.game.scale.parentSize.height / 2, 'ship');
this.spaceship.setDrag(35);//https://photonstorm.github.io/phaser3-docs/Phaser.Physics.Arcade.Components.Drag.html#setDrag
let menuItem: Phaser.GameObjects.Text = this.add.text(15, 15, "Home", { fontFamily: 'Verdana, "Times New Roman", Tahoma, serif', fontSize: 25, color: '#3333ff' });
menuItem.setInteractive({ cursor: 'pointer' }).on('pointerdown', () => { this.scene.start('MenuScene'); });
menuItem.setScrollFactor(0) //I believe in Phaser 2 you could lock things to camera with fixedToCamera, https://photonstorm.github.io/phaser3-docs/Phaser.GameObjects.Components.ScrollFactor.html#setScrollFactor
this.cursors = this.input.keyboard.createCursorKeys();
this.spaceship.setCollideWorldBounds(true);
this.pointer = this.input.activePointer;//https://photonstorm.github.io/phaser3-docs/Phaser.Input.Pointer.html
this.touch = this.input.pointer1;
this.cameras.main.startFollow(this.spaceship, true, 0.05, 0.05);
}
update() {
if (this.pointer.isDown) {
this.SetVelocityAndRotation(this.pointer);
} else if (this.touch.isDown) {
this.SetVelocityAndRotation(this.touch);
}
if (this.cursors.left.isDown) {
this.spaceship.angle -= 1;
}
if (this.cursors.right.isDown) {
this.spaceship.angle += 1
}
if (this.cursors.up.isDown) {
let velocity: Phaser.Math.Vector2 = new Phaser.Math.Vector2()
this.physics.velocityFromRotation(this.spaceship.rotation, 150, velocity);
this.spaceship.setVelocity(velocity.x, velocity.y);
}
if (this.cursors.down.isDown) {
this.spaceship.setVelocity(0);
}
}
SetVelocityAndRotation(pointer: Phaser.Input.Pointer) {
let velocity: Phaser.Math.Vector2 = new Phaser.Math.Vector2();
let pointerWorld: Phaser.Geom.Point = new Phaser.Geom.Point(pointer.worldX, pointer.worldY);
/*
BetweenPoints seemed to work great in the last example
But it seemed to fail here in a larger world.
Creating a point using the pointer world coordinates
seems to work better but still seeing a few issues now and then.
*/
this.spaceship.rotation = Phaser.Math.Angle.BetweenPoints(this.spaceship, pointerWorld);//https://photonstorm.github.io/phaser3-docs/Phaser.Math.Angle.html#.BetweenPoints__anchor
this.physics.velocityFromRotation(this.spaceship.rotation, 150, velocity);//https://photonstorm.github.io/phaser3-docs/Phaser.Physics.Arcade.ArcadePhysics.html#velocityFromRotation__anchor
this.spaceship.setVelocity(velocity.x, velocity.y);//https://photonstorm.github.io/phaser3-docs/Phaser.Physics.Arcade.Components.Velocity.html#setVelocity__anchor
}
}
export default BackGroundScene

With the larger world size, the velocityFromRotation had issues. I believe because the pointer.x/y should be worldX/WorldY. Passing in those values instead seemed to correct the issues

In the last example, I had issues on my laptop if I used the touch screen I could no longer use the mouse using the activePointer.

I now use both the touch and mouse pointer instead and that does work but I still believe just using activePointer should work and will continue looking into that.

With the larger world and camera follow I found the ‘home’ to return to menu text would disappear as the sprite flew around.

In Phaser 2 you would use fixedToCamera on text/buttons you wanted to be locked to a position. After some looking through examples I found setScrollFactor allows you to lock it or semi-lock it which looks like it could be useful for other hud/motion effects.

Other Changes

Phaser Examples Menu Scene with addition of Back Ground scene
Phaser Examples Menu Scene

Besides adding the new scene/example to the menu scene I did some rewriting as in the future it will become longer and harder to work with.

class MenuScene extends Phaser.Scene {
private menuItems: Phaser.GameObjects.Text[];
constructor() {
super({
key: 'MenuScene'
});
}
create(): void {
console.log('menu scene create');
this.menuItems = new Array<Phaser.GameObjects.Text>();
let center = this.game.scale.parentSize.width / 2 - 275; //https://photonstorm.github.io/phaser3-docs/Phaser.Scale.ScaleManager.html#parentSize__anchor
this.add.text(center, 25, "Phaser Examples", { fontFamily: 'Verdana, "Times New Roman", Tahoma, serif', fontSize: 64, color: '#ffffff' })
.setTintFill(0xff0000,0x00ff00,0x0000ff,0xffffff);
let items = Array(
{ text: "Sprite movement control (mouse / keyboard)", scene: "SpriteSpaceShipScene" },
{ text: 'Back Ground Scene', scene: 'BackGroundScene' });
items.forEach(item => {
this.addMenuItem(item);
});
}
addMenuItem(menuItem: { text: string, scene: string }): void {
let y: number = 100;
y += (this.menuItems.length * 50);
let item: Phaser.GameObjects.Text = this.add.text(this.game.scale.parentSize.width / 2 - 275, y, menuItem.text, { fontFamily: 'Verdana, "Times New Roman", Tahoma, serif', fontSize: 32, color: '#ffffff' });
item.setInteractive({ cursor: 'pointer' }).on('pointerdown', () => { this.scene.start(menuItem.scene); });
this.menuItems.push(item);
}
}
export default MenuScene

This still isn’t what I have in my head but is moving closer to it. I either will consider some sort of pagination or breaking down examples into categories.

With just a couple of menu items, things work great but if I end up with dozens of examples the menu will both be hard to work with and hard for users to understand.

For now, I stopped the pointerover and pointerout events and just set a cursor: ‘pointer’

I also demonstrate setTintFill on a Phaser 3 text object.

Leave a comment

Your email address will not be published. Required fields are marked *