Reputation: 321
I'm trying to create upgrades for my player.
I have the player stats in game.js (for example let player_speed = 300
).
I've created another scene that contains the UI of the upgrades like so:
upgradeScene.js
import IncreaseSpeed from './Upgrades/increase_speed.js';
import IncreaseDamage from './Upgrades/increase_damage.js';
import IncreaseFireRate from './Upgrades/increase_firerate.js';
export default class Upgrade extends Phaser.Scene {
constructor() {
super('upgradeScene');
}
preload() {
this.load.image('bg', 'Assets/UI/bg.png');
}
create() {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const screenCenterY = this.cameras.main.worldView.y + this.cameras.main.height / 2;
bg = this.add.image(screenCenterX, screenCenterY, 'bg').setAlpha(0.5);
title = this.add.text(screenCenterX, screenCenterY - 300, 'UPGRADES', {
fontFamily: 'dogicaPixel',
fontSize: '40px',
align: 'center'
}).setOrigin(0.5);
p = this.add.text(screenCenterX, screenCenterY - 260, 'lorem ipsum dolor sit amet', {
fontFamily: 'dogicaPixel',
fontSize: '15px',
align: 'center'
}).setOrigin(0.5);
this.scene.add(this, IncreaseSpeed, true);
this.scene.add(this, IncreaseDamage, true);
this.scene.add(this, IncreaseFireRate, true);
Increase_speed.js
export default class IncreaseSpeed extends Phaser.Scene {
constructor() {
super('increase_speed');
}
preload() {
this.load.image('cardbg', './Assets/UI/cardbg.png');
}
create() {
const screenCenterX = this.cameras.main.worldView.x + this.cameras.main.width / 2;
const screenCenterY = this.cameras.main.worldView.y + this.cameras.main.height / 2;
rectC = this.add.image(0, 0, 'cardbg');
increase_speed_title = this.add.text(0, -100, 'Increase\nSpeed', {
fontFamily: 'dogicaPixel',
fontSize: '20px',
align: 'center'
}).setOrigin(0.5);
increase_speed_description = this.add.text(0, 0, 'Lorem ipsum\ndolor sit amet', {
fontFamily: 'dogicaPixel',
fontSize: '15px',
align: 'center'
}).setOrigin(0.5);
increase_speed_btn = this.add.text(0, 120, 'UPGRADE', {
fontFamily: 'dogicaPixel',
fontSize: '20px',
align: 'center'
}).setOrigin(0.5).setInteractive();
cardC = this.add.container(screenCenterX, screenCenterY, [rectC, increase_speed_title, increase_speed_description, increase_speed_btn]);
// increase_speed_btn.on('pointerdown', () => {
// console.log('test');
// });
}
update() {
increase_speed_btn.on('pointerover', function (pointer) {
increase_speed_btn.setScale(1.5);
})
increase_speed_btn.on('pointerout', function (pointer) {
increase_speed_btn.setScale(1);
})
}
}
I would like to increase the player_speed when you click on the button in order to set the upgrade.
I'm still learning, I've done research about that but I'm confused cause I haven't find a way to 'communicate' between scenes.
Upvotes: 1
Views: 1714
Reputation: 14820
You can communicate between scene with the Phaser EventEmitters (link to Documentation). You just have to emit
and listen(on
) on the same Emitter.
In this case, after adding the scene, you get the correct Emitter, with this.scene.get(...).events
.
Here a small working demo:
(Just click the red "Click me" text)
document.body.style = 'margin:0;';
class Scene2 extends Phaser.Scene {
constructor(){
super('scene2');
}
create() {
this.add.text(10, 40, 'SCEEN-SPEED', {color: '#ff0000'}).setOrigin(0);
let button = this.add.text(10, 70, 'CLICK ME => 100 SPEED', {color: '#ff0000', fontStyle: 'bold'})
.setOrigin(0)
.setInteractive()
.on('pointerdown', () => this.events.emit('speed-increase', 100));
}
}
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
scene: {
key: 'scene1',
create,
update
},
banner: false
};
function create () {
this.playerSpeed = 0;
this.playerSpeedText = this.add.text(10, 10, '', { color: '#ffffff'}).setOrigin(0);
this.scene.add(this, Scene2, true);
this.scene.get('scene2').events.on('speed-increase', speed => this.playerSpeed = speed);
}
function update(){
this.playerSpeedText.setText(`Player Speed: ${this.playerSpeed}`);
if(this.playerSpeed > 99){
this.playerSpeedText.setColor('#00ff00');
}
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
Update:
If I understand this correct you have:
If this is the case, this makes the things abit more complex, but still possible.
you won't need to import anything else (I think), just add the following code in the specific files.
In the "gameScene", in the create
function (or after the adding of the UpgradeScene), add:
this.scene.get('Upgrade-Scene-Key')
.events.on('upgrade-action', speed => this.playerSpeed = speed);
In the "UpdatedScene" in the create
function (or after the adding the specific Scenes) add:
// this you could do for all upgrade options
this.scene.get('IncreaseSpeed-Scene-key')
.events.on('upgrade-speed', speed => this.events
.emit('upgrade-action', speed));
And in the "IncreaseSpeedScene", just add the emit
function call to the button event callback:
// just be sure that the context of this = the current scene
this.events.emit('upgrade-speed', 100)
With other words, you have now one extra event emitter(in the UpgradeScene), that just passes the Event and the Data to the gameScene.
I hope this clears things up abit.
btw.: the names of the event 'upgrade-action', 'upgrade-speed', ... can be choose more or less freely, they just have to match between emiter (
emit
function) and listener (on
function)
Upvotes: 1