Hi!
I am trying to identify where a tremendous performance slowdown is in my little game.
I have a global array called bullets
, to which I add bullets using this function when a cannon is fired.
function shootBullet(physics, tower, tilesGroup, towers, color) {
// console.log("shooting bullet for rotation for " + tower.cannon.id);
sound.play('sfx', markers[4]);
var bullet = physics.add.sprite(tower.x, tower.y - 50, 'bullet');
bullet.bounces = 5;
bullet.onCollide = true;
var angle = tower.cannon.rotation;
var speed = 400;
bullet.targetColor = tower.cannon.targetColor;
bullet
// .setVelocity(300, 200)
.setBounce(1)
.setScale(0.03)
.setTint(bullet.targetColor)
.setCollideWorldBounds(true);
bullet.anims.create(explosionAnim);
bullet.body.angularVelocity = angle * 10;
bullet.body.velocity = physics.velocityFromRotation(angle, 400, bullet.body.velocity);
bullet.onCollide = true;
bullet.body.onWorldBounds = true;
bullet.firingCompleted = false;
bullet.UUID = globalBulletCounter;
bullets.push(bullet);
globalBulletCounter++;
bullet.body.world.on('worldbounds', handleBulletBounce, bullet);
// // physics.add.overlap(bullet, tilesGroup, changeTileColor);
// physics.add.overlap(bullet, towers, handleTowerHit);
}
This works like a champ, then later in create()
I assign collison handling like this (using overlap instead of collide since I want control over the action of the balls)
this.physics.add.overlap(bullets, tilesGroup, changeTileColor); //works great!
this.physics.add.overlap(bullets, towers, handleTowerHit); //also works
console.log("create completed");
Both callbacks of changeTileColor
and handleTowerHit
call another method handleBulletBounce
, which keeps track of how many bounces a bullet has had. Once they have bouinced 3 times, we play an animation then call destroy()
on the bullet.
The Problem
You would think this would work like a champ, but after a few minutes of playing, I can observe that the count of objects in bullets
has gone into the hundreds and hundreds. Calling destroy()
doesn’t seem to actually delete the objects! I can observe in a perf trace that my JS memory is shooting up to more than a GB for a simple game.
How to prune unused objects without breaking collision?
I tried to add this to update()
, filtering out bullets which have active === false
, but doing this completely breaks the collision tracking for any objects still on the screen.
//tried this but it breaks collision / overlap, i.e. any remaining objects alive on screen then no longer have tracking
bullets = bullets.filter(obj => {
return obj.active === true
});