Issue with update() function

Hi everyone, I’m having an issue with my interaction system in my tutorial level. The issue is that I have a dialogue box with dialogue text that keeps on stacking on continuously once I change the value of my three variables this.checkA = false, this.checkD = false, and this.checkSPACE = false

When my level loads, I display a dialogue box to the player from one of the NPCs. This one only shows up when the above variables have a boolean of false

The only way I know to check for keypresses is within the update function, and keypresses are what I’m using to trigger my variables above to change from false to true

When they are true I change the text in my dialogue and destroy the previous text. But I can’t figure out how to stop the update() function from basically breaking everything. I know update() runs continuously so basically I need a way to break out of a portion of the loop.

create() {
this.checkA = false;
        this.checkD = false;
        this.checkSPACE = false;

        if (this.checkA === false && this.checkD === false) {
            this.dialWindow = this.dialogue.create(960, 500, "dialInstructor").setScale(1.25); // create the dialogue box
            this.dialogueText1 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, this.interact.dialObj.dialInstructor.dialIntro1, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
        }
}

update() {

if (this.checkA === true && this.checkD === true) {
    this.dialogueText1.destroy();
    this.dialogueText2 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, this.interact.dialObj.dialInstructor.dialIntro2, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
}

if (this.checkSPACE === true) {
    this.dialogueText2.destroy();
    this.dialogueText3 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, this.interact.dialObj.dialInstructor.dialIntro3, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
}

if (this.cursors.left.isDown && this.checkA < 2) {
    this.checkA = true;
    console.log("A checked");
} else if (this.cursors.right.isDown && this.checkD < 2) {
    this.checkD = true;
    console.log("D checked");
} else if (this.cursors.jump.isDown && this.checkSPACE < 2) {
    this.checkSPACE = true;
}
}

In the following code:

function create ()
{
    this.checkA = false;
    this.checkD = false;
    this.checkSPACE = false;

    if (this.checkA === false && this.checkD === false) 
    {
        this.dialWindow = this.dialogue.create(960, 500, "dialInstructor").setScale(1.25); // create the dialogue box
        this.dialogueText1 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, this.interact.dialObj.dialInstructor.dialIntro1, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
    }
}

You don’t need the if conditional because you set this.checkA and this.checkB to false just prior.

In your update method, you can combine the following conditionals since they do the same thing. So

if (this.checkA === true && this.checkD === true) {
    this.dialogueText1.destroy();
    this.dialogueText2 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, this.interact.dialObj.dialInstructor.dialIntro2, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
}

if (this.checkSPACE === true) {
    this.dialogueText2.destroy();
    this.dialogueText3 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, this.interact.dialObj.dialInstructor.dialIntro3, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
}

turns into

if((this.checkA === true && this.checkD === true) || (this.checkSPACE === true))
{
    this.dialogueText2.destroy();
    this.dialogueText3 = this.add.text(this.dialWindow.x - 260, this.dialWindow.y - 280, 
    this.interact.dialObj.dialInstructor.dialIntro3, {fontFamily: "sans-serif", fontSize: 30, lineSpacing: 2, fontColor: 0xffffff});
}

Also, in the following code, you’re checking your boolean variables (0 & 1) to see if they are less than two, which will always evaluate to true. I think you’re going to want to change those to !this.checkA

if (this.cursors.left.isDown && this.checkA < 2) {
    this.checkA = true;
    console.log("A checked");
} else if (this.cursors.right.isDown && this.checkD < 2) {
    this.checkD = true;
    console.log("D checked");
} else if (this.cursors.jump.isDown && this.checkSPACE < 2) {
    this.checkSPACE = true;
}

Hope this leads you in the right direction.

Hey Jake! This was helpful in doing some refactoring, so thank you very much for that. Let me explain what I am trying to achieve. The solution to add in my checkSPACE variable into a single if statement with checkA and checkD won’t work.

  1. A user starts the game
  2. They are immediately welcomed with the dialogue that is in the create() method
  1. They press W/D to test movement
  2. The dialogue changes and now they are prompted to test jump (SPACE)
  3. They press SPACE and the previous dialogue should be destroyed.

What is happening now is my dialogues are changing, right? no problem there. At the end I can close out, no problem there. The problem is that EVERY time I press W/A or SPACE, a new dialogue text pops up because once those variables are true, they are always true. I need a way to say "hey, after this.checkA and this.checkB and this.checkSPACE have been set to true, let’s move them back to false forever.

Hi,

Could you add another check to see if they are all true and then set them to false for example.

if(this.checkA && this.checkB && this.checkSPACE) {
    this.checkA = false;
    this.checkB = false;
    this.checkSPACE = false;
}

Hope this helps :slight_smile:

Ah, that makes sense. If I were to approach this, I would do the following:

create()
{
    this.states = { testMovement: 0, testJump: 1, tutorialComplete: 2 };
    this.setState(this.states.testMovement);
    this.input.keyboard.on('keydown', (event) => {
        if (this.state == this.states.testMovement) {
            if (event.keyCode === Phaser.Input.Keyboard.KeyCodes.D) this.pressedD = true;
            else if (event.keyCode === Phaser.Input.Keyboard.KeyCodes.A) this.pressedA = true;
            if (this.pressedD && this.pressedA) this.setState(this.states.testJump);
        }
        else if (this.state == this.states.testJump) {
            if (event.keyCode === Phaser.Input.Keyboard.KeyCodes.SPACE) this.setState(this.states.tutorialComplete);
        }
    });
}
setState(state) 
{
    this.state = state;
    if (this.state === this.states.testMovement) {
        //CREATE DIALOG
        console.log("Creating dialog");
    }
    else if (this.state === this.states.testJump) {
        //CHANGE DIALONG
        console.log("Changing dialog");
    }
    else if (this.state === this.states.tutorialComplete) {
        //DESTROY DIALOG
        console.log("Destroying dialog");
    }
}
1 Like

Hi Retro,

So this sort of worked, but by doing this in my update() method I think there were just so many other problems. Thanks for the help though.

This worked perfectly, I haven’t ever messed with state in Phaser, so I wasn’t even thinking about this. Thanks man!

No problem and glad to hear it worked! :smile:

1 Like