phaser icon indicating copy to clipboard operation
phaser copied to clipboard

Phaser.Types.Physics.Arcade.GameObjectWIthBody should accept generic types

Open johanvergeer opened this issue 3 years ago • 2 comments

Version

  • Phaser Version: 3.55.2
  • Operating system: MacOS
  • Browser:

Description

I was working on converting the files that I created while doing the tutorial created by Luis Zuno to TypeScript, and I run into a similar issue as @DeweyHur in #5759.

In my case I'm using a SpriteWithDynamicBody, but all I need in the callback function is Phaser.Physics.Arcade.Components.Enable.

Would it be an idea to make when the parameters of Phaser.Types.Physics.Arcade.GameObjectWIthBody generic so developers can pass in just about anything, and still have decent type hinting?

The issue occurs right here:

image
TS2345: Argument of type '(player: any, powerUp: Enable) => void' is not assignable to parameter of type 'ArcadePhysicsCallback'.   
  Types of parameters 'powerUp' and 'object2' are incompatible.    
    Type 'GameObject & { body: Body | StaticBody; }' is missing the following properties from type 'Enable': enableBody, disableBody, refreshBody

Example Test Code

import Phaser from "phaser";
import playerSprite from "./assets/spritesheets/player.png";
import powerUpSprite from "./assets/spritesheets/power-up.png";

export default class SimpleScene extends Phaser.Scene {
    private powerUps!: Phaser.Physics.Arcade.Group;
    private player!: Phaser.Types.Physics.Arcade.SpriteWithDynamicBody;

    constructor() {
        super("bootGame");
    }

    preload() {
        this.load.spritesheet("power-up", powerUpSprite, {
            frameWidth: 16,
            frameHeight: 16,
        });
        this.load.spritesheet("player", playerSprite, {
            frameWidth: 16,
            frameHeight: 24,
        });
    }

    create() {
        this.createPowerUps();
        this.createPlayer();

        this.physics.add.overlap(
            this.player,
            this.powerUps,
            this.pickPowerUp,
            undefined,
            this
        );
    }

    pickPowerUp(
        player: any,
        powerUp: Phaser.Physics.Arcade.Components.Enable,
    ) {
        powerUp.disableBody(true, true);
    }

    private createPlayer() {
        this.player = this.physics.add.sprite(100, 100, "player");
    }

    private createPowerUps() {
        this.powerUps = this.physics.add.group()
        
        for (let i = 0; i <= 4; i += 1) {
            const powerUp = this.physics.add.sprite(16, 16, "power-up");
            this.powerUps.add(powerUp);
            powerUp.setRandomPosition(0, 0, 256, 272);
        }
    }
}

Additional Information

johanvergeer avatar Oct 24 '21 19:10 johanvergeer

I don't know if there's any way Phaser could solve this though.

samme avatar Oct 25 '21 17:10 samme

This could solve it:

pickPowerUp(
        player: any,
        powerUp: Phaser.Types.Physics.Arcade.GameObjectWithBody
    ) {
        (powerUp as Phaser.Physics.Arcade.Components.Enable).disableBody(true, true);
    }

TomCool-TomTom avatar Aug 19 '22 17:08 TomCool-TomTom

There's no way to do this with the current TS Generator we use, and I'm afraid there are no plans to add this feature. Roll-on Phaser 4, TS from the start.

photonstorm avatar Nov 18 '22 21:11 photonstorm

this does the trick

pickPowerUp: ArcadePhysicsCallback = (_player, powerUp): void => {
    (powerUp as Phaser.Types.Physics.Arcade.SpriteWithDynamicBody).disableBody(
      true,
      true
);

also you can call it without passing context:

this.physics.add.overlap(this.player, this.powerUps, this.pickPowerUp);

ViieeS avatar Jan 22 '23 04:01 ViieeS