How to build a jump in a beat-based gravity? (Arcade Physics)

Hi there!

I want to build a beat-based Jump’n’Run and have some problems with the jump. I use arcade physics with a gravity of “y: 0”, my player sprite is created with

this.sprite.body.setGravityY(1);

In my create()-function is a looped event like this:

create() {
    this.bps = 600;
    this.beat = this.time.addEvent({ delay: this.bps, callback: this.onEvent, 
    callbackScope: this, loop: true});
}

And an onEvent()-function like this:

onEvent () {
    this.sound.play('beat');
    console.log("Beat!");

    // gravity
    console.log(this.player.getJumping());
    if(this.player.getJumping() == false) { 
        this.player.moveDirection("down"); 
    }
}

So what I want to achieve is that every beat where the player isn’t jumping he should fall down. But when the player jumps, he should go up, stay there a bit and then go up even further (so the player can steer the jump left or right).
In my Player.js I have 3 functions which are relevant for the question (If you need more I’ll gladly provide):

jump() {
    this.jumping = true;
    this.sprite.body.setGravityY(0);
    this.moveDirection("up");
    setTimeout(() => {
      this.moveDirection("up");
    }, 600);
    setTimeout(() => {
      this.moveDirection("up");
    }, 600);
    setTimeout(() => {
      this.jumping = false;
      this.sprite.body.setGravityY(1);
    }, 600);

  }

getJumping() {
    return this.jumping;
}

moveDirection(direction) {
   // other directions [..]
  } else if(direction == "down") {
    this.sprite.body.setVelocityY(160)
    setTimeout(() => {
      this.sprite.body.setVelocityY(0);
    }, 200);
  }
}

Sometimes the jump behaves as wanted but most of the times the first or second part of the movement of the jump is short or cancelled. I think it’s because of the gravity setting in too soon, but I can’t figure out the right way to make it work like I want.

Thanks in advance to everyone who looks into the topic.

I think I get what you are wanting to do here. I’m not sure if this is the problem, but what I am thinking looking at this is that you are polling for the movement inside the onEvent method “out of update sync”. I wonder if it may simplify your code and prevent the update cycle from working against you by having a flag that determines if the player can jump (or whatever the specific effect of jumping on beat is). When your beat event fires, just set that flag to create a period where the player can jump. You may then need to set another timer inside the onEvent to switch the flag back off when the opportunity is over, maybe for as long as the beat sound is.

Then for the most part you make a normal platformer-ish update function where you handle the controls. However, you check that flag to see if the player is jumping during their opportunity to jump. Just wrap the jumping logic or whatever logic you want inside of an if-statement that checks if the flag is on and skip it if it is not.

I am thinking setting it up this way may make your logic and its interactions with other player controls in the update method easier to understand and follow. I have a suspicion that your logic in onEvent could be wrestling with the rapidly-called movement logic elsewhere in your code.

I already had my player.jumping flag, I solved the problem by extending the duration the flag was active.