`

(转)ENTER_FRAME实现直线路径移动

阅读更多
package
{

    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.text.TextField;

	public class CharMove extends Sprite
    {
            private var paths:Array
            private var char:InteractiveObject;
            private var text:TextField=new TextField();

			private var t1:TextField = new TextField();
			
            public function CharMove()
            {
				this.stage.align = StageAlign.TOP_LEFT;
                this.stage.scaleMode = StageScaleMode.NO_SCALE;
                setup();
            }
                
            private function setup():void
            {
            	//创建Text
            	text.width = 300;
                text.height = 30;
                text.selectable = false;
                text.mouseEnabled = false;
                this.addChild(text);
				
				t1.x = 100;
				t1.y = 200;
				t1.width = 300;
                t1.height = 30;
                t1.selectable = false;
                t1.mouseEnabled = false;
                t1.text = "测试";
                this.addChild(t1);
				
				
				char = new InteractiveObject();
                char.graphics.beginFill(0xff0000);
                char.graphics.drawCircle(0,0,2);
                char.x = char.y = 100;
                
                this.addChild(char);
                char.addEventListener(Event.COMPLETE,walkEndFunc);
                this.stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownFunc);
                this.stage.addEventListener(Event.ENTER_FRAME,enterFrameFunc);
            }
            
            private function walkEndFunc(e:Event):void
            {
            	text.text='移动结束 !';
            }
            private function mouseDownFunc(e:MouseEvent):void
            {
                this.graphics.clear()
                this.graphics.beginFill(0x00ff00)
                this.graphics.drawCircle(mouseX,mouseY,10)
                var p2:Point = new Point(mouseX,mouseY);
                var p1:Point = new Point(char.x,char.y);
                var len:int = Point.distance(p1,p2) / 10;
                for (var i:int = 0; i <len; i++) 
                {
                    var pt:Point = Point.interpolate(p1 , p2 , i / len);
                    this.graphics.beginFill(0xcacaca)
                    this.graphics.drawCircle(pt.x,pt.y,2)        
                }
                
                char.walk = [p2,new Point(100,200),new Point(300,100)];
                text.text='路径更新 !'
            }
                
            private function enterFrameFunc(e:Event):void
            {
				char.moving()
            }
                
        }
}

package 
{
        
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.utils.getTimer;
        
    /**
     * 可按路径数组进行移动的基础对象 
     */        
    public class InteractiveObject extends Sprite
    {
    
    	/**
         * 路径数组对象 
         */
		private var pathArr:Array
        
        /**
         * 时间 
         */
		private var time:int

		/**
		 * 总时间 
		 */
		private var totalTime:int

		/**
		 * 速度 
		 */
		private var _speed_:int = 50;

		/**
		 * 开始点
		 */		
		private var tar_point:Point;
		        

        /**
         * 构造函数
         */		
        public function InteractiveObject()
        {
        	super();
		}
        
        /**
         * 速度 get set
         */        
        public function get speed():int
        {
        	return _speed_;
		}

		public function set speed(value:int):void
        {
        	_speed_ = value;
		}

		/**
		 * 足迹 
		 * @param path 线段集合
		 * 
		 */		
		public function set walk(path:Array):void
        {
    		this.pathArr = path.slice(); //返回由原始数组中某一范围的元素构成的新数组,而不修改原始数组。
    		
            if ( this.pathArr.length>0 )
            {
            	//获取flash运行毫秒数
                time = getTimer();
                
                //总执行时间
                totalTime = 0;
                tar_point = this.pathArr.shift(); //删除数组中第一个元素,并返回该元素。 始终获取第一个点
            }
        }

        /**
         * 移动函数
         */		
        public function moving():void
        {
//            if(pathArr && pathArr.length >= 0)
//            {
//                    
//                totalTime += ( getTimer() - time );
//                trace(" totalTime " + totalTime);
//                if(totalTime > 0 && tar_point) // 此处totalTime会一直为正数
//                {
//                    move();
//                }
//            }
//            time = getTimer();
        
        	if (this.pathArr && tar_point != null)
        	{
        		// 记录时间
        		
        		//累计每一帧的时间差
        		totalTime += ( getTimer() - time );
        		
        		trace(" totalTime " + totalTime);
        		
        		//移动
        		move();
        		
        		//移动完之后获取当前timer
        		time = getTimer();
        	}
        }

        /**
         * 计算点
         */		
        protected function move():void
        {
			
			//当前点
            var point:Point = new Point(x,y);
            
            //计算从当前位置到目的地所需时间
            var dis:Number = Point.distance(point,tar_point);//返回两点之间的距离
            //S=VT S是距离,V是速度,T是时间。 默认是秒为单位,乘以1000以毫秒为单位。上面getTime以毫秒为单位
            var time:Number = (dis / this._speed_) * 1000;



			//剩余的时间 小于这帧间隔的时间情况下  直接使用剩余的时间来计算长度
			
            //当间隔积累时间大于或等于达到目标位置所需实际通过时间时,以实际通过路程所需时间为准
            if(totalTime >= time)
            {
                //间隔积累时间减去实际时间,得出还可以继续走的积累时间,并在到达目的地后将间隔积累时间置0;
                this.totalTime -= time;
            }
            else 
            {
                //当当前间隔积累时间内不能到达预订目的地时使用当前积累时间作为实际速度的换算。并将间隔积累时间置0;
                time = totalTime;
                this.totalTime = 0;
            }
            
            //根据当前速度以及在该段时间内的路程
            var vs:Number = this._speed_ * time / 1000;
            
            //根据当前位置以及目标位置计算出 在目标位置方向的具体位移量。
            var dx:Number = tar_point.x - point.x;
            var dy:Number = tar_point.y - point.y;
            var angle:Number = Number(( Math.atan2(dy,dx)).toFixed(2));
            var vx:Number = Number(( Math.cos(angle) * vs).toFixed(2));
            var vy:Number = Number((Math.sin(angle) * vs).toFixed(2));
            
            this.y += vy;
            this.x += vx;
            
            //计算新位置与目标位置的距离,这里需要取整形,避免小数的误差导致无法验证达到目的地
            dis = int(Point.distance(new Point(x,y),tar_point));
            
            //当到达预订位置后,否则等待下次心跳
            if(dis <= 0)
            {
            	//当还有剩余路径需要行走时
                if(this.pathArr.length > 0)
                {
                	tar_point = this.pathArr.shift();
				}
				else 
				{
                    //否则全程行走完毕,重置cur_pt,totalTime,runing,以及角色动作
                    totalTime = 0;
                    tar_point = null;
                    this.dispatchEvent(new Event(Event.COMPLETE));
                }
            }               
    	}       
    }
}
分享到:
评论

相关推荐

    //敌人自动追击主角的代码

    首先,我们关注到代码中的`stage.addEventListener(Event.ENTER_FRAME,event_fn);`这一行,这表明程序在Flash舞台(stage)上添加了一个帧事件监听器。每当舞台更新一帧时,就会调用`event_fn`函数进行处理。 ```as...

    AS3 雷电效果

    2. **动画原理**:雷电的闪烁和移动可以通过Tween或 ENTER_FRAME 事件实现。Tween对象可以平滑地改变对象的属性,如位置、大小或透明度。而监听ENTER_FRAME事件可以在每一帧执行特定代码,实现连续动画效果。 3. **...

    动画 AdvancEDActionScriptAnimation

    AS3允许开发者自定义运动路径,不仅可以沿着直线运动,还可以沿着曲线、圆形等复杂路径移动对象,这大大增强了动画的多样性。通过`CurveTo()`方法,可以定义平滑的贝塞尔曲线,实现平滑的动画轨迹。 除此之外,AS3...

    AS3实现百战天虫中的子弹挖坑效果

    4. **子弹运动**:在AS3中,我们可以使用 ENTER_FRAME 事件来更新子弹的位置,模拟其直线飞行。通过设置速度和方向,可以控制子弹的移动轨迹。 5. **碰撞检测**:实现子弹挖坑的关键在于准确检测子弹与地面的碰撞。...

    flash作品 蝴蝶飞呀

    4. **设置动作**:现在,我们需要告诉蝴蝶按照引导层的路径移动。在蝴蝶所在的图层的第一帧,右键点击并选择“动作”(Actions),在ActionScript 2.0或3.0中输入以下代码: - AS2: ```actionscript onEnterFrame...

    射击游戏打鸭子

    例如,鸭子可能会按照预设路径飞行,而玩家射出的子弹则以直线轨迹移动。在AS3.0中,可以使用 ENTER_FRAME 事件来每帧更新对象的位置,从而实现动态效果。 音效也是游戏体验的重要组成部分。“打鸭子”可能使用AS...

    flash shiti

    19.Flash插入(Insert)菜单中,Key Frame表示? A. 删除当前帧或选定的帧序列 B. 在时间线上插入一个新的关键帧 C. 在时间线上插入一个新的空白关键帧 D. 清楚当前位置上或选定的关键在时间线上插入一个新的...

    vb控件大全与使用教程

    - **路径(Path)**:当前选定的路径。 #### 十三、文件控件的说明 文件控件用于读取和写入文件。 - **打开(Open)**:用于打开文件的方法。 - **关闭(Close)**:用于关闭已打开文件的方法。 - **读取(Read)**:用于...

    excel-vb常用词汇252个

    `Line`方法用于在图片框或形状控件中绘制直线。 #### List 列表 `List`通常指一个有序的数据集合。 #### Listbox 列表框 `ListBox`控件用于显示可选项目的列表。 #### Load 装载 `Load`方法用于加载窗体或控件。 ...

Global site tag (gtag.js) - Google Analytics