Jump to content

Group of enemies don't take damage


Santiago
 Share

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.

Link to comment
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;
        
        
        }    
        
        
        
    },

 

Link to comment
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);
        }
      });
    }
  }
};

 

Link to comment
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.

 

Link to comment
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.

Link to comment
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

Link to comment
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!

Link to comment
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

Link to comment
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; /*************************/

 

Link to comment
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.

Link to comment
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.-

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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