topical media & game development
#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.