owen Posted September 14, 2014 Share Posted September 14, 2014 Hi. OK this should be really simple. I want to randomly select 1 of the sprites which are currently visible (inCamera) within the object layer. (The randomly selected sprite will become the target for my player's heatseeker missile.) I am a little stuck on how to do this, specifically how to do a forEach on all of the object layer's currently visible sprites. I am sure this is very simple but I can't see an example of it. Any ideas how I can do this? Thanks!Owen Link to comment Share on other sites More sharing options...
Taleforge Posted September 15, 2014 Share Posted September 15, 2014 You could create a group, containing all targetable sprites. So you can iterate through the childs of that group.If you dont want to create a own group - the game.world also extends the Phaser.Group! Then you can check if the Sprite is visible:game.camera.screenView.intersects(mySprite.getBounds()) Link to comment Share on other sites More sharing options...
lewster32 Posted September 15, 2014 Share Posted September 15, 2014 group.forEachAlive(function(sprite) { if (sprite.visible && sprite.inCamera) { // do something with all visible sprites }});The key is that the callback returns each object, so you can query each one within the callback. A more clever way to do this would be to filter the children array and return a random one, like so:function getRandomVisible(group) { var visible = group.children.filter(function(sprite) { return (sprite.exists && sprite.alive && sprite.visible && sprite.inCamera); } return Phaser.Math.getRandom(visible);} owen 1 Link to comment Share on other sites More sharing options...
Taleforge Posted September 15, 2014 Share Posted September 15, 2014 Nice - that "inCamera"-property is new to me! Link to comment Share on other sites More sharing options...
owen Posted September 15, 2014 Author Share Posted September 15, 2014 Thanks Lewster. This looks good in theory but unfortunately for me it's not working. The below gives console output of "targeted: null" even though I definitely have items in the badguys group, the filter seems to be filtering the group down to nothing at all, meaning there is no bad guy chosen from those on screen. It seems the inCamera property is the problem because if I take that out then console output gives an object (albeit not one I can use since it's not visible). So almost but not quite there. Is there something I have to do to make inCamera work properly?function getRandomBadguy() { var visibleBadGuys = badguys.children.filter(function (sprite) { return (sprite.exists && sprite.alive && sprite.visible && sprite.inCamera); }); var targeted = Phaser.Math.getRandom(visibleBadGuys); console.log("targeted: " + targeted); return targeted;}ThanksOwen Link to comment Share on other sites More sharing options...
lewster32 Posted September 15, 2014 Share Posted September 15, 2014 Hmm not sure... the code that's run when you check inCamera is as follows:this.game.world.camera.screenView.intersects(this.getBounds());So it doesn't seem to rely on anything else to enable it. Can you check that any of your sprites are ever getting inCamera marked as true? Link to comment Share on other sites More sharing options...
Taleforge Posted September 17, 2014 Share Posted September 17, 2014 Try to debug the code, "this.game.world.camera.screenView" and "this.getBounds()" are both Phaser.Rectangle - so it should not be hard to manually check if they intersect or not! Link to comment Share on other sites More sharing options...
MorpheusZ Posted September 17, 2014 Share Posted September 17, 2014 a slightly more efficient solution that does not require creating a temporary list:var getRandomSprite() = function(group) { var randomSprite = null, cnt = 0; group.forEachAlive(function(sprite) { if (sprite.visible && sprite.inCamera) { ++cnt; if (Math.random() <= 1 / cnt) { randomSprite = sprite; } } }); return randomSprite;}do that math and you'll see that each visible sprite has the same probability of being picked lewster32 1 Link to comment Share on other sites More sharing options...
owen Posted September 17, 2014 Author Share Posted September 17, 2014 OK this is wierd. For all of the sprites in the loop, I get these unexpected values for every sprite: inCamera = undefinedx = 0y = 0 Why might inCamera be undefined? Surely it's either true or false every time?The X and Y can't possibly be correct as I'm seeing lots of bad guys and other sprites all over the screen. Any idea what I might be doing wrong here? EDIT: I solved it.The problem was that it turns out I was not looping through sprites, but through groups of sprites. My own silly fault. When I populated by badguys group I was populating it with groups of sprites, not sprites. Of course a group does not have X or Y properties (these came back as 0 at group level) and there is no inCamera property of a group, so it makes sense that it was undefined. I modified the code as follows and it works. badguys.children.forEach(function (badguyGroup) { badguyGroup.children.forEach(function (sprite) { if (sprite.visible && sprite.inCamera) { console.log("IN-CAMERA TARGET FOUND"); // do stuff with target sprite } }); });CheersOwen Link to comment Share on other sites More sharing options...
Recommended Posts