How do you count the times a state is activated?

Hi there! I’m working on playable combat with an npc in Phaser 3. I have state machines, each for the player and an npc.

I want to be able to count the amount of times a state is activated. I created a variable in my entity class, and then called the variable from a state (in this case, called a NPCWeakAttackState)

export class NPCWeakAttackState extends State {
    enter(scene, npc) {
        npc.weakAttackAmount = npc.weakAttackAmount + 1
        if (npc.flipX == false) {
            npc.play("minotaur-weakattack", true)
        }
        if (npc.flipX == true) {
            npc.play("minotaur-weakattack", true)
        }
    }

    execute(scene, npc) {
        if (npc.flipX == false) {
            npc.on("animationupdate", (anim, frame) => {
                if (frame.textureFrame == 41 ) {
                    npc.attackZone.x = npc.x + 38
                    npc.attackZone.y = npc.y 
                    npc.attackZone.setSize(10, 10)
                    scene.physics.world.enable(npc.attackZone)
                }
                if (frame.textureFrame == 42) {
                    scene.physics.world.disable(npc.attackZone)
                }
                if (frame.textureFrame == 43) {
                    npc.weakAttackAmount = npc.weakAttackAmount + 1
                    this.stateMachine.transition("wait")
                }  
            })
        }

        if (npc.flipX == true) {
            npc.on("animationupdate", (anim, frame) => {
                if (frame.textureFrame == 41 ) {
                    npc.attackZone.x = npc.x - 38
                    npc.attackZone.y = npc.y 
                    npc.attackZone.setSize(10, 10)
                    scene.physics.world.enable(npc.attackZone)
                }
                if (frame.textureFrame == 42) {
                    scene.physics.world.disable(npc.attackZone)
                }
                if (frame.textureFrame == 43) {
                    this.stateMachine.transition("wait")
                }  
            })
        }
    }
}

The weakAttackAmount code is written in my Player class which looks like this:

this.weakAttackAmount = 0

I’ve had relative success in getting things to work, moving from state to state. I figured I could try setting up a variable inside my entity class, called weakAttackAmount, that will be called into my states and incremented +1 each time the attack state is activated. I could then use a conditional statement, if weakAttackAmount < 3 = then switch to the strong attack.

Problem is that, in my state code, it increments far more than I want it to. I only want it to increment 1 once each time, whereas it instead increments multiple times.

The states work fine, but I can’t increment a variable by one.

I’m having some difficulty solving this problem. If anyone has any advice on state management, I’d really appreciate it. Any suggestions or help would be much appreciated. I will be updating this post as much as I can. Thanks

Add logging to see where it gets updated.
I guess 'enter()' is only called once, so it’s probably ‘if (frame.textureFrame == 43)’ in the animationupdate. That one keeps getting called as long as there is an event, independent of state.

Yeah I managed to get help on stackoverflow, I believe it wasnt working because I was calling a state transition from the execute function, and it was executing that state more times than I wanted it to.

export class NPCPrepareAttackState extends State {
    enter(scene, npc, lastPos) {
        this.scene = scene
        this.npc = npc
        this.lastPos = lastPos
        this.amount = 0
    }
    execute(scene, npc) {
            scene.physics.moveTo(npc, this.lastPos.x, this.lastPos.y, 50)
            npc.play("minotaur-run", true)
            this.dist = Phaser.Math.Distance.Between(this.lastPos.x, this.lastPos.y, npc.x, npc.y);
            if (this.dist < 40) {
                this.amount = this.amount + 1
                if (this.amount == 1) {
                    this.stateMachine.transition("weakattack")
                }
            }
    }
}

export class NPCWeakAttackState extends State {
    enter(scene, npc) {
        npc.weakAttackAmount = npc.weakAttackAmount + 1
        npc.on("animationupdate", (anim, frame) => {
            if (frame.textureFrame == 41) {
                npc.attackZone.x = npc.x + (npc.flipX ? -38 : 38);
                npc.attackZone.y = npc.y
                npc.attackZone.setSize(10, 10)
                scene.physics.world.enable(npc.attackZone)
            }
            if (frame.textureFrame == 42) {
                scene.physics.world.disable(npc.attackZone)
            }
            if (frame.textureFrame == 43) {
                this.stateMachine.transition("wait")
            }
        })
    }
    execute(scene, npc) {
        npc.play("minotaur-weakattack", true)
    }
}

I’m unsure if this is a stable way to use states, but it seems to be working.