Jump to content

Group Damage()


Heppell08
 Share

Recommended Posts

I've been working on this for a bit of time, used the EXACT same code i have in another project that works perfectly and does what i need. The only differences being the phaser versions.

My old project was a 1.1.4 phaser game and my current is 2.0.4.

 

Now i can reference each enemy to die when show, thats simple enough. I have assigned them all health in my group creation, the console tells me they have 100 health.

 

I then in another function i'm using with arcade physics overlap callback, telling the bullet to image itself to kill(); and to the hurt the enemy it overlapped with.

It kills the enemy instantly without even touching the health! This is not the expected behaviour i had considering ive done the same code that worked previously.

 

Not sure if damage wants to be done differently or something else but i just cant get it to do what i require.

 

I've checked http://docs.phaser.io/Phaser.Sprite.html#damage and it seems the same as it always was by calling .damage(5);

 

Heres my code:

 

enemies = this.add.group();for(var j = 0; j < enemyRound; j++){enemy = this.add.sprite(this.world.randomX, this.world.randomY, 'enemy1');enemy.anchor.setTo(0.5,0.5);enemy.health = 100;this.physics.arcade.enable(enemy);        enemies.add(enemy);}

Then in the overlap for arcade i call this on overlap:

 

enemyShot: function(enemy, bullet01){    var j;    for(j = 0; j < enemies.length; j++)    {        enemies.getAt(j).damage(1);    }    console.log('Life:' + enemy.health);    bullet01.kill();}

If you see what im doing wrong please let me know ASAP becasue this has really got me thinking what i may have done differently or not.

 

 

Thanks :)

 

Update: i did notice that if i put the core function code in my update,it would take the health from the robots, it just wont do it in my function when its outside the update.

 

EDIT: Took enemy out the parameter of the function, works ok, just now that the enemies are not dying 1 by 1...

Link to comment
Share on other sites

The overlapping bullet is in a group of bullets called bulletgroup.

this.physics.arcade.overlap(bulletGroup, enemies, this.enemyShot, null, this);

I create my bullets like so:

bulletGroup = this.add.group(player)	bulletGroup.enableBody = true;    bulletGroup.physicsBodyType = Phaser.Physics.ARCADE;    bulletGroup.createMultiple(30, 'bullet01', 0, false);    bulletGroup.setAll('anchor.x', 0.5);    bulletGroup.setAll('anchor.y', 0.5);    bulletGroup.setAll('scale.x', 0.5);    bulletGroup.setAll('scale.y', 0.5);    bulletGroup.setAll('outOfBoundsKill', true);    bulletGroup.setAll('checkWorldBounds', true);

then i call this on the overlap of the bullet and the enemy:

enemyShot: function(bullet01){    var j;    for(j = 0; j < enemies.length; j++)    {        enemies.getAt(j).damage(1);    }    console.log('Life:' + enemy.health);    bullet01.kill();}

I've done the exact same code before in a previous project but for some reason it wont work in 2.0.4 of phaser.

Link to comment
Share on other sites

enemies = this.add.group();

for(var j = 0; j < enemyRound; j++)

{

enemy = this.add.sprite(this.world.randomX, this.world.randomY, 'enemy1');

enemy.anchor.setTo(0.5,0.5);

this.physics.arcade.enable(enemy);

        enemies.add(enemy);

}

enemies.setAll('health', 100);

enemies.callAll('animations.add','animations','enemywalk',[0,1,2,3,4,5,6,7], 12, true); 

Link to comment
Share on other sites

What i guess here is that the way your code first was it killed the ENEMY when you called the bullet01.kill(). Are you sure the order you passed the group was correct?

When you ruled out the enemy by only passing the bullet inside the enemyShot you say that all of the enemies died like they should (not only with 1 damage) but they died all together. 

I think it's possible for it to work correctly but the execution is so fast that you can't see the difference of them when they die.

Link to comment
Share on other sites

I think the problem lies in this part:

enemyShot: function(bullet01){    var j;    for(j = 0; j < enemies.length; j++)    {        enemies.getAt(j).damage(1);    }    console.log('Life:' + enemy.health);    bullet01.kill();}

