Santiago Posted August 27, 2017 Share Posted August 27, 2017 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 More sharing options...
Santiago Posted August 27, 2017 Author Share Posted August 27, 2017 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 More sharing options...
samme Posted August 27, 2017 Share Posted August 27, 2017 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 More sharing options...
Santiago Posted August 28, 2017 Author Share Posted August 28, 2017 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 More sharing options...
samme Posted August 28, 2017 Share Posted August 28, 2017 You probably want to use arcade.collide. Because unless you separate the overlapping sprites they will still overlap on consecutive frames (and take more damage). Link to comment Share on other sites More sharing options...
Santiago Posted August 29, 2017 Author Share Posted August 29, 2017 Could you explain better? I can't get what you mean. Link to comment Share on other sites More sharing options...
samme Posted August 29, 2017 Share Posted August 29, 2017 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 More sharing options...
pdiddles03 Posted August 29, 2017 Share Posted August 29, 2017 I'm confused as to why the arcade physics is being defined in the update function. Shouldn't it be defined once? Link to comment Share on other sites More sharing options...
samme Posted August 29, 2017 Share Posted August 29, 2017 You can change that back if you don't like it. It's just a shortcut reference so you don't have to type game.physics.arcade over and over. Link to comment Share on other sites More sharing options...
Santiago Posted August 29, 2017 Author Share Posted August 29, 2017 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 More sharing options...
Santiago Posted September 2, 2017 Author Share Posted September 2, 2017 Seems no one can help... Link to comment Share on other sites More sharing options...
samme Posted September 2, 2017 Share Posted September 2, 2017 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. Link to comment Share on other sites More sharing options...
Santiago Posted September 3, 2017 Author Share Posted September 3, 2017 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 More sharing options...
Santiago Posted September 3, 2017 Author Share Posted September 3, 2017 I also could set my own health variable, not the phaser propertie and with a forEachAlive I killed the sprites, but kills all the group Link to comment Share on other sites More sharing options...
samme Posted September 3, 2017 Share Posted September 3, 2017 See the CodePen. You need to use setAll after creating the enemies. this.enemies.createMultiple(5, 'vikingo', 0, true); this.enemies.setAll('health', 100); Link to comment Share on other sites More sharing options...
Santiago Posted September 10, 2017 Author Share Posted September 10, 2017 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 Link to comment Share on other sites More sharing options...
Santiago Posted September 12, 2017 Author Share Posted September 12, 2017 Nobody can help? Link to comment Share on other sites More sharing options...
Taz Posted September 12, 2017 Share Posted September 12, 2017 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 More sharing options...
samme Posted September 12, 2017 Share Posted September 12, 2017 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 More sharing options...
Santiago Posted September 14, 2017 Author Share Posted September 14, 2017 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 More sharing options...
Recommended Posts