Flex高级动画教程中所讲的寻找行为

----向量类

package vector.steering 

{

    import flash.display.Graphics;

   

    /**

     * ...

     * @author DefaultUser (Tools -> Custom Arguments...)

     */

    public class Vector2D

    {

        private var _x:Number;

        private var _y:Number;

       

        public function Vector2D(x:Number=0,y:Number=0)

        {

            _x = x;

            _y = y;

        }

       

        public function draw(graphics:Graphics, color:uint=0):void {

            graphics.lineStyle(0, color);

            graphics.moveTo(0, 0);

            graphics.lineTo(_x, _y);

        }

        /**

         * 返回自己的克隆向量

         * @return Vector2D

         */

        public function clone():Vector2D {

            return new Vector2D(_x, _y);

        }

        /**

         * 返回 Vector2D (0,0)

         * @return Vector2D

         */

        public function zero():Vector2D {

            _x = 0;

            _y = 0;

            return this;

        }

        /**

         * 返回是否为零向量

         * @return Boolean

         */

        public function iszero():Boolean {

            return _x == 0 && _y == 0;

        }

        public function set length(value:Number):void {

            var a:Number = angle;

            _x = Math.cos(a) * value;

            _y = Math.sin(a) * value;

        }

        /**

         * 返回向量的长度

         */

        public function get length():Number {

            return Math.sqrt(lengthSQ);

        }

        public function get lengthSQ():Number {

            return _x * _x + _y * _y;

        }

        public function set angle(value:Number):void {

            var len:Number = value;

            _x = Math.cos(value) * len;

            _y = Math.sin(value) * len;

        }

        public function get angle():Number {

            return Math.atan2(_y, _x);

        }

        /**

         * 返回垂直向量

         */

        public function get perp():Vector2D {

            return new Vector2D( -y, x);

        }

        public function set x(value:Number):void {

            _x = value;

        }

        public function get x():Number {

            return _x;

        }

        public function set y(value:Number):void {

            _y = value;

        }

        public function get y():Number {

            return _y;

        }

        /**

         * 向量单位化

         * @return Vector2D

         */

        public function normalize():Vector2D {

            if (length == 0) {

                _x = 1;

                return this;

            }

            var len:Number = length;

            _x /= len;

            _y /= len;

           

            return this;

        }

        public function scale(value:uint):Vector2D {

           

            return new Vector2D(_x * value, _y * value);

        }

        /**

         * 限制向量的最大长度

         * @param   max

         * @return Vector2D

         */

        public function truncate(max:Number):Vector2D {

            length = Math.min(max, length);

            return this;

        }

        /**

         * 向量反转

         * @return Vector2D

         */

        public function reverse():Vector2D {

            _x = -_x;

            _y = -_y;

           

            return this;

        }

        /**

         * 返回是否为单位向量

         * @return Boolean

         */

        public function isNormalized():Boolean {

            return length == 1.0;

        }

        public function dotProd(v2:Vector2D):Number {

            return _x * v2.x + _y * v2.y;

        }

        public function crossProd(v2:Vector2D):Number {

            return _x * v2.y - _y * v2.x;

        }

        /**

         * 返回两个向量的角度

         * @param   v1

         * @param   v2

         * @return Number

         */

        public function angleBetween(v1:Vector2D, v2:Vector2D):Number {

            if (!v1.isNormalized()) v1 = v1.clone().normalize();

            if (!v2.isNormalized()) v2 = v2.clone().normalize();

            return Math.acos(v1.dotProd(v2));

        }

        /**

         *

         * @param   v2

         * @return Vector2D

         */

        public function sign(v2:Vector2D):int {

            return perp.dotProd(v2) < 0? -1:1;

        }

        /**

         * 返回两个Vector2D之间的距离

         * @param   v2

         * @return Number

         */

        public function dist(v2:Vector2D):Number {

            return Math.sqrt(distSQ(v2));

        }

        /**

         * 返回向量的平方值

         * @param   v2

         * @return Number

         */

        public function distSQ(v2:Vector2D):Number {

            var dx:Number = v2.x - x;

            var dy:Number = v2.y - y;

            return dx * dx + dy * dy;

        }

        /**

         * 加上向量v2

         * @param   v2

         * @return Vector2D

         */

        public function add(v2:Vector2D):Vector2D {

            return new Vector2D(_x + v2.x, _y + v2.y);

        }

        /**

         * 减去向量v2

         * @param   v2

         * @return Vector2D

         */

        public function substract(v2:Vector2D):Vector2D {

            return new Vector2D(_x - v2.x, _y - v2.y);

        }

        /**

         * 乘以向量value

         * @param   value

         * @return Vector2D

         */

        public function multiply(value:Number):Vector2D {

            return new Vector2D(_x * value, _y * value);

        }

        /**

         * 除以向量value

         * @param   value

         * @return Vector2D

         */

        public function divide(value:Number):Vector2D {

            return new Vector2D(_x/value,_y/value);

        }

        /**

         * 判断两个向量是否相同

         * @param   v2

         * @return

         */

        public function equals(v2:Vector2D):Boolean {

            return _x == v2.x && _y == v2.y;

        }

        public function toString():String {

            return "[Vector2D(x:" + _x + ",y:" + _y + ")]";

        }

    }

}

 

----vehicle基类