This is included in the overlap callback, which is called continuously while the objects overlap. In it, you're looping through every enemy and inflicting 1 damage. At 60fps, this will do 60 damage per second to every enemy on the screen until the bullet is killed (which is not necessarily instantly in the case of physics calculations). I'm not entirely sure why you're looping through all the enemies as surely you only want to damage the one enemy that's hit? In which case the function should probably be like so:

enemyShot: function(currentEnemy, currentBullet){  if (currentBullet.alive && currentEnemy.alive) { // ensure both are alive to prevent unwanted calls    currentEnemy.damage(1);    console.log('Life:' + currentEnemy.health);    currentBullet.kill();  }}
Link to comment
Share on other sites

I got it 70% working. The problem i face now is when i go to kill the bullet, it kills the enemy too in a single hit on impact with the enemy.

If i dont kill the bullet, the health is removed as it should be from the enemy in the way you and i would predict. Its very strange behaviour and im starting to think its because of my bullet group creation.

 

bulletGroup = this.add.group(player)bulletGroup.enableBody = true;    bulletGroup.physicsBodyType = Phaser.Physics.ARCADE;    bulletGroup.createMultiple(30, 'bullet01', 0, false);    bulletGroup.setAll('anchor.x', 0.5);    bulletGroup.setAll('anchor.y', 0.5);    bulletGroup.setAll('scale.x', 0.5);    bulletGroup.setAll('scale.y', 0.5);    bulletGroup.setAll('outOfBoundsKill', true);    bulletGroup.setAll('checkWorldBounds', true);

so what imn going to try now is removing the whole setAll stuff, and coding it in like a standard group to see the results after that.

Link to comment
Share on other sites

I'd maybe set enemy.isEnemy = true on all enemies during creation, and only call .kill() if enemy.isEnemy === true just to get some sanity checking going, and make sure that only bullets are being directly killed, whereas enemies are being killed as a result of their health reaching zero.

Link to comment
Share on other sites

I'd maybe set enemy.isEnemy = true on all enemies during creation, and only call .kill() if enemy.isEnemy === true just to get some sanity checking going, and make sure that only bullets are being directly killed, whereas enemies are being killed as a result of their health reaching zero.

 

Even setting an isEnemy flag does nothing.Heres a gif of it happening with console showing too.

 

http://imgur.com/WbfxnAc

Link to comment
Share on other sites

Afraid I can't view the gif or the content on DropBox because of my work's proxy but I'll take a look when I get home later. I think in the mean time you just need to keep trying to rule out all other factors that are causing kill() to be invoked.

 

You may want to try calling game.enableStep() when a bullet is fired to pause the game, and set something up outside of Phaser to call game.step() (onClick on a button maybe) so you can systematically step through the game updates and see what's happening at each frame.

Link to comment
Share on other sites

I've taken a look and the issue here is globals. 'enemy' is defined globally, and is populated with the last created enemy. When you run the callback function, 'enemy' isn't what you expect it to be. Changing the callback to this seems to fix the problem:

enemyShot: function(thisBullet, thisEnemy){	if(thisEnemy.isEnemy === true)	{        thisEnemy.damage(1);    }    thisBullet.kill();    console.log('Enemy:' + thisEnemy.health);}

You have to be careful about where you define variables, as a global variable will supersede any local variables or function parameters with the same name. I'd recommend taking 'var enemy;' out at line 27 and instead defining it inside the create function as follows:

	enemies = this.add.group();        var enemy;	for(var j = 0; j < enemyRound; j++)	{		enemy = this.add.sprite(this.world.randomX, this.world.randomY, 'enemy1');		this.physics.arcade.enable(enemy);		enemy.isEnemy = true;        enemies.add(enemy);	}
Link to comment
Share on other sites

The same goes for all of the other globally defined variables in your game; try to encapsulate as much as possible. Define variables only inside functions (preferably at the top of the function, just to keep them all together) and if you need to access something outside of that function, consider whether you can pass it to the function you need to call via its parameters; and if that's impractical then make it a property of your state so it can be accessed pretty much anywhere so long as it's in the state. It's possible to write JavaScript with virtually no pollution of the global namespace, and it's very good practice to try and achieve that.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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