topical media & game development

talk show tell print

#graphic-player-10-cube-be-nascom-flash-util-DisplayObjectsIntoUnitGridUtil.ax

#graphic-player-10-cube-be-nascom-flash-util-DisplayObjectsIntoUnitGridUtil.ax [swf] [flash] flex


  package be.nascom.flash.util{
          
          import flash.display.DisplayObject;
          import flash.events.EventDispatcher;
          import flash.events.IEventDispatcher;
          import flash.geom.Rectangle;
  
          public class @ax-graphic-player-10-cube-be-nascom-flash-util-DisplayObjectsIntoUnitGridUtil extends EventDispatcher{
                  
                  private var _min_rect:Rectangle;
                  private var _max_rect:Rectangle;
                  
                  private var _target_rectangle:Rectangle;
                  private var _unit_grid:UnitGrid;
                  
                  public function get display_objects():Array{
                          return _display_objects.slice();
                  }
                  private var _display_objects:Array;
                  
                  public function get placed_display_objects():Array{
                          return _placed_display_objects.slice();
                  }
                  private var _placed_display_objects:Array;
                  
                  private var _seed_stack:Array;//list of rectangles, added to stage, which have not yet been used as "seeds" for positioning rectangles.
                  
                  public function @ax-graphic-player-10-cube-be-nascom-flash-util-DisplayObjectsIntoUnitGridUtil(target:IEventDispatcher=null){
                          super(target);
                  }
                  
                  public function init(display_objects:Array,unit_grid:UnitGrid,delay:uint=0):void{
                          _display_objects=display_objects;
                          _placed_display_objects=new Array();
                          updateMaxAndMinRectangles();
                          _unit_grid=unit_grid;
                  }
                  
                  
                  protected function updateMaxAndMinRectangles():void{
                          var s:DisplayObject=DisplayObject(_display_objects[0]);
                          var biggest:uint=Math.max(s.width,s.height);
                          _min_rect=new Rectangle(0,0,biggest,biggest);
                          _max_rect=_min_rect.clone();
                          for each(s in _display_objects){
                                  biggest=Math.max(s.width,s.height);
                                  if(biggest>_max_rect.width)_max_rect=new Rectangle(0,0,biggest,biggest);
                                  if(biggest<_min_rect.width)_min_rect=new Rectangle(0,0,biggest,biggest);
                          }
                          /*
                          trace("updateMaxAndMinRectangles()");
                          trace("\tmin_rect:"+_min_rect);
                          trace("\tmax_rect:"+_max_rect);
  			*/
                  }
                  
                  private function extractDisplayObjectByIndex(index:uint):DisplayObject{
                          return DisplayObject(_display_objects.splice(index,1)[0]);
                  }
  
                  private function getRandomDisplayObject():DisplayObject{
                          var index:uint=Math.floor(Math.random()*_display_objects.length);
                          return extractDisplayObjectByIndex(index);
                  }
                  
                  private function getRectFromDisplayObject(_do:DisplayObject):Rectangle{
                          return new Rectangle(_do.x,_do.y,_do.width,_do.height);
                  }
  
                  private function placeFirstDisplayObject():DisplayObject{
                          var center_index:uint=_unit_grid.getCenterCellIndex();
                          //trace("placeFirstRectangle()1 center_index:"+center_index);
                          var display_object:DisplayObject=getRandomDisplayObject();
                          //trace("placeFirstRectangle()2 getCellX:"+_unit_grid.getCellXByIndex(center_index));
                          //trace("placeFirstRectangle()3 getCellY:"+_unit_grid.getCellYByIndex(center_index));
                          //trace("placeFirstRectangle()4 rect:"+getRectFromDisplayObject(display_object));
                          display_object.x=Math.floor(_unit_grid.getCellXByIndex(center_index)-display_object.width/2);
                          display_object.y=Math.floor(_unit_grid.getCellYByIndex(center_index)-display_object.height/2);
                          //trace("placeFirstRectangle()5 rect:"+getRectFromDisplayObject(display_object));
                          _unit_grid.disableCellsUnderRect(getRectFromDisplayObject(display_object));
                          //return DisplayObject(addChild(rect));
                          return display_object;
                  }
  
                  public function placeDisplayObjectsIntoUnitGridRandom():void{
                          //var rect:DisplayObject;
                          _seed_stack=new Array();
                          _seed_stack.push(placeFirstDisplayObject());
                          updateMaxAndMinRectangles();
                          var max_iterations:uint=200;
                          var cur_iteration:uint=0;
                          while(_display_objects.length && _seed_stack.length){
                                  populateFromSeed(DisplayObject(_seed_stack.shift()));
                                  if(++cur_iteration>max_iterations)break;
                                  //trace("fitRectangles() Looping : "+cur_iteration+", _display_objects:"+_display_objects.length+",_seed_stack.length:"+_seed_stack.length);
                          }
                  }
  
                  private var _place_rect_functions:Array=new Array(placeDisplayObjectToTheRight,placeDisplayObjectBelow,placeDisplayObjectToTheLeft,placeDisplayObjectAbove);
                  private function populateFromSeed(rect:DisplayObject):void{
                          //var source_bounds:Rectangle=rect.getBounds(stage);
                          var source_bounds:Rectangle=new Rectangle(rect.x,rect.y,rect.width,rect.height);
                          //trace(source_bounds);
                          //trace("populateFromSeed() : source_bounds:"+source_bounds);
  
                          var indeces:Array=new Array(0,1,2,3);
                          var order:Array=new Array();
                          while(indeces.length){
                                  order.push(indeces.splice(Math.floor(Math.random()*indeces.length),1));
                          }
                          for(var i:uint=0;i<4;i++){
                                  _place_rect_functions[order[i]](source_bounds);
                          }
                          /*
                          placeDisplayObjectToTheRight(source_bounds);
                          
                          placeDisplayObjectBelow(source_bounds);
                          placeDisplayObjectToTheLeft(source_bounds);
                          placeDisplayObjectAbove(source_bounds);
  			*/
                  }
                  
                  private function placeAvailableDisplayObjectIntoRectangle(source_rect:Rectangle,unit_grid_rect:Rectangle):void{
                          if(source_rect==null || unit_grid_rect==null)return;
                          if(unit_grid_rect.width>=_min_rect.width){
                                  var available:DisplayObject=findDisplayObjectWhichFitsIn(unit_grid_rect);
                                  if(available==null){
                                          trace("placeAvailableDisplayObjectIntoRectangle() No available rectangle found");
                                          return;
                                  }
                                  available.x=unit_grid_rect.x+unit_grid_rect.width/2-available.width/2;
                                  available.y=unit_grid_rect.y+unit_grid_rect.height/2-available.height/2;
                                  _unit_grid.disableCellsUnderRect(new Rectangle(available.x,available.y,available.width,available.height));
                                  _seed_stack.push(available);
                                  //addChild(available);
                                  _placed_display_objects.push(removeDisplayObject(available));
                                  updateMaxAndMinRectangles();
                          }                
                  }
                  
                  private function placeDisplayObjectToTheRight(source_bounds:Rectangle):void{
                          //trace("placeDisplayObjectToTheRight()");
                          var found:Rectangle=_unit_grid.findRectangleToTheRight(source_bounds,_min_rect,_max_rect);
                          //trace("placeDisplayObjectToTheRight() found : "+found);
                          if(found!=null)placeAvailableDisplayObjectIntoRectangle(source_bounds,found);
                  }
  
                  private function placeDisplayObjectBelow(source_bounds:Rectangle):void{
                          //trace("placeDisplayObjectBelow()");
                          var found:Rectangle=_unit_grid.findRectangleBelow(source_bounds,_min_rect,_max_rect);
                          //trace("placeDisplayObjectBelow() found : "+found);
                          if(found!=null)placeAvailableDisplayObjectIntoRectangle(source_bounds,found);
                  }
  
                  private function placeDisplayObjectToTheLeft(source_bounds:Rectangle):void{
                          //trace("placeDisplayObjectToTheLeft()");
                          var found:Rectangle=_unit_grid.findRectangleToTheLeft(source_bounds,_min_rect,_max_rect);
                          //trace("placeDisplayObjectToTheLeft() found : "+found);
                          if(found!=null)placeAvailableDisplayObjectIntoRectangle(source_bounds,found);
                  }
  
                  private function placeDisplayObjectAbove(source_bounds:Rectangle):void{
                          //trace("placeDisplayObjectAbove()");
                          var found:Rectangle=_unit_grid.findRectangleAbove(source_bounds,_min_rect,_max_rect);
                          //trace("placeDisplayObjectToTheAbove() found : "+found);
                          if(found!=null)placeAvailableDisplayObjectIntoRectangle(source_bounds,found);
                  }
  
                  private function findDisplayObjectWhichFitsIn(rect:Rectangle):DisplayObject{
                          var candidate:DisplayObject;
                          var max_side:uint;
                          if(rect.width<this._min_rect.width){
                                  trace("findRectangleWhichFitsIn() rect is smaller than _min_rect ");
                                  return null;
                          }
                          for each(var s:DisplayObject in this._display_objects){
                                  max_side=Math.max(s.width,s.height);
                                  if(max_side<rect.width){
                                          if(candidate==null){
                                                  candidate=s;
                                          }else if(max_side>Math.max(candidate.width,candidate.height)){
                                                  candidate=s;
                                          }
                                  }
                          }
                          return candidate;
                  }
                  
                  //meh... maybe _display_objects should be passed as argument...
                  private function removeDisplayObject(_disp_obj:DisplayObject):DisplayObject{
                          for(var i:uint=0;i<_display_objects.length;i++){
                                  if(_display_objects[i]==_disp_obj){
                                          return _display_objects.splice(i,1)[0];
                                  }
                          }
                          trace("removeRectangle, no match found. rect:"+_disp_obj);
                          return null;
                  }
                  
          }
  }


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.