phaserjs / phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
https://phaser.io
MIT License
36.94k stars 7.08k forks source link

onBounce event emitted from a Physics.Arcade.Body #6406

Closed ricardofiorani closed 6 months ago

ricardofiorani commented 1 year ago

Hello there, I tried recently to achieve a way of getting an Arcade Physics Body to emit an event without changing Phaser's source code, however, I found myself unable to do so.

I would kindly drop a pull request adding said functionality, however, I would like to ask here first if is there a way already to do it.

Please let me know if really there is no way to do so at the moment, so I can start and draft a pull request for it.

Thanks in advance.

photonstorm commented 1 year ago

Hi - Thanks for the offer of a PR. First, could you explain why you'd need an onBounce event when you've already got onCollide? (as a bounce cannot happen without a collision)

ricardofiorani commented 1 year ago

Hello @photonstorm , thank you for the quick response.

In my idea, the reason for having a universal event onBounce is that it would work with both World Bounds and other bodies. It would simplify and prevent the need of keeping track of everything that is collidable and not having to add an add.onCollide() to each possible collidable body, plus, listening for the worldbounds event.

In the following example, you can see that the collide event is not emitted when it happens to a world bound:

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    parent: 'phaser-example',
    physics: {
        default: 'arcade',
        arcade: {
            gravity: {
                y: 200
            }
        }
    },
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

function preload ()
{
    this.load.image('bg', 'assets/skies/space2.png');
    this.load.spritesheet('ball', 'assets/sprites/balls.png', { frameWidth: 17, frameHeight: 17 });
}

function create ()
{
    this.add.image(400, 300, 'bg');

    var group = this.physics.add.group({
        key: 'ball',
        frameQuantity: 2,
        bounceX: 1,
        scale: 9,
        bounceY: 1,
        collideWorldBounds: true,
        velocityX: 180,
        velocityY: 120,
    });

    Phaser.Actions.RandomRectangle(group.getChildren(), this.cameras.main);

    Phaser.Actions.Call(group.getChildren(), function (ball) {
        ball.body.onWorldBounds = true;
        ball.body.onCollide = true;
    });

    this.physics.world.on('worldbounds', () => console.log('worldbounds event'));
    this.physics.world.on('collide', () => console.log('collide event'));
}

EDIT:

PS: Also it would only be emitted by bodies that have a bounce value > 0.

EDIT2:

I tested it here -> https://labs.phaser.io/edit.html?src=src/physics/arcade/world%20bounds%20event.js&v=3.55.2