1

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.

winner_joiner
  • 12,173
  • 4
  • 36
  • 61
EmptyStone
  • 235
  • 1
  • 7

2 Answers2

0

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.

winner_joiner
  • 12,173
  • 4
  • 36
  • 61
  • I supposed either way works, but I just tested it, and it turns out the shockTimer1 integer isn't going up. I have an idea for a fix, but your free to share one if you want. – EmptyStone May 21 '23 at 05:09
  • Hey, my quick fix worked. Thanks for the help anyway. Now only one big issue left. – EmptyStone May 21 '23 at 05:12
0

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.

Timothy Bushell
  • 170
  • 1
  • 7