Collisions between two groups

Hello all,
I am struggling a little bit with collisions between two group members and I think I need some advice or help.
I am writing a game in which an alien ship fires bullets and the player ship fires lasers.
To achieve that, I have created two classes that extend the Group class like that:

class BulletsGroup extends Phaser.Physics.Arcade.Group {
…
}

and

class LasersGroup extends Phaser.Physics.Arcade.Group {
…
}

In the constructor of each class (BulletsGroup and LasersGroup classes), I create multiple instances of Bullet and Laser classes which are sprites extending the Phaser.Physics.Arcade.Sprite class.

class Bullet extends Phaser.Physics.Arcade.Sprite {
…
}

and

class Laser extends Phaser.Physics.Arcade.Sprite {
…
}

In my create() function, I then create instance of each of above Group classes:

bullets = new BulletsGroup(this, 2);

and

lasers = new LasersGroup(this, 2);`

Everything works fine until that point.

Then, I want to detect collisions between a laser (a sprite within the Lasers group) and a bullet (a sprite within the Bullets group, that is, the player can stop a bullet by firing a laser beam). So I add an overlap callback function like this, still in my create() function:

this.physics.add.overlap(lasers, bullets, laserBulletCollide, null, this);

The first two parameters are the instances to the groups I have created earlier, and the laserBulletCollide() is the callback function in which I simply display a message on the console.

When I run the game, several collisions are immediatly detected when the collider is setup while no bullet and no laser has been fired. I see the log console counter dramatically increasing.

My assumption is that all objects (laser and bullet) within their respective groups are created at the same position on the screen (while neither active nor visible) and for the physics engine, they are overlapping, so collisions are detected.

I tried to create the sprites at different position by adding x and y properties like that:

class BulletsGroup extends Phaser.Physics.Arcade.Group {
	constructor(scene, size) {
		super(scene.physics.world, scene);		
    		this.createMultiple({
    			key: 'red_bullet',
    			quantity: size,
    			active: false,
    			visible: true,
    			classType: Bullet,
    			repeat: 0,
    			setXY: {
    				x: 100,
    				y: 100,
    				stepX: 30
    			}
    		});
    	}

and the Bullet class is given below:

class Bullet extends Phaser.Physics.Arcade.Sprite {
	constructor (scene, x, y) {
		super(scene, x, y, 'red_bullet');
		this.screenBoundaries = { 
			xmax: scene.game.config.width,
			ymax: scene.game.config.height
		}
		console.log("Bullet: (" + x + " ; " + y + ")");
	}
	
	fire(x, y) {
		this.body.reset(x, y);
		this.setActive(true);
		this.setVisible(true);
		this.setVelocityY(450);
	}
	
	preUpdate(time, delta) {
		super.preUpdate(time, delta);
		
		if(this.y >= this.screenBoundaries.ymax) {
			this.setActive(false);
			this.setVisible(false);
		}
	}
	
	disable() {
		this.setActive(false);
		this.setVisible(false);
	}
}

You can see that in the constructor, I display the sprite position on the console (for debugging purpose).

I did the same for the Lasers group at a different position to avoid any overlapping with the bullet sprites.

But this does not change anything. Collisions are still detected.

In the console, I display the position of each created sprite (laser and bullet as well) and they are still all at position (0 ; 0).

For the moment, I think my assumption is good but I cannot figure out how to set different positions for the sprites. Maybe, it should be simpler to disable collision detection until a bullet (or a laser or both) is fired ? But I do not know exactly how to do that.

If you have some tips or any idea, this would really be appreciated. In the mean time, I keep investigating…

Thanks in advance for your answers!

Kind regards.

1 Like

Hi zedraken,

my answer is late and you have probably solved the problem, but I share my solution anyway for future readers.

I stumbled upon the same problem, in my case with laser beams and viruses… :o)

When I read that they are all created at position x: 0 and y: 0, the solution was simple.

The solution was not to use the supplied method createMultiple, but to create the child objects (laser beams and viruses) myself at a defined position (e.g. x: 100 and y: -500):

export default class VirusSwarm extends Phaser.Physics.Arcade.Group
{
    constructor(scene: Phaser.Scene) 
    {
		super(scene.physics.world, scene);

		// creates all objects at x:0 and y:0
		// this.createMultiple({
		// 	classType: Virus, 
		// 	frameQuantity: 65,
		// 	active: false,
		// 	visible: false,
		// 	key: TextureKeys.Virus			
		// })

		for (let index = 0; index < 65; index++) 
		{
			const virus = new Virus(scene, 100, -500, TextureKeys.Virus)
			virus.active = false
			virus.visible = false
			this.add(virus, true)	
		}
    }
	
    spawnVirus(x: number, y:number) 
    {
		const virus = this.getFirstDead(false) as Virus
		if (virus) 
		{
			virus.fire(x, y);
		}
	}
 
}