GourmetGorilla Posted May 5, 2015 Share Posted May 5, 2015 I'm playing around with phasers invaders example game.When the object is shot, instead of killing it I'm changing the sprite and moving it to the bottom of the screen. However, it can now be shot again. I don't want it to be shootable a 2nd time. I'm thinking that because the gamephysics are on the group 'aliens', there are probably two options.a) Either I can take the single shot alien out of the group 'aliens' and hope that stops it from being shot a 2nd time. Or there's some way of saying ' alien just shot = now protected from being shot again' , I tried the following to no avail.alien.physicsBodyType = null;This is my collision handler right now function collisionHandler (bullet, alien) {// When a bullet hits an alien we kill them bothbullet.kill();alien.loadTexture("cured");// move alien to bottomvar tween2 = game.add.tween(alien).to( { y: 300 }, 1000, Phaser.Easing.Linear.EaseIn, true);tween2.onComplete.add(doNext, this);tween2.start();So, basically the changed sprite can still be shot at, I need to make it so it cannot be shot at.Here's the full code:var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });function preload() { game.load.image('bullet', 'assets/games/invaders/bullet.png'); game.load.image('enemyBullet', 'assets/games/invaders/enemy-bullet.png'); game.load.spritesheet('invader', 'assets/games/invaders/invader32x32x4.png', 32, 32); game.load.spritesheet('cured', 'assets/games/invaders/happy32x32x4.png', 32, 32); game.load.image('ship', 'assets/games/invaders/player.png'); game.load.spritesheet('kaboom', 'assets/games/invaders/explode.png', 128, 128); game.load.spritesheet('love', 'assets/games/invaders/hearts.png', 128, 128); game.load.image('starfield', 'assets/games/invaders/starfield.png');}var player;var aliens;var bullets;var bulletTime = 0;var cursors;var fireButton;var explosions;var explosions2;var starfield;var score = 0;var scoreString = '';var scoreText;var lives;var enemyBullet;var firingTimer = 0;var stateText;var livingEnemies = [];function create() { game.physics.startSystem(Phaser.Physics.ARCADE); // The scrolling starfield background starfield = game.add.tileSprite(0, 0, 800, 600, 'starfield'); // Our bullet group bullets = game.add.group(); bullets.enableBody = true; bullets.physicsBodyType = Phaser.Physics.ARCADE; bullets.createMultiple(30, 'bullet'); bullets.setAll('anchor.x', 0.5); bullets.setAll('anchor.y', 1); bullets.setAll('outOfBoundsKill', true); bullets.setAll('checkWorldBounds', true); // The enemy's bullets enemyBullets = game.add.group(); enemyBullets.enableBody = true; enemyBullets.physicsBodyType = Phaser.Physics.ARCADE; enemyBullets.createMultiple(30, 'enemyBullet'); enemyBullets.setAll('anchor.x', 0.5); enemyBullets.setAll('anchor.y', 1); enemyBullets.setAll('outOfBoundsKill', true); enemyBullets.setAll('checkWorldBounds', true); // The hero! player = game.add.sprite(400, 535, 'ship'); player.anchor.setTo(0.5, 0.5); game.physics.enable(player, Phaser.Physics.ARCADE); // The baddies! aliens = game.add.group(); aliens.enableBody = true; aliens.physicsBodyType = Phaser.Physics.ARCADE; createAliens(); // The score scoreString = 'Score : '; scoreText = game.add.text(10, 10, scoreString + score, { font: '34px Arial', fill: '#1C2840' }); // Lives lives = game.add.group(); game.add.text(game.world.width - 100, 10, 'Lives ', { font: '34px Arial', fill: '#1C2840' }); // Text stateText = game.add.text(game.world.centerX,game.world.centerY,' ', { font: '84px Arial', fill: '#5C85D6' }); stateText.anchor.setTo(0.5, 0.5); stateText.visible = false; for (var i = 0; i < 3; i++) { var ship = lives.create(game.world.width - 100 + (35 * i), 60, 'ship'); ship.anchor.setTo(0.5, 0.5); ship.angle = 0; ship.alpha = 0.5; } // An explosion pool explosions = game.add.group(); explosions.createMultiple(30, 'love'); explosions.forEach(setupInvader, this); // 2nd explosion pool explosions2 = game.add.group(); explosions2.createMultiple(30, 'kaboom'); explosions2.forEach(setupPlayer, this); // And some controls to play the game with cursors = game.input.keyboard.createCursorKeys(); fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR); }function createAliens () { for (var y = 0; y < 4; y++) { for (var x = 0; x < 10; x++) { var alien = aliens.create(x * 48, y * 50, 'invader'); alien.anchor.setTo(0.5, 0.5); alien.animations.add('fly', [ 0, 1, 2, 3 ], 20, true); alien.play('fly'); alien.body.moves = false; } } aliens.x = 100; aliens.y = 200; // All this does is basically start the invaders moving. Notice we're moving the Group they belong to, rather than the invaders directly. var tween = game.add.tween(aliens).to( { x: 200 }, 2000, Phaser.Easing.Linear.None, true, 0, 1000, true); // When the tween loops it calls descend tween.onLoop.add(descend, this);}function setupInvader (invader) { invader.anchor.x = 0.5; invader.anchor.y = 0.5; invader.animations.add('love');}function setupPlayer (ship) { ship.anchor.x = 0.5; ship.anchor.y = 0.5; ship.animations.add('kaboom');}function descend() { aliens.y -= 10;}function update() { // Scroll the background // starfield.tilePosition.y += 2; if (player.alive) { // Reset the player, then check for movement keys player.body.velocity.setTo(0, 0); if (cursors.left.isDown) { player.body.velocity.x = -200; } else if (cursors.right.isDown) { player.body.velocity.x = 200; } // Firing? if (fireButton.isDown) { fireBullet(); } if (game.time.now > firingTimer) { enemyFires(); } // Run collision game.physics.arcade.overlap(bullets, aliens, collisionHandler, null, this); game.physics.arcade.overlap(enemyBullets, player, enemyHitsPlayer, null, this); }}function render() { // for (var i = 0; i < aliens.length; i++) // { // game.debug.body(aliens.children[i]); // }}function collisionHandler (bullet, alien) { // When a bullet hits an alien we kill them both bullet.kill();// alien.physicsBodyType = null; alien.loadTexture("cured"); // move alien to bottom var tween2 = game.add.tween(alien).to( { y: 300 }, 1000, Phaser.Easing.Linear.EaseIn, true);tween2.onComplete.add(doNext, this); tween2.start();function doNext (happy){ alien.kill();}; // Increase the score score += 20; scoreText.text = scoreString + score; // And create an explosion var explosion = explosions.getFirstExists(false); explosion.reset(alien.body.x, alien.body.y); explosion.play('love', 30, false, true); if (aliens.countLiving() == 0) { score += 1000; scoreText.text = scoreString + score; enemyBullets.callAll('kill',this); stateText.text = " You Won, \n Click to restart"; stateText.visible = true; //the "click to restart" handler game.input.onTap.addOnce(restart,this); }}function enemyHitsPlayer (player,bullet) { bullet.kill(); live = lives.getFirstAlive(); if (live) { live.kill(); } // And create an explosion var explosion2 = explosions2.getFirstExists(false); explosion2.reset(player.body.x, player.body.y); explosion2.play('kaboom', 30, false, true); // When the player dies if (lives.countLiving() < 1) { player.kill(); enemyBullets.callAll('kill'); stateText.text=" GAME OVER \n Click to restart"; stateText.visible = true; //the "click to restart" handler game.input.onTap.addOnce(restart,this); }}function enemyFires () { // Grab the first bullet we can from the pool enemyBullet = enemyBullets.getFirstExists(false); livingEnemies.length=0; aliens.forEachAlive(function(alien){ // put every living enemy in an array livingEnemies.push(alien); }); if (enemyBullet && livingEnemies.length > 0) { var random=game.rnd.integerInRange(0,livingEnemies.length-1); // randomly select one of them var shooter=livingEnemies[random]; // And fire the bullet from this enemy enemyBullet.reset(shooter.body.x, shooter.body.y); game.physics.arcade.moveToObject(enemyBullet,player,120); firingTimer = game.time.now + 2000; }}function fireBullet () { // To avoid them being allowed to fire too fast we set a time limit if (game.time.now > bulletTime) { // Grab the first bullet we can from the pool bullet = bullets.getFirstExists(false); if (bullet) { // And fire it bullet.reset(player.x, player.y + 8); bullet.body.velocity.y = -400; bulletTime = game.time.now + 200; } }}function resetBullet (bullet) { // Called if the bullet goes out of the screen bullet.kill();}function restart () { // A new level starts //resets the life count lives.callAll('revive'); // And brings the aliens back from the dead aliens.removeAll(); createAliens(); //revives the player player.revive(); //hides the text stateText.visible = false;} Link to comment Share on other sites More sharing options...
jonoco Posted May 6, 2015 Share Posted May 6, 2015 This should be as simple as turning off the alien's body, which would prevent any more collisions being detected.function collisionHandler (bullet, alien) { // When a bullet hits an alien we kill them both bullet.kill(); alien.loadTexture("cured"); alien.body = null;You can read more about the sprite's body property here if you're curious: http://phaser.io/docs/2.3.0/Phaser.Sprite.html#body Link to comment Share on other sites More sharing options...
GourmetGorilla Posted May 7, 2015 Author Share Posted May 7, 2015 Thanks jonoco, nice suggestion, but throws the error: alien.body is null @ invaders.js:243 - basically alien is used later in that function. here's my new code: // change alien sprite alien.loadTexture("cured"); alien.body = null; // move alien to bottom of screen var tween2 = game.add.tween(alien).to( { y: 300 }, 1000, Phaser.Easing.Linear.EaseIn, true); tween2.onComplete.add(doNext, this); tween2.start(); //for now, kill alien function doNext (alien){ alien.kill(); }; The entire function collisionHandler is as follows.function collisionHandler (bullet, alien) { // When a bullet hits an alien we kill them both bullet.kill(); // change alien sprite alien.loadTexture("cured"); alien.body = null; // move alien to bottom of screen var tween2 = game.add.tween(alien).to( { y: 300 }, 1000, Phaser.Easing.Linear.EaseIn, true); tween2.onComplete.add(doNext, this); tween2.start(); //for now, kill alien function doNext (alien){ alien.kill(); }; // Increase the score score += 20; scoreText.text = scoreString + score; // And create an explosion var explosion = explosions.getFirstExists(false); explosion.reset(alien.body.x, alien.body.y); explosion.play('love', 30, false, true); // add count if (aliens.countLiving() == 0) { score += 1000; scoreText.text = scoreString + score; enemyBullets.callAll('kill',this); stateText.text = " You Won, \n Click to restart"; stateText.visible = true; //the "click to restart" handler game.input.onTap.addOnce(restart,this); }} If I move that code block to below the last alien reference, as per the below, I get a weird intermittent error: shooter.body is null @ invaders.js:310 function collisionHandler (bullet, alien) { // When a bullet hits an alien we kill them both bullet.kill(); // Increase the score score += 20; scoreText.text = scoreString + score; // And create an explosion var explosion = explosions.getFirstExists(false); explosion.reset(alien.body.x, alien.body.y); explosion.play('love', 30, false, true); // change alien sprite alien.loadTexture("cured"); alien.body = null; // move alien to bottom of screen var tween2 = game.add.tween(alien).to( { y: 300 }, 1000, Phaser.Easing.Linear.EaseIn, true); tween2.onComplete.add(doNext, this); tween2.start(); //for now, kill alien function doNext (alien){ alien.kill(); }; // add count if (aliens.countLiving() == 0) { score += 1000; scoreText.text = scoreString + score; enemyBullets.callAll('kill',this); stateText.text = " You Won, \n Click to restart"; stateText.visible = true; //the "click to restart" handler game.input.onTap.addOnce(restart,this); }}Any ideas? Link to comment Share on other sites More sharing options...
drhayes Posted May 7, 2015 Share Posted May 7, 2015 I think taking the alien out of the aliens group is a great way to stop it from getting shot. Make another group called deadAliens or something? Since you're only checking bullets and aliens you'd be good. Link to comment Share on other sites More sharing options...
GourmetGorilla Posted May 7, 2015 Author Share Posted May 7, 2015 Yes I tried that, but for some reason it moves the position of the alien, and also it can still be shot at - strange o.O. Here was my group add code (I'm learning ): deadAliens.add(alien);And I created the group above that: deadAliens = game.add.group();Why can I still shoot these dead aliens when they've been taken out of the group? poor aliens, being shot dead twice. Link to comment Share on other sites More sharing options...
ladybenko Posted May 7, 2015 Share Posted May 7, 2015 Probably not the most efficient way, but you can always add a flag to the aliens that are not shootable anymore. Then you pass an additional filter to the overlap method. Assuming that flag is called immune, you could have:game.physics.arcade.overlap(bullets, aliens, collisionHandler, function (bullet, alien) { return !alien.immune;}, this); Link to comment Share on other sites More sharing options...
drhayes Posted May 7, 2015 Share Posted May 7, 2015 Adding it to a different group probably moves it because the different group has a new position. See this?aliens.x = 100;aliens.y = 200;That's assigning the x/y position of the aliens group. If your new group, deadAliens, has the same x/y position then the aliens won't jump when you switch them from one group to another. And "deadAliens.add(alien);" looks good to me. It'll handle removing the alien from the old group. Link to comment Share on other sites More sharing options...
Recommended Posts