1

I have started learning Phaser 3.60 and unfortunately I am stuck. I can't find a way to set up the hitbox. Exactly what I would like is to have the raindrop falling from the top down and have an umbrella that when the raindrop falls on it, it cancels the raindrop and generates a new one. The mechanics are written but I can't rewrite the hitbox. I would like your help with this. I will send you a few lines of my code.

Umbrella:

export class Umbrella extends Phaser.Physics.Arcade.Sprite {
    private raindrops: Phaser.Physics.Arcade.Group;
    private debugGraphic: Phaser.GameObjects.Graphics; // debugGraphic tulajdonság hozzáadása

    constructor(
        scene: Phaser.Scene,
        x: number,
        y: number,
        raindrops: Phaser.Physics.Arcade.Group
    ) {
        super(scene, x, y, "umbrella");

        scene.add.existing(this);
        this.scene.physics.world.enable(this); // Engedélyezzük a fizikai testet az esernyő Sprite-hoz

        // Inicializáljuk a debugGraphic-t
        this.debugGraphic = scene.add.graphics();

        (this.body as Phaser.Physics.Arcade.Body).allowGravity = false; // Kikapcsoljuk a gravitációt

        const hitboxWidth = 100; // A hitbox szélessége
        const hitboxHeight = 100; // A hitbox magassága

        const topHeight = hitboxHeight * 0.25; // A felső téglalap magassága (25%)
        const bottomHeight = hitboxHeight - topHeight; // Az alsó téglalap magassága

        this.raindrops = raindrops;
    }

    public mouseMove(input: Phaser.Input.InputPlugin): void {
        // Itt mozgatjuk az egérrel az esernyőt ha kattintunk
        var pointer = input.activePointer;
        if (pointer.isDown) {
            this.x = pointer.x;
            this.y = pointer.y;
        }

        // Itt mozgatjuk az egérrel az esernyőt ha simán mozgatjuk.
        input.on("pointermove", (pointer) => {
            this.x = pointer.x;
            this.y = pointer.y;

            this.drawHitbox(this.x, this.y);
        });
    }

    private drawHitbox(x: number, y: number): void {
        const hitbox = this.body as Phaser.Physics.Arcade.Body;
        // Rajzolás a debugGraphic segítségével
        this.debugGraphic.clear();
        this.debugGraphic.lineStyle(2, 0xff0000); // Vonalstílus beállítása (2 pixel vastag, piros szín)
        this.debugGraphic.strokeRect(
            x - hitbox.width / 2,
            y - hitbox.height / 2,
            hitbox.width,
            hitbox.height
        );
    }
}

MainGame Scene:

collision event:

//Az esőcsepp és az esernyő detektálása.
    this.physics.add.overlap(
        this.umbrella,
        this.raindrops,
        this.collectDrop,
        null,
        this
    );
}

Collision detection:

private collectDrop(
    umbrella: Phaser.Physics.Arcade.Sprite,
    drop: Phaser.Physics.Arcade.Sprite
): void {

    // // Eltávolítjuk a cseppet a csoportból
    this.raindrops.remove(drop, true, true);

    // Generálunk egy új esőcseppet
    const newDrop = new Raindrop(
        this,
        Math.floor(Math.random() * Number(this.game.config.width)),
        -100
    );
    this.raindrops.add(newDrop);
}
winner_joiner
  • 12,173
  • 4
  • 36
  • 61
Drelaky
  • 23
  • 3

1 Answers1

0

As @zenly mentioned thin-bar is enough. To create this you can use the functions setSize and setOffset of the physics body, shown in the following demo (link to the documentation).

btw.: you don't really need, to create a debug graphics object, since phaser offers it out-of-the-box, with the config property debug, just set it to true.

Here a short demo:

document.body.style = 'margin:0;';
class Umbrella extends Phaser.Physics.Arcade.Sprite {
    constructor( scene, x, y, raindrops ) {
        super(scene, x, y, "umbrella");

        scene.add.existing(this);
        this.scene.physics.world.enable(this); 

        this.body.allowGravity = false;

        // size of hitbox
        this.setSize(80, 5);
        // offset of hitbox
        this.setOffset(-25, -20);

        const hitboxWidth = 100;
        const hitboxHeight = 100;

        const topHeight = hitboxHeight * 0.25;
        const bottomHeight = hitboxHeight - topHeight;

        this.raindrops = raindrops;
    }
    
    //...
}

var config = {
    type: Phaser.AUTO,
    width: 536,
    height: 183,
    physics: {
        default: 'arcade',
        arcade: {
            // shows debug hitbox
            debug: true
        }
    },
    scene: { create }
}; 

function create () {    
     let i = new Umbrella(this, 100, 100, []);
}

new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>

If you want the create a T-shaped hitbox. I could create a custom Phaser Container and add two physics objects/bodies, and position the with the above mentioned functions.

winner_joiner
  • 12,173
  • 4
  • 36
  • 61
  • I see. However, what you said is half right, that is, in debug it really measures everything, but in the umbrella class I can't use this.body.setSize or this.body.setOffset because it says so: umbrella.ts:12 Uncaught TypeError: Cannot read properties of null (reading 'setSize') at new t (umbrella.ts:12:14) at u.create (MainGame.ts:82:19) In mainGame.ts I call it like this: this.umbrella = new Umbrella(this, this.sys.canvas.width / 2, this.sys.canvas.height - 100); Or it deletes things in the same way as before. If I set it to this.umbrella – Drelaky May 24 '23 at 14:33
  • Sorry, it was a mistake, I think it should be` this.setOffset` and `this.setSize`. javascript is more forgiving than typescript. I hope this works now. – winner_joiner May 24 '23 at 14:39
  • I would like to do this spriteot pixel accurate detection. Unfortunately I don't understand how to do it yet. – Drelaky May 24 '23 at 14:39
  • Sry my mistake because i used later this.scene.physics.world.enable(this); – Drelaky May 24 '23 at 14:43
  • pixel accurate detection is not so easy. you could use the `processCallback` parameter from the `overlap` function [link to the documentation](https://newdocs.phaser.io/docs/3.55.2/focus/Phaser.Physics.Arcade.ArcadePhysics-overlap), in this function you would have to detect the collision yourself. Or you could use the _matter_ engine, but that is much more complicated – winner_joiner May 24 '23 at 15:07