Santiago

Group of enemies don't take damage

Recommended Posts

Hello! I have a group of enemies following the player, and I want when they are overlapping with the player and I press Q they take an amount of damage setted before.

 

this is the part of the create function where I create the group

this.enemies = game.add.group();
        this.enemies.enableBody = true;
        this.enemies.setAll('body.immovable', true);
        
        this.enemies.createMultiple(5,"vikingo")
        
        this.enemies.children[0,1,2,3,4].health = 100;
        console.log(this.enemies.children[0,1,2,3,4].health)

Here's the function I'm trying to use. Before I used the same syntax with a single sprite and went perfectly. In this case the console throws "Uncaught ReferenceError: i is not defined"

matar: function(){
        
        if(this.player.scale.x == 1 && this.Q.justDown && game.physics.arcade.overlap(this.player, this.enemies)) {
            
            this.enemies.children[i].damage(25);

            game.physics.arcade.moveToXY(this.enemies.children[i],15,2500,-300,0)
            console.log(this.enemies.children[i].health)
        }
        
        if(this.player.scale.x == -1 && this.Q.justDown && game.physics.arcade.overlap(this.player, this.enemies)){
            
            this.enemies.children[i].damage(25);

            game.physics.arcade.moveToXY(this.enemies.children[i],-15,-2500,300,0)
            console.log(this.enemies.children[i].health)
        }
        
    },

I tested some other ways like changing children with children[0,1,2,3,4] but instead of throwing error I get "health = 100" all the time.

Share this post


Link to post
Share on other sites

I've forgotten something important, I got here an addEnemies() function, where I set the properties of the sprite, and I don't know if I should set the health property here, although I tried with negative results

addEnemies: function (){

    for(var e = 0; e<3; e++){
        
        
       var posX = game.world.randomX;
                
       this.enemy = this.enemies.getFirstDead();
        
        if(!this.enemy) return;
        
        //PROPERTIES
        
        
        this.enemy.anchor.setTo(0.5, 1);
        this.enemy.tint = 0x000000
        this.enemy.reset(posX, 200)
        this.enemy.body.gravity.y = 500;
        this.enemy.checkWorldBounds = true;
        this.enemy.outOfBoundsKill = true;
        
        
        }    
        
        
        
    },

 

Share this post


Link to post
Share on other sites
var state = {

  create: function () {
    this.enemies = game.add.group();
    this.enemies.enableBody = true;
    this.enemies.createMultiple(5, 'vikingo');
    this.enemies.setAll('health', 100);
    this.enemies.setAll('body.immovable', true);
  },

  update: function () {
    var arcade = game.physics.arcade; // shortcut

    if (this.Q.justDown) {
      arcade.overlap(this.player, this.enemies, function (overlappingPlayer, overlappingEnemy) {
        overlappingEnemy.damage(25);

        if (overlappingPlayer.scale.x === 1) {
          arcade.moveToXY(overlappingEnemy, 15, 2500, -300, 0);
        } else {
          arcade.moveToXY(overlappingEnemy, -15, -2500, 300, 0);
        }
      });
    }
  }
};

 

Share this post


Link to post
Share on other sites

Hey, that was really helpful! I appreciate it! Could you explain what you've done? Because as long as I'm still being a newbie, I can't understand at all how it works the function in the executing code of the if statement.

Again I thank you very much, and the only problem came up is when overlappingEnemy.damage(25); is executed, enemies die instantly, because for some reason it takes 124 of damage, and I can't still to fix it.

 

Share this post


Link to post
Share on other sites

Remember update (and overlap) are running 60 times per second. I don't know how the sprites are moving, but if the player is overlapping one enemy for 4 frames in a row (about 67ms, not long), that enemy will receive damage 4 times and die.

Share this post


Link to post
Share on other sites
13 hours ago, samme said:

Remember update (and overlap) are running 60 times per second. I don't know how the sprites are moving, but if the player is overlapping one enemy for 4 frames in a row (about 67ms, not long), that enemy will receive damage 4 times and die.

 moveEnemies: function(){
    
    for(var i = 0; i < 1; i++){
                    
        if(this.enemies.children[i].body.x < (this.player.body.x - 40)) {
            
        this.enemies.children[i].body.velocity.x = 100;
    }
        else if(this.enemies.children[i].body.x > (this.player.body.x + 40)){
            
         this.enemies.children[i].body.velocity.x = -100;
        }
       
}
},

This is the function I use for moving my enemies. 

I don't think what you are saying is happening because in that case the health of enemies would be at a multiple of the damage taken, in this case 25 of 100, and the final health is -24, I still working on it and with no results

Share this post


Link to post
Share on other sites
9 hours ago, samme said:

Re. moveEnemies, use Group#forEach or Group#forEachAlive instead. As written, moveEnemies makes only one iteration (i.e. one sprite)

If the final health is -24 it's possible that the sprite started with health 1 (instead of 100) and received 25 damage once.

 

That's what I thought! But can't set the health, I mean, I tried to this.enemies.health = 100, same with this.enemy of my addEnemies function. I can't change the health value of overlappingPlayer in this case, how could I do it? I don't know what else to do! I know I'm annoying but this cost me a lot to learn, I even re-write al the code 3 times with same results, I always end up in the same result!

Share this post


Link to post
Share on other sites

