Jump to content

problem with destroy()


naril
 Share

Recommended Posts

Hello, 

 

i started using phaser yesterday and i like it. I'm trying to rewrite my old game which was written in pure javascript with phaser.

 

I need to destroy sprite in group when it get hit by another sprite or get out bounds.  My code is 

function fire() {
    if(game.time.now > bulletTime) {
            bullet = bullets.create(player.x, player.y, 'bullet');
            bullet.anchor.setTo(0.5,0.5);
            bullet.body.velocity.y = -400;
            bullet.checkWorldBounds = true;
            bullet.events.onOutOfBounds.add(function (bullet) {bullet.kill(); bullet.destroy(true);}, this);
            bulletTime = game.time.now + 200;
    }
}
 
function addEnemy () {
    if(game.time.now > enemyAddTimer) {
        var enemy = enemys.create(game.rnd.integerInRange(0,game.world.width - 63),0, 'enemy');
        enemy.anchor.setTo(0.5,0.5);
        enemy.body.velocity.y = 400;
        enemy.checkWorldBounds =true;
        enemy.events.onOutOfBounds.add(function (enemy) {enemy.kill();enemy.destroy(true);}, this);
        enemyAddTimer = game.time.now + 800;
    }
}
 
function enemyShoot() {
    var enemy;
    if(game.time.now > enemyShootTimer) {
        if(enemy = enemys.getRandom()) { 
            var enemyBullet = enemyBullets.create(enemy.x, enemy.y+10, 'enemyBullet');
            enemyBullet.anchor.setTo(0.5,0.5);
            enemyBullet.body.velocity.y = 600;
            enemyBullet.checkWorldBounds = true;
            enemyBullet.events.onOutOfBounds.add(function (bullet) {bullet.kill(); bullet.destroy(true);}, this);
            enemyShootTimer = game.time.now + 400;
        }
    }
}
 

function update() { ctrl(); addEnemy(); enemyShoot(); // colisions game.physics.arcade.overlap(bullets, enemys, bulletHitEnemy, null, game); game.physics.arcade.overlap(enemys, player, enemyHitPlayer, null, game); game.physics.arcade.overlap(enemyBullets, player, bulletHitPlayer, null, game); } function bulletHitEnemy (bullet, enemy) { // When a bullet hits an enemy we kill them both bullet.kill(); enemy.kill(); explosion(enemy); bullet.destroy(true); enemy.destroy(true); // Increase the score score += 20; scoreText.text = scoreString + score; } function enemyHitPlayer(enemy, player) { enemy.kill(); explosion(enemy); enemy.destroy(true); lives -= 1; livesText.text = liveString + lives; if (lives < 1) { gameOver(); } } function bulletHitPlayer(player, enemyBullet) { enemyBullet.kill(); enemyBullet.destroy(true); lives -= 1; livesText.text = liveString + lives; explosion(player); if (lives < 1) { gameOver(); } }

when is destroy called from enemyBullet.events.onOutOfBounds then i get error Uncaught TypeError: Cannot read property 'camera' of null in phaser.js:37182 which is

 

 this.world.setTo(this.game.camera.x + this.worldTransform.tx, this.game.camera.y + this.worldTransform.ty);

 

in method Phaser.Sprite.prototype.preUpdate

 

When it is called in callback from game.physics.arcade.overlap then i get Uncaught TypeError: Cannot read property 'exists' of undefined which in phaser.js:63304 which is  if (group1.children.exists) 

 

in method collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly).

 

Can you please give me advise how to use destroy() ?

Sorry for my english, it is not my native language.

 

Link to comment
Share on other sites

You could .kill() the sprites (enemies / bullets) instead of destroying them.

They are then invisible - and you won't get any errors.

 

Now you might think you will end up with unlimited invisible sprites that clog up the memory - but for spawning new enemies / bullets you always first check if there are dead ones and reset and reuse those.

 

Something like this:

//spawn new enemyvar enemy = enemyGroup.getFirstDead();if (enemy != null) {  enemy.reset(100, 100);} else {  enemy = game.add.sprite(100, 100, "enemy");}

If you really want to destroy the enemies and bullets you should only do that during the update() call to your state, not in callbacks.

(As you have experienced callbacks often happen during loops over lists of sprites - and those loops (and the code they call) do not like it when sprites vanish during those callbacks).

 

To do implement this, you could during the callback push the sprite into a "toBeDestroyed" array and at the start of the update loop destroy every sprite in that array.

Link to comment
Share on other sites

Hello,

 

thank you for your answer. I want to destroy them insted of killing because I want to get a random enemy from the group and make him shoot in the update loop. If I only kill them then getRandom gives me dead enemies. If I know it right, there is no getRandomAlive method and I dont want to do getRandom repeatedly and check if it is alive or not. So I will do it according to your advice and make toBeDestroyed array and destroy them in the beginning of update loop. Thank you.

Link to comment
Share on other sites

  • 2 weeks later...

Another option is to kill them and in the update loop verify whether they are alive or not. If they are dead, then destroy them. Something like this:

Bullet.prototype.onCollision = function(bullet, enemy) {  bullet.kill();};Bullet.prototype.update = function() {  if (this.alive) {    // Do your stuff here    // ...  } else {    this.destroy();  }};

This would save you from creating and maintaining an extra array to handle the dead bullets.

Link to comment
Share on other sites

You could still use kill() in that scenario, you just need to use forEachAlive() to filter out the dead ones.

randomEnemyFire: function () {		//randomly determine if we should fire, then randomly select a unit to fire.		if (this.enemies.countLiving() > 0) {			var livingEnemies = [];			livingEnemies.length = 0;			this.enemies.forEachAlive(function (enemy) {				livingEnemies.push(enemy);			}, this.enemies);			var firingEnemy = Math.floor(Math.random() * livingEnemies.length);			this.fireRedLaser(livingEnemies[firingEnemy]);		}	},
Link to comment
Share on other sites

  • 2 weeks later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...