矩形在as3视觉编程中的几个应用方式

  矩形在视觉编程中应用甚广,下面描述其中的几种在as3中的应用方式。

  本文所用的速度用矢量表示,都是Vector_2D类的实例。
  这个2D的矢量类见 http://www.cnblogs.com/vilyLei/articles/1567703.html

1.一个物体被限制在矩形框内运动,碰到边界就反弹.此处用矩形物体来做示例,此示例代码直接复制即可用作测试。

as3代码如下:

  

代码
package
{
    
/**
      * Copyright (C) 2008-2012 Vily
     *
     * @class name(类名):    Main
     *
     * @author(创建人): Vily
     *
     * @version(版本): v1.1
     *
     * @create date(创建日期): 2009-12-13
     *
     * @purpose(对此类实现的功能的描述):Main文档类
     *
     * @public properties(公开的属性): None. Static constants only.
     * @public methods(公开的方法):
     *             Main( ) - Constructor. 
     *
     
*/
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Rectangle;
    
    
public class Main extends Sprite{
        
//作为矩形区域的矩形块
        private var _areaRectSpr:RectSpr = null;
        
//作为运动的矩形块
        private var _currSpr:RectSpr = null;
        
//记录物体运动当前速度的矢量
        private var _currV:Vector_2D = new Vector_2D();
        
private var _areaRect:Rectangle = null;
        
public function Main(){
            init();
        }
        
/**
         *    系统程序初始化入口
         
*/
        
private function init():void{
            
            initDispObj();
            initListener();
        }        
        
/**
         *    初始化显示对象
         
*/
        
private function initDispObj():void{
            
            
//矩形区域
            _areaRect = new Rectangle(50,50,450,300);
            _areaRectSpr 
= new RectSpr();
            addChild(_areaRectSpr);
            _areaRectSpr.x 
= _areaRect.x;
            _areaRectSpr.y 
= _areaRect.y;
            _areaRectSpr.drawBg(_areaRect.width,_areaRect.height);
            
            
//运动的矩形可是对象
            _currSpr = new RectSpr();
            _currSpr.drawBg(
30,30,0xff0000);
            _currSpr.x 
= 200;
            _currSpr.y 
= 200;
            addChild(_currSpr);
            
            _currV.x 
= Math.round(Math.random() * 4);
            _currV.y 
= Math.round(Math.random() * 4);
        }
        
/**
         *    初始化侦听器
         
*/
        
private function initListener():void{
            
this.addEventListener(Event.ENTER_FRAME,enterTest);
        }
        
private function enterTest(evt:Event):void{
            
            
//检测运动的_currSpr是否碰到矩形的左右边界
            var px:Number = 0;
            
if(_currV.x > 0){
                px 
= _currSpr.x + _currV.x;
                
if(px > (_areaRect.x + _areaRect.width - _currSpr.width)){
                    px 
= _areaRect.x + _areaRect.width - _currSpr.width;
                    _currV.x 
= -_currV.x;
                }
            }
else{
                px 
= _currSpr.x + _currV.x;
                
if(px < _areaRect.x){
                    px 
= _areaRect.x;
                    _currV.x 
= -_currV.x;
                }
            }
            
            
//检测运动的_currSpr是否碰到矩形的上下边界
            var py:Number = 0;
            
if(_currV.y > 0){
                py 
= _currSpr.y + _currV.y;
                
if(py > (_areaRect.y + _areaRect.height - _currSpr.height)){
                    py 
= _areaRect.y + _areaRect.height - _currSpr.height;
                    _currV.y 
= -_currV.y;
                }
            }
else{
                py 
= _currSpr.y + _currV.y;
                
if(py < _areaRect.y){
                    py 
= _areaRect.y;
                    _currV.y 
= -_currV.y;
                }
            }
            _currSpr.x 
= px;
            _currSpr.y 
= py;
        }
    }
}

import flash.display.Sprite;
class RectSpr extends Sprite{
    
public function RectSpr(){}
    
public function drawBg(w:Number,h:Number,color:uint = 0x0):void{
        
this.graphics.beginFill(color);
        
this.graphics.drawRect(0,0,w,h);
        
this.graphics.endFill();
    }
}

 

