Sign in to follow this  
owen

Select a currently visible sprite at random

Recommended Posts

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

 

 

 

 

 

Share this post


Link to post
Share on other sites

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())

Share this post


Link to post
Share on other sites
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);}

Share this post


Link to post
Share on other sites

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;}

Thanks

Owen

Share this post


Link to post
Share on other sites

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?

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

OK this is wierd.  For all of the sprites in the loop, I get these unexpected values for every sprite:

 

inCamera = undefined

x = 0

y = 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                  }        });    });

Cheers

Owen

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.