EmptyStone
EmptyStone

Reputation: 315

Phaser Struggling to get temporary text boxes working, any chance there are for loops in phaser?

I'm trying to get some text to breifly appear, and then disappear, but I'm struggling to figure out how.

What I have here is some dialogue that is triggered if a boolean is true. It has 2 timer integers, one for each dialogue. While the first one is going, its related dialogue is displayed, until the timer reaches 100, which then stops, and the second timer gets going, showing its related dialogue and disappearing when that timer reaches 100.

    if (bought == true){
        this.shockTime1 = 0;
        this.shockTime2 = 0;
        if (this.shockTime1 < 100){
            this.bubble.setAlpha(1);
            this.speech.setText('What the heck?! \nYou used company\nmoney to buy some\nrun down mansion?\nWhy?!?');
            this.shockTime1 = this.shockTime1 + 1;
            
        }
        else if (this.shockTime2 == 100 && this.shockTime2 < 100){
            this.bubble.setAlpha(1);
            this.speech.setText('Your not going to\neven live there! This is\nan outrageous waste\nof money! You \nlittle idiot!!!');
            this.thankTime2 = this.thankTime2 + 1;
            
        }
        else {
            this.bubble.setAlpha(0);
            this.speech.setText('');
        }
    }

Or at least that's the idea. When I tested this, I found that the first timer only went up one and then stopped, thus leaving the first dialogue on display indefinitely. I'm not sure about what the solution could be, so I'm asking for help.

If this was in Java in the Eclipse compiler, I would use for loops to solve this issue. I did try to make what I thought would be a phaser version of a for loop, but I just got errors. If there is a way to do this with for loops, can someone give me an example.

If it helps, I'm using Phaser 3 in VSCode.

Upvotes: 1

Views: 167

Answers (2)

Timothy Bushell
Timothy Bushell

Reputation: 190

I suggest you make use of multiple scenes. Have a special scene which is for displaying messages, like this:

class AlertBoxScene extends Scene {
  create() {
    let alertBoxScene = this
    let { height, width } = alertBoxScene.game.config
    // Add a simple centered text box. Use config to format it better.
    alertBoxScene.MESSAGEBOX = alertBoxScene.add.text(
      width/2, height/2, "Incoming message...")
    alertBoxScene.MESSAGEBOX.setOrigin(0.5)
   } 
   // Add a way to change the message of this scene from another scene.
   message(messageText) {
    let alertBoxScene = this
    alertBoxScene.MESSAGEBOX.setText(messageText)
   }
 }

Then you would use this extra scene from your MainScene class like this:

 let alertBoxScene = myMainScene.scene.get("AlertBoxScene")
 alertBoxScene.start()
 alertBoxScene.message("You won dammit! Now I have to give you my coins.")
 myMainScene.time.addEvent({
  delay: 2000,
  callback: () => alertBoxScene.stop(),
})

And to have multiple scenes, config your game like this:

const myGame = new Game(GAMECONFIG)
myGame.scene.add("MyMainScene", MyMainScene, true, SCENECONFIG)
myGame.scene.add("AlertBoxScene", AlertBoxScene, false, SCENECONFIG)

Where true and false determine which scene is the one that myGame automatically loads.

Upvotes: 0

winner_joiner
winner_joiner

Reputation: 14880

Well your code is abit confusing, nevertheless a simplier solution would be to simply use the javascript builtin function setTimout (link to the documentation), or the Phaser function delayedCall (link to the documentation), or the Phaser timeline (link to the documentation)

Here a mini demo, with timeline:
You just have to set the times for when the action should be fired, in the property at, in milliseconds.

document.body.style = 'margin:0;';

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    scene: { create },
    banner: false
}; 

function create () {
    let bubble = this.add.rectangle(10, 10, 250, 50, 0xffffff)
        .setAlpha(0)
        .setOrigin(0);
        
    let label = this.add.text(30, 22, '')
      .setScale(1.5)
      .setColor('#000000')
      .setOrigin(0)
      .setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
    
    //initialize timeline
    const chatTimeline = this.add.timeline([{
            // fires after 500ms
            at: 500,
            run: () => {
                bubble.setAlpha(1);
                label.setText('What the heck?!...');
            }
        },{
            // fires after 1500ms
            at: 1500,
            run: () => {
                bubble.setAlpha(1);
                label.setText('Your not going...');
            }
        },{
            // fires after 2000ms
            at: 2000,
            run: () => {
                bubble.setAlpha(0);
                label.setText('');
            }
        },{
            // fires after 3000ms
            at: 3000,
            run: () => {
                //Just for the demo, so that it loops
                chatTimeline.play();
            }
        },
    ]);
        
    chatTimeline.play();
}

new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

Update:
I you only want to fix your code, I think just fix the typos in this line (you used incorrect property names):

...
else if (this.shockTime2 == 100 && this.shockTime2 < 100){
...

it should be:

...
else if (this.shockTime1 == 100 && this.thankTime2  < 100){
...

if I understud your code.

And you are resetting this.shockTime1 = 0; and this.shockTime2 = 0; on each run, this might also be partly the cause for the integer not going up.

Upvotes: 0

Related Questions