setVelocity(vx, vy) not working as excepted

when I call this.setVelocity(x, y) from inside the constructor of my custom gameObject Class it doesn’t work but it works when I write this.setVelocity(x, y) inside the update(time, delta) method.
I also replicated the issue in this phaser 3 sandbox

if I add the line this.setVelocity(10, 0); after line:9 in the above link then the game won’t run.
I also tried adding
scene.add.existing(this);
scene.physics.add.existing(this);
in the constructor if it’s needed.

Assuming you want to use Arcade Physics: this.setVelocity only exists on an Arcade Image or an Arcade Sprite. For any other Game Object, you have to use this.body.setVelocity after adding it to the physics world with scene.physics.add. You also need to enable Arcade Physics.

My class extends Phaser.Physics.Arcade.Sprite

export default abstract class Bullet extends Phaser.Physics.Arcade.Sprite {
    
    private damage:integer
    private v
    public team:number

    constructor(scene: Phaser.Scene, x:number, y:number, damage:number, team:number, image:string, angle:number, velocity:number) {
        super(scene, x, y, image)
        scene.add.existing(this);
        scene.physics.add.existing(this);

        this.damage = damage
        this.team = team
        this.setAngle(angle)
        let v =  new Phaser.Math.Vector2(1, 1);
        v.setAngle(this.rotation)
        v.setLength(velocity)
        this.setVelocity(this.v.x, this.v.y)
    }

    update(t:number, dt:number) {
        super.update(t, dt)
        //  this.setVelocity(this.v.x, this.v.y)
    }
}

If I comment this.setVelocity(this.v.x, this.v.y) in the constructor and add it in the update() then the sprite moves as excepted. But why do I need to setVelocity on every update?

Are you using a group?

Yes I am testing collision between 2 groups

this.physics.add.overlap(this.ships, this.bullets,
      (ship, bullet) => this.handleBulletCollision(ship as Ship, bullet as Bullet), undefined, this)

The physics body is configured from the physics group defaults when it’s added to the group.

From my scene class, I am creating and adding objects to the group like this

this.ships.add(new MotherShip(this, 600, 400, 0));// MotherShip extends Ship

this.bullets.add(new PulseLaser(this.scene, this.x, this.y, this.team, this.angle)); //PulseLaser extends Bullet

@samme Do you mean the constructor is never called for the bullet object?

If this.bullets is a physics group then it’s going to overwrite any physics body values you set in the bullet constructor.

You can do

 this.bullets.defaults = {};

to avoid that.

2 Likes

@samme thanks for clarifying :smiley:
I am using ts so this.bullets.defaults = {};is showing me error.
So I created a callback when defining the groups like this

this.Bullets = this.physics.add.group({
        classType: Bullet,
        createCallback: (obj) => {
            (obj as Bullet).create()
        }
    });

Then I set the velocity and other physics properties in the create() to get around this.

Anyways, how does overwriting the values set by contructor with default values make sense?
This will be so non-trivial to figure out if you don’t know all ins and outs of phaser :thinking:

I guess all the properties are marked required. But really they’re not.

It is a little weird.

If the error you get comes from TypeScript, you could deal with it with something like this (I did so):

(asteroidGroup.defaults as {}) = {};

That way you can convince your code processor not to complain.

And to explain why I’m here - I faced the same problem and this thread solved the issue I was struggling with for a long time. Thanks a lot guys.