Perfect, I realise now that I had this.enemies.createMultiple in exists = false (4th parameter), but if I set it to true, it avoids my addEnemies function and the MoveEnemies function and only appear one enemy flying.

So, if exists is set to false everything's fine, but this.enemies.setAll('health',100); doesn't work, but if set to to true, works but I get a rare behavior, I'm uploading pictures to understand.

Also, here is my code updated, I tried to simplify useless things.

 create: function () {

        this.cursor = game.input.keyboard.createCursorKeys();
        this.jump = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);
        this.Q = game.input.keyboard.addKey(Phaser.Keyboard.Q);
        this.enter = game.input.keyboard.addKey(Phaser.Keyboard.ENTER);
        

        
        
        this.timer = 0;
        
        //ENEMIGOS
        
        this.enemies = game.add.group();
        this.enemies.enableBody = true;
        this.enemies.setAll('body.immovable', true);
        this.enemies.setAll('anchor',0.5,1)
        this.enemies.createMultiple(10, 'enemigoAnim',[0,1,2,3,4]);
        this.enemies.setAll('health', 100);
        
        
        //ADD ENEMIES ANIMATIONS       
                    
        
        this.enemies.callAll('animations.add', 'animations', 'enemigoAnim', [0,1,2,3,4], 4, true);
        this.enemies.callAll('animations.play','animations','enemigoAnim')
        
        
        
    },



    update: function () {
        
        
        game.physics.arcade.collide(this.player, this.walls);
        game.physics.arcade.collide(this.enemies, this.walls);
        game.physics.arcade.overlap(this.player, this.enemies);
       
        
        
    
        this.moveEnemies();
        this.ataquePlayer()

        if (game.time.now > this.timer) {

            this.addEnemies(game.rnd.integerInRange(1));
 		
        this.timer = game.time.now + game.rnd.integerInRange(1000, 3000);;
 	}
        
    },
    
    
    addEnemies: function (){
    
    var enemies = 5;
        
    for(var e = 0; e<enemies; e++){
        
        var posX = game.world.randomX;
                
        if (posX > (this.player.x - 150) && posX < (this.player.x + 150))
                posX = -80;
       this.enemy = this.enemies.getFirstDead();
        
        if(!this.enemy) return;
        
        //PROPERTIES
        
        
        this.enemy.anchor.setTo(0.5, 1);
        this.enemy.reset(posX, 200)
        this.enemy.body.gravity.y = 1000;
        this.enemy.checkWorldBounds = true;
        this.enemy.outOfBoundsKill = true;
        
        }    
        
        
        
    },
    
    moveEnemies: function(){
    for(var i = 0; i < 50; i++){
    if(this.enemies.children[i].body.touching.down){
                    
        if(this.enemies.children[i].body.x < (this.player.body.x-40)) {
        
        this.enemies.children[i].body.velocity.x = 100;
        this.enemies.children[i].scale.x = 1;
        this.enemies.callAll('animations.play','animations','enemigoAnim')

            
    }
        else if(this.enemies.children[i].body.x > (this.player.body.x+40)){
            
         this.enemies.children[i].body.velocity.x = -100;
         this.enemies.children[i].scale.x = -1;  
         this.enemies.callAll('animations.play','animations','enemigoAnim')
         this.enemies.callAll('animations.play','animations','enemigoAnim')


        }
        
        else{
            
            this.enemies.children[i].body.velocity.x = 0;
            this.enemies.callAll('animations.stop','animations','enemigoAnim')
        }
    }
}
},
         
    
    
    
    
    

}

 

Beforehand thank you very much

exists = false.png

exists = true.png

Share this post


Link to post
Share on other sites

looks like maybe a problem is that when you create them with exists param = true, then all of them exist and are alive, so you're add function always returns on the first iteration of the loop without doing anything since getFirstDead() always returns null - since they're all alive. So I think they are all drawn to the same position since the add function returns before handling the positioning, never calling reset(posX, 200), so I would expect them to all be drawn at position (0, 0) which matches your second picture if you have some padding on your image I think... Maybe using callAll would work better than looping through them. Hopefully that helps, otherwise maybe I can look at it more tomorrow - yawn - if still stuck).

Also if still having trouble, if you can make a demo on CodePen or fork and update samme's, that will help a lot I think

 

UPDATE:  For reference this snippet from Phaser.Group.prototype.create (which is called by createMultiple), confirms alive and exists are both being set to the param exists:

child.exists = exists;
child.visible = exists;
child.alive = exists; /*************************/

 

Share this post


Link to post
Share on other sites
On 9/10/2017 at 2:07 PM, Santiago said:

So, if exists is set to false everything's fine, but this.enemies.setAll('health',100); doesn't work, but if set to to true, works but I get a rare behavior

In addEnemies, you call sprite.reset without a health argument, so it sets health=1.

If you call createMultiple with exists=false, addEnemies finds no dead enemies so it doesn't reset them. They're all still positioned at (0, 0), where they were created.

Share this post


Link to post
Share on other sites
On 12/9/2017 at 3:57 PM, samme said:

In addEnemies, you call sprite.reset without a health argument, so it sets health=1.

If you call createMultiple with exists=false, addEnemies finds no dead enemies so it doesn't reset them. They're all still positioned at (0, 0), where they were created.

That was the problem, I don't know how I've overlooked that, got to read better the API.-

Thank you very much.-

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.