package vector.steering

{

    import flash.display.Sprite;

   

    public class Vehicle extends Sprite

    {

        protected var _edgeBehavior:String = WRAP;

        protected var _mass:Number = 1.0; //质量

        protected var _maxSpeed:Number = 10;

        protected var _position:Vector2D; //位置向量

        protected var _velocity:Vector2D; //速度向量

       

        public static const WRAP:String = "wrap";

        public static const BOUNCE:String = "boounce";

       

        public function Vehicle(){

            _position = new Vector2D();

            _velocity = new Vector2D();

            draw();

        }

       

        protected function draw():void{

            graphics.clear();

            graphics.lineStyle(0);

            graphics.moveTo(10, 0);

            graphics.lineTo(-10, 5);

            graphics.lineTo(-10, -5);

            graphics.lineTo(10, 0);

        }

       

        public function update():void{

            _velocity.truncate(_maxSpeed);  //限制最大速度

            _position = _position.add(_velocity);   //添加速度向量

           

            if(_edgeBehavior == WRAP){

                wrap();

            }else if(_edgeBehavior == BOUNCE){

                bounce();

            }

           

            //更新机车类坐标

            x = position.x;

            y = position.y;

           

            //更新转向速度

            rotation = _velocity.angle * 180/Math.PI;

        }

       

        /**

         * 碰到墙壁,反弹

         * 直接更改相反方向的向量坐标

         */

        public function bounce():void{

            if(stage != null){

                if(position.x > stage.stageWidth){

                    position.x = stage.stageWidth;

                    velocity.x *= -1;

                }else if(position.x < 0){

                    position.x = 0;

                    velocity.x *= -1;

                }

               

                if(position.y > stage.stageHeight){

                    position.y = stage.stageHeight;        

                    velocity.y *= -1;

                } else if(position.y < 0) {

                    position.y = 0;

                    velocity.y *= -1;

                }

            }

        }

       

        public function wrap():void{

            if(stage != null){

                if(position.x > stage.stageWidth) position.x = 0;

                if(position.x < 0) position.x = stage.stageWidth;

                if(position.y > stage.stageHeight) position.y = 0;

                if(position.y < 0) position.y = stage.stageHeight;

            }

        }

       

       

        public function set edgeBehavior(value:String):void{

            _edgeBehavior = value;

        }

       

        public function get edgeBehavior():String{

            return _edgeBehavior;

        }

       

        public function set mass(value:Number):void{

            _mass = value;

        }

       

        public function get mass():Number{

            return _mass;

        }

       

        public function set maxSpeed(value:Number):void{

            _maxSpeed = value;

        }

       

        public function get maxSpeed():Number{

            return _maxSpeed;

        }

       

        public function set position(value:Vector2D):void{

            _position = value;

            x = _position.x;

            y = _position.y;

        }

       

        public function get position():Vector2D{

            return _position;

        }

       

        public function set velocity(value:Vector2D):void{

            _velocity = value;

        }

       

        public function get velocity():Vector2D{

            return _velocity;

        }

       

        override public function set x(value:Number):void{

            super.x = value;

            _position.x = x;

        }

       

        override public function set y(value:Number):void{

            super.y = value;

            _position.y = y;

        }

    }

}

 

----SteeredVehicle机车子类

package vector.steering

{

    public class SteeredVehicle extends Vehicle

    {

        private var _maxForce:Number = 1;      //旋转力

        private var _steeringForce:Vector2D; //作为叠加后的转向合力

       

        public function SteeredVehicle()

        {

            _steeringForce = new Vector2D();

            super();

        }

       

        public function set maxForce(value:Number):void{

            _maxForce = value;

        }

       

        public function get maxForce():Number{

            return _maxForce;

        }

        /**

         * 主要控制旋转力

         */

        override public function update():void{

            _steeringForce.truncate(_maxForce);

            _steeringForce = _steeringForce.divide(_mass);

            _velocity = _velocity.add(_steeringForce);

            _steeringForce = new Vector2D();

            super.update();

        }

       

        /**

         * 寻找行为 把机车移动到指定点

         */

        public function seek(target:Vector2D):void{

            var desiredVelocity:Vector2D = target.substract(_position);

            desiredVelocity.normalize();

            desiredVelocity = desiredVelocity.multiply(_maxSpeed);

            var force:Vector2D = desiredVelocity.substract(_velocity);

            _steeringForce = _steeringForce.add(force);

           

        }

    }

}

 

---测试类

package vector.chapter1

{

    import flash.display.Sprite;

    import flash.display.StageAlign;

    import flash.display.StageScaleMode;

    import flash.events.Event;

   

    import vector.steering.SteeredVehicle;

    import vector.steering.Vector2D;

   

    public class SeekTest extends Sprite

    {

        private var _vehicle:SteeredVehicle;

       

        public function SeekTest()

        {

            stage.align = StageAlign.TOP_LEFT;

            stage.scaleMode = StageScaleMode.NO_SCALE;

           

            _vehicle = new SteeredVehicle();

            addChild(_vehicle);

           

            addEventListener(Event.ENTER_FRAME, onEnterFrame);

        }

       

        private function onEnterFrame(event:Event):void{

            _vehicle.seek(new Vector2D(mouseX, mouseY));

            _vehicle.update();

        }

    }

}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值