2.检测是否碰撞到矩形,如果碰到障碍物就反弹(A)

  本示例 以运动的矩形物体的中心点为检测条件。也就相当于判定一个点是否和一个矩形相碰撞。

  而碰撞后反弹时的速度矢量则使用逆向算法计算的到.

  as3代码如下:

代码
package
{
    
/**
      * Copyright (C) 2008-2012 Vily
     *
     * @class name(类名):    Main
     *
     * @author(创建人): Vily
     *
     * @version(版本): v1.1
     *
     * @create date(创建日期): 2009-12-13
     *
     * @purpose(对此类实现的功能的描述):Main文档类
     *
     * @public properties(公开的属性): None. Static constants only.
     * @public methods(公开的方法):
     *             Main( ) - Constructor. 
     *
     
*/
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Rectangle;
    
    
public class Main extends Sprite{
        
//作为矩形区域的矩形块
        private var _areaRectSpr:RectSpr = null;
        
//作为运动的矩形块
        private var _currSpr:RectSpr = null;
        
//记录物体运动当前速度的矢量
        private var _currV:Vector_2D = new Vector_2D();
        
//限制小矩形块运动的矩形区域
        private var _areaRect:Rectangle = null;        
        
        
//临时矢量
        private var _tempV:Vector_2D = new Vector_2D();
        
//矩形障碍物所占的矩形
        private var _blockRect:Rectangle = null;
        
//作为矩形障碍物的RectSpr实例
        private var _blockSpr:RectSpr = null;
        
public function Main(){
            init();
        }
        
/**
         *    系统程序初始化入口
         
*/
        
private function init():void{
            
            initDispObj();
            initListener();
        }        
        
/**
         *    初始化显示对象
         
*/
        
private function initDispObj():void{
            
            
//矩形区域
            _areaRect = new Rectangle(50,50,450,300);
            _areaRectSpr 
= new RectSpr();
            addChild(_areaRectSpr);
            _areaRectSpr.x 
= _areaRect.x;
            _areaRectSpr.y 
= _areaRect.y;
            _areaRectSpr.drawBg(_areaRect.width,_areaRect.height);
            
            
            
//矩形障碍物
            _blockRect = new Rectangle(240,120,80,150);
            _blockSpr 
= new RectSpr();
            addChild(_blockSpr);
            _blockSpr.x 
= _blockRect.x;
            _blockSpr.y 
= _blockRect.y;
            _blockSpr.drawBg(_blockRect.width,_blockRect.height,
0x008800);
            
            
//运动的矩形可是对象
            _currSpr = new RectSpr();
            _currSpr.drawBg(
30,30,0xff0000);
            _currSpr.x 
= 81;
            _currSpr.y 
= 81;
            addChild(_currSpr);
            
            _currV.x 
= Math.round(Math.random() * 4);
            _currV.y 
= Math.round(Math.random() * 4);
        }
        
/**
         *    初始化侦听器
         
*/
        
private function initListener():void{
            
this.addEventListener(Event.ENTER_FRAME,enterTest);
        }
        
//计算碰到矩形边界后的速度矢量
        protected function calcHitRectBoundsV(posV:Vector_2D,speed_v:Vector_2D,rect:Rectangle):Boolean{
            var px:Number 
= posV.x + speed_v.x;
            
if(px <= rect.x || px >= (rect.x + rect.width)){
                
//碰到左边界
                speed_v.x = -speed_v.x;
                
return true;
            }
            var py:Number 
= posV.y + speed_v.y;
            
if(py <= rect.y || py >= (rect.y + rect.height)){
                    
//碰到左边界
                    speed_v.y = -speed_v.y;
                    
return true;                
            }
            
return false;
        }
        
private function enterTest(evt:Event):void{
            
            var py:Number 
= 0;
            var px:Number 
= 0;
            
//检测是否碰到障碍物
            
//计算_currSpr下一步运动后的中心点坐标
            _tempV.x = _currSpr.x + _currSpr.width/2 + _currV.x;
            _tempV.y 
= _currSpr.y + _currSpr.height/2 + _currV.y;
            
//先判断小矩形块的中心点是否和矩形障碍物相碰
            if(_blockRect.contains(_tempV.x,_tempV.y)){
                
                
//这里采用逆向算法来计算碰撞后的速度矢量
                _currV.x = -_currV.x;
                _currV.y 
= -_currV.y;
                var boo:Boolean 
= calcHitRectBoundsV(_tempV,_currV,_blockRect);
                _currV.x 
= -_currV.x;
                _currV.y 
= -_currV.y;
                
                
//如果已经碰撞,那就要反弹.
                if(boo){
                    
return;
                }
            }
            
            
//检测运动的_currSpr是否碰到矩形的左右边界            
            if(_currV.x > 0){
                px 
= _currSpr.x + _currV.x;
                
if(px > (_areaRect.x + _areaRect.width - _currSpr.width)){
                    px 
= _areaRect.x + _areaRect.width - _currSpr.width;
                    _currV.x 
= -_currV.x;
                }
            }
else{
                px 
= _currSpr.x + _currV.x;
                
if(px < _areaRect.x){
                    px 
= _areaRect.x;
                    _currV.x 
= -_currV.x;
                }
            }
            
            
//检测运动的_currSpr是否碰到矩形的上下边界            
            if(_currV.y > 0){
                py 
= _currSpr.y + _currV.y;
                
if(py > (_areaRect.y + _areaRect.height - _currSpr.height)){
                    py 
= _areaRect.y + _areaRect.height - _currSpr.height;
                    _currV.y 
= -_currV.y;
                }
            }
else{
                py 
= _currSpr.y + _currV.y;
                
if(py < _areaRect.y){
                    py 
= _areaRect.y;
                    _currV.y 
= -_currV.y;
                }
            }            
            _currSpr.x 
= px;
            _currSpr.y 
= py;
        }
    }
    
    
}

