Categories Displayed in Flash

Archive for the 'array' Category

AS3: Array.filter R0xr!

Array in AS3 has some nifty features that make managing and manipulating active data much easier. Thanks to Brandon Hall's nooks and crannies presentation at LA Flash for getting me to look. Here's an example of using Array.filter

Here's the minimum filter that doesn't do anything. I default the last parameters as often filters are useful outside of iterating over arrays, but the filter method nicely tells the filter where it is via the 'index' and a reference back to the Array.

  1.  
  2.         public class Filter {
  3.                 public function passesFilter(item:*,  index:int= 0, array:Array = null):Boolean{
  4.                         var passes:Boolean = true;
  5.                         return passes;
  6.                 }
  7.         }

Inside com.troyworks.data.filters. I've created a family of filters, in particular RangeFilter that allows inclusive and exclusive of a given range. Here's what a 3-8 filter looks like:


3-8 filter.. 0123456789012345678
* inclusive ---[PASS]----------
noninclusive ---]PASS[----------

The real power of filters is they can be stacked. Here's an example of using a color filter, that looks for color values in the midgray band, but adds an additional filter so that values to close to gray are thrown out.

  1.  
  2. //find values from 0x555555 to 0xBBBBBB non-inclusive on both sides
  3.         var midsFilter:ColorStatisticFilter = new ColorStatisticFilter( ColorUtil.GRAY5, ColorUtil.GRAYB, false, false);
  4.         midsFilter.distanceFromShadeFilter = new NumberRangeBooleanFilter(36, 255);
  5.      // second param needs to be null as this filter is a function closure instead of an anonymous function.
  6.       var midColors:Array = indexedColors.filter(midsFilter.passesFilter,null);

ArrayX and ArrayWeighting

com.troyworks.datastructures has a few useful collection types. One of the more frequently used is ArrayX, a drop in replacement for Array. ArrayX for eXtended. It has common used features in many collection management, media and game applications:

  • swapPlaces
  • shift (relative, absolute, number of positions) - useful for playlist
  • shuffle - useful for cards and playlist
  • remove (obj) - searches through and removes the item
  • getFirstIndexOf(item, fromIdx, toIdx) - similar to String's use
  • getLastIndexOf(item, fromIdx, toIdx) - similar to String's use
  • getFilteredSet (fromIdx, toIdx, thatsNot, thatIsOneOf), this allows simple database querying of the collection, from a start position to an end position. With a filterout and filter in.
  • getFilteredRandom - same as above, of the valid values in the collection return a random
  • snapToClosest - useful for sorted number collections, gets the closest value in the collection.
  • contains(item) -
  • isBefore(itemA, itemB, inRange) - is itemA before itemB within inRange elements
  • isAfter(itemA,itemB, inRange)- is itemA before itemB within inRange elements

Also paired with it is ArrayWeighting , a series of weights is paired with an array, that get's random elements based on the weighting/distribution. Imagine the source array represents group of pipe organ pipes, the element at [0] being one note, [1] being another, behind it is a bellows pushing air infinitely, but no sound is emitted until the valve is opened. A monkey is randomly jumping on the keyboard getting one peep at a time, if he's jumping fast enough there is a random chord, creating this random cacophony. However we can make this haromincally pleasing by weighting the notes. The weighting array is an array the same length of the pipes array, with a value inside of it that can be whatever, but it will get normalized relative to the other. Let's use 0-1 being 0% to 100%

  • wts[0] = 1; //whatever is at pipes[0] will get called 100% of the time.
  • wts[1] = 0; //whatever is at pipes[1] will get called 0% of the time.

Getting a stream of them would be

0,0,0,0,0,0,0, which might represent whistling the same note over and over again.
Setting the weights to

  • 0 = .5
  • 1 = .5

Getting a stream of them might be

0,1,0,1,1,0,0 which might be the jaws theme, or a two note chord depending on how fast they are played back.
The percentage of values gotten will get close to the weighting set. The weighting can be reset, so one can imagine a music game teaching the kid chords, at first one note at a time, then the weights being reset to teach them together, then the next section teaching a new chord, and after a review game, perhaps the valve will be stuck partly open to handle notes the kid is hard at hearing. Cogs is a good approach to managing these score sections.
The contents can be anything from quiz problems, particle, to enemies on a battlefield. The number of elements included can be arbitrary large, representing the game from beginning to end. The random ensures some variance, and replayability. Say we have a 100 different types of enemies that cover a game. The weights can be reset over time, their weights even tweened. The distribution might be

Level1: 1, .5, 0, 0...

Level2: .1, .7, .2, 0...

Level3: .1, .2, .5, .2 ...

Which graphically looks like a ripple moving from left to right, and from the users experience can be a smooth progression of difficulty. But it might not be exact from one replay to the other.

Last night I was able to get it and it's unit test converted to AS3 ( which took some wrangling, thankfully Array can be extended unlike most other types). Coming soon is CollectionManager which adds event management for collection changed, and toXML to present XML views (like used for TreeComponents)