naril Posted December 13, 2014 Share Posted December 13, 2014 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 More sharing options...
jpdev Posted December 14, 2014 Share Posted December 14, 2014 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. naril and satanas 2 Link to comment Share on other sites More sharing options...
naril Posted December 14, 2014 Author Share Posted December 14, 2014 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 More sharing options...
satanas Posted December 26, 2014 Share Posted December 26, 2014 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 More sharing options...
Rezalas Posted January 2, 2015 Share Posted January 2, 2015 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 More sharing options...
Oliganti Posted January 15, 2015 Share Posted January 15, 2015 I would like to thank you for this. I have just implemented recycling of the sprites and the effect was overwhelming. Link to comment Share on other sites More sharing options...
Recommended Posts