import flash.display.Sprite;
class RectSpr extends Sprite{
    
public function RectSpr(){}
    
public function drawBg(w:Number,h:Number,color:uint = 0x0):void{
        
this.graphics.beginFill(color);
        
this.graphics.drawRect(0,0,w,h);
        
this.graphics.endFill();
    }
}

 

 

3.检测是否碰撞到矩形,如果碰到障碍物就反弹(B)

  本示例 以运动的矩形物体所占据的矩形区域为检测条件。也就相当于判定两个矩形相的碰撞。

  而碰撞后反弹时的速度矢量则使用矩形重叠算法计算的到.

 

代码
package
{
    
/**
      * Copyright (C) 2008-2012 Vily
     *
     * @class name(类名):    Main
     *
     * @author(创建人): Vily
     *
     * @version(版本): v1.1
     *
     * @create date(创建日期): 2009-12-13
     *
     * @purpose(对此类实现的功能的描述):Main文档类
     *
     * @public properties(公开的属性): None. Static constants only.
     * @public methods(公开的方法):
     *             Main( ) - Constructor. 
     *
     
*/
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Rectangle;
    
    
public class Main extends Sprite{
        
//作为矩形区域的矩形块
        private var _areaRectSpr:RectSpr = null;
        
//作为运动的矩形块
        private var _currSpr:RectSpr = null;
        
//记录物体运动当前速度的矢量
        private var _currV:Vector_2D = new Vector_2D();
        
//限制小矩形块运动的矩形区域
        private var _areaRect:Rectangle = null;        
        
        
//临时矢量
        private var _tempV:Vector_2D = new Vector_2D();
        
//临时矩形变量
        private var _tempRect:Rectangle = new Rectangle();
        
private var _interRect:Rectangle = null;
        
        
//矩形障碍物所占的矩形
        private var _blockRect:Rectangle = null;
        
//作为矩形障碍物的RectSpr实例
        private var _blockSpr:RectSpr = null;
        
public function Main(){
            init();
        }
        
/**
         *    系统程序初始化入口
         
*/
        
private function init():void{
            
            initDispObj();
            initListener();
        }        
        
/**
         *    初始化显示对象
         
*/
        
private function initDispObj():void{
            
            
//矩形区域
            _areaRect = new Rectangle(50,50,450,300);
            _areaRectSpr 
= new RectSpr();
            addChild(_areaRectSpr);
            _areaRectSpr.x 
= _areaRect.x;
            _areaRectSpr.y 
= _areaRect.y;
            _areaRectSpr.drawBg(_areaRect.width,_areaRect.height);
            
            
            
//矩形障碍物
            _blockRect = new Rectangle(240,120,80,150);
            _blockSpr 
= new RectSpr();
            addChild(_blockSpr);
            _blockSpr.x 
= _blockRect.x;
            _blockSpr.y 
= _blockRect.y;
            _blockSpr.drawBg(_blockRect.width,_blockRect.height,
0x008800);
            
            
//运动的矩形可是对象
            _currSpr = new RectSpr();
            _currSpr.drawBg(
30,30,0xff0000);
            _currSpr.x 
= 81;
            _currSpr.y 
= 81;
            addChild(_currSpr);
            
            _currV.x 
= Math.round(Math.random() * 4);
            _currV.y 
= Math.round(Math.random() * 4);
            _tempRect.width 
= _currSpr.width;
            _tempRect.height 
= _currSpr.height;
        }
        
/**
         *    初始化侦听器
         
*/
        
private function initListener():void{
            
this.addEventListener(Event.ENTER_FRAME,enterTest);
        }        
        
private function enterTest(evt:Event):void{
            
            var py:Number 
= 0;
            var px:Number 
= 0;
            
            
//计算_currSpr下一步运动后的矩形数据
            _tempRect.x = _currSpr.x + _currV.x;
            _tempRect.y 
= _currSpr.y + _currV.y;
            
//判断小矩形块是否和矩形障碍物相碰,如果相碰就反弹
            _interRect = _tempRect.intersection(_blockRect);
            
if(_interRect.width>0 || _interRect.height>0 ){
                
if(_interRect.width < _interRect.height){
                        _currV.x 
= -_currV.x;
                }
else{
                    _currV.y 
= -_currV.y;
                }
                
return;
            }
            
            
//检测运动的_currSpr是否碰到矩形的左右边界
            if(_currV.x > 0){
                px 
= _currSpr.x + _currV.x;
                
if(px > (_areaRect.x + _areaRect.width - _currSpr.width)){
                    px 
= _areaRect.x + _areaRect.width - _currSpr.width;
                    _currV.x 
= -_currV.x;
                }
            }
else{
                px 
= _currSpr.x + _currV.x;
                
if(px < _areaRect.x){
                    px 
= _areaRect.x;
                    _currV.x 
= -_currV.x;
                }
            }
            
            
//检测运动的_currSpr是否碰到矩形的上下边界            
            if(_currV.y > 0){
                py 
= _currSpr.y + _currV.y;
                
if(py > (_areaRect.y + _areaRect.height - _currSpr.height)){
                    py 
= _areaRect.y + _areaRect.height - _currSpr.height;
                    _currV.y 
= -_currV.y;
                }
            }
else{
                py 
= _currSpr.y + _currV.y;
                
if(py < _areaRect.y){
                    py 
= _areaRect.y;
                    _currV.y 
= -_currV.y;
                }
            }            
            _currSpr.x 
= px;
            _currSpr.y 
= py;
        }
    }
    
    
}

import flash.display.Sprite;
class RectSpr extends Sprite{
    
public function RectSpr(){}
    
public function drawBg(w:Number,h:Number,color:uint = 0x0):void{
        
this.graphics.beginFill(color);
        
this.graphics.drawRect(0,0,w,h);
        
this.graphics.endFill();
    }
}

  

注意,在实际的应用中可能需要第二点和第三点结合使用。否则可能有偏差。

以上描述如果有问题,请您留言提示我,在此先谢谢了。

 

posted @ 2009-12-14 11:21  vily_雷  阅读(467)  评论(0编辑  收藏  举报