Jump to content

Fire platform collider callback once only


Goshawk
 Share

Recommended Posts

I have a player character and a platform. When the player collides with platform I would like to perform some things once only.

Currently I have:

create(){
  // add hero
  this.hero = this.physics.add.sprite(gameOptions.spriteSize/2, gameOptions.spriteSize/2, 'hero', 0);

  // add platform
  this.platforms = this.physics.add.staticGroup();
  for ( var xPos = gameOptions.spriteSize/2; xPos < gameOptions.width; xPos+=gameOptions.spriteSize ) {
      this.platforms.create(xPos, gameOptions.height - gameOptions.spriteSize*1.5, 'tiles', 8);
  }

  // handle collisions
  this.physics.add.collider(this.hero, this.platforms, this.collidesWithPlatform, false, this);
}

collidesWithPlatform(){
  console.log('Collided!');
  // Do some things once
}

However, `collidesWithPlatform()` fires continuously whilst the player is stood on the platform.

I can make use of a flag:

collidesWithPlatform(){
  if (!this.onGround) {
    console.log('Collided!');
    // Do some things once
  }
  this.onGround = true;
}

...but it strikes me that this isn't possibly the best idea as I would likely end up having to handle the flag in multiple places. For the sake of avoiding fragile code, is there another way to ensure `collidesWithPlatform` fires once only?

Link to comment
Share on other sites

  • 2 months later...
  • 7 months later...

 

/**
 * Any passed callback will be called once
 * @param callback  - Your method
 * @param context   - Context of the method - by default it uses the current class 'this'
 */

private callOnce(callback?: Function, context = this) {

        if (typeof callback !== 'function') {
            callback = () => {
            };
        }

        let once = false;

        return (...args: any[]) => {
            if (!once) {
                once = true;
                callback.apply(context, args);
            }
        }

    }


create(){

 ...

 this.physics.add.collider(bullet, this.platform, this.callOnce(this.destroyAmmo), null, this);

 ...

}

private destroyAmmo(ammo: Phaser.Physics.Arcade.Image, platform: Phaser.Physics.Arcade.Image) {

        console.log('once !', ammo.x, ammo.y);

}

 

In case someone ends up here, i just encountered this and solved it by creating a helper method.

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...