Jump to content

Randomly select multiple different objects from a group


Michel (Starnut)
 Share

Recommended Posts

Hello again,

 

here is another problem I'm currently facing: I have, say, 5 passengers that each want one of 41 seats on a bus. Since I want them to be distributed sort of evenly over the bus, I need to select those seats randomly. But whenever I've appointed a seat to a passenger, I want to skip this seat for the remaining passengers.

 

Normally, I'd create a duplicate (slice) of the array of seats, shuffle it and then simply pop of one seat after the other or, alternatively, randomly splice them off the unshuffled array.

 

But how would I do this somewhat elegantly with a Phaser.Group, which my seats are in? I've been browsing the docs quite some and failed to come up with a satisfying solution. Any ideas?

 

Thanks,

Michel

Link to comment
Share on other sites

Honestly I would just do it the way you're used to - so get a list of all available seats from the Group and put a reference to these objects in a local array. Then shuffle / sort / pop until you are done, assigning passengers as you go. Also look at the RandomDataGenerator class (until game.rnd) as it has several useful functions for picking from arrays with weights.

Link to comment
Share on other sites

Or maybe, if you don't want your local array to be garbage collected at an unpredictable time, you could mark the seats of the group as they are assigned.

 

Something like this, assuming seats is your group  :

var seat;for(var i=0; i<5; i++) {  seat = seats.getRandom();  while ( seat.pax_assigned ) {       // already assigned    seats.cursor = seat;              // if I understand well the cursor property    seat = seats.next().cursor;       // get the next unassigned   }  seat.pax_assigned = true;}

not tested, just imagined from the documentation

Link to comment
Share on other sites

Thanks, guys,

 

@rich, thanks for the affirmation. One of the things I was wondering was whether there was simpler access to the array of elements in a group besides calling getAt in a for loop. 

 

@Jerome: thanks for the input. I checked out the cursor functionality some more and figured, I might as well stick with the getAt approach. I eventually came up with this (mind that I'm using the project template and thus code looks a little different from the other examples):

// generic function to find all objects in a group that match a given key value pairfindMatchesInGroup: function(key, value, group) {    var matches = [],        item;    for (var i = 0; i < group.length; i++) {        item = group.getAt(i);        if (item[key] === value)            matches.push(item);    };    return matches;},// takes an array of passenger objects and assigns them seat objects from a second array.// Both arrays are intendedly deconstructed in the process.assignPassengersToSeats: function(passengers, seats) {    // check if there are enough seats    if (passengers.length > seats.length)        throw "Not enough free seats left!";            var passenger;    // assign seats to passengers in correct passenger order    while (passengers.length > 0) {        passenger = passengers.shift();        passenger.jumpToSeat(seats.shift());    };    // clear remaining seats    while (seats.length > 0) {        seats.pop();    };},// And the actual calls i.e. within the create functioncreate: function() {    // create and initialize passengers and seats    // ...    // find all free seats and idle passengers    var seats = this.findMatchesInGroup('occupied', false, this.seats),        passengers = this.findMatchesInGroup('idle', true, this.passengers);    // shuffle seats    seats = Phaser.Utils.shuffle(seats);    // assign passengers to shuffled seats    this.assignPassengersToSeats(passengers, seats);}

Thanks for the help and pointers!

 

 

Link to comment
Share on other sites

Groups use a linked list, not an array, so sadly there's no quick way to just clone and modify it (they do have an array as well, but it's the LL that controls the order of things in there). This is purely because of the way Pixi works, I needed to duplicate that inside of the Group to maintain display list order.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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