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)); } } } } }