AS3四叉树

在一些游戏中,当地图上有很多元素时,或者有一张很大的地图需要渲染。通常的做法是遍历所有的显示对象,但是这样做,可能会占用大量的CPU,所以为了处理这种情况。我们可以使用四叉树,这里的四叉树,就是把场景划分为四等分,然后每一小份再分成四等分,这下分下去,通常情况分四五次就行了。具体分几层,可以在实践中去测试,以获得最高的效率。
下面是四叉树中的公开的类,其实很简单,就是先建树,然后往里面添加对象,移除对象,清空所有的对象。最重要的就是搜索显示对象。

/** 
* 构造函数 
* @param 四叉树的层数 
* @param 整个地图的长和度 
*/
public function QuadTree( layerNum:int , maxRect:Rectangle ) 
  
//添加一个显示对象 
public function insertObj( obj:DisplayObject ):void
  
//删除一个显示对象从四叉树中 
public function deleteObj (obj:DisplayObject):void
  
//清空四叉树中的所有元素 
public function removeAll():void 
  
/** 
 * 查询显示对象 
* @param rect 查询区域 
 * @param exact 是否精确查找 
 * @return 返回查询集合 
*/
public function searchByRect( rect:Rectangle , exact:Boolean ):Vector.<DisplayObject>

下面是测试四叉树,现在场景上有一千个元素,我们可以用鼠标快速地选择你想要的

 

package

    import bing.utils.QuadTree; 
    import flash.display.DisplayObject; 
    import flash.display.Sprite; 
    import flash.events.Event; 
    import flash.events.MouseEvent; 
    import flash.geom.Point; 
    import flash.geom.Rectangle; 
    import flash.utils.getTimer; 
    import test.Model; 
  
    [SWF(backgroundColor="0x000000")] 
    public class QuadTreeTest extends Sprite 
    { 
        private var _modelContainer:Sprite  = new Sprite(); 
        private var _selectContainer:Sprite =new Sprite(); 
        private var _selectModels:Vector.<DisplayObject> ; 
        private var _tree:QuadTree; 
        private var _downLoc:Point  = new Point();; 
  
        public function QuadTreeTest() 
        { 
            addChild(_modelContainer); 
            addChild(_selectContainer); 
  
            if(stage) init(); 
            else addEventListener(Event.ADDED_TO_STAGE , init ); 
        } 
  
        private function init( e:Event = null ):void
        { 
            stage.scaleMode="noScale"; 
            stage.align="TL"; 
            removeEventListener(Event.ADDED_TO_STAGE , init ); 
            stage.addEventListener(MouseEvent.MOUSE_DOWN , onDown ); 
            stage.addEventListener(MouseEvent.MOUSE_MOVE , onMove); 
            stage.addEventListener(MouseEvent.MOUSE_UP , onUp); 
  
            _tree = new QuadTree( 4 , new Rectangle(0,0,1200,750)); 
            var model:Model ; 
            for( var i:int = 0 ; i<40 ; i++) 
            { 
                for(var j:int = 0 ; j<25 ; j++) 
                { 
                    model = new Model(); 
                    model.x = i*model.width + i*10 ; 
                    model.y = j*model.height + j*10 ; 
                    _modelContainer.addChild( model ); 
                    _tree.insertObj( model ); 
                } 
            } 
        } 
  
        private function onDown(e:MouseEvent):void
        { 
            _downLoc.x = mouseX; 
            _downLoc.y = mouseY; 
            //清除最后选择的 
            if(_selectModels) 
            { 
                for each( var obj:DisplayObject in _selectModels) 
                { 
                    obj.alpha =1 ; 
                } 
            } 
        } 
  
        private function onMove(e:MouseEvent):void
        { 
            if(e.buttonDown) 
            { 
                _selectContainer.graphics.clear(); 
                _selectContainer.graphics.beginFill(0x000000,.5); 
                _selectContainer.graphics.lineStyle(1,0xCCCCCC,.5); 
                _selectContainer.graphics.drawRect( _downLoc.x,_downLoc.y,mouseX-_downLoc.x,mouseY-_downLoc.y); 
                _selectContainer.graphics.endFill(); 
            } 
        } 
  
        private function onUp(e:MouseEvent):void
        { 
            var time:int = getTimer(); 
            _selectModels = _tree.searchByRect( new Rectangle( _downLoc.x,_downLoc.y,mouseX-_downLoc.x,mouseY-_downLoc.y ),true); 
            trace( getTimer()-time);  //ms 
            for each( var obj:DisplayObject in _selectModels) 
            { 
                obj.alpha = 0.5 ; 
            } 
            _selectContainer.graphics.clear(); 
        } 
    } 
}


转载http://blog.163.com/fll_0601/blog/static/5499988201171651141898/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值