egret使用二维向量实现曲线运动

目标效果,针对于一些列点做曲线圆滑的转向效果,试用三角函数等都未达到理想效果。后来使用voctor2d向量来实现。

封装方法:


class GuideMov extends hw.DisplayObjectContainer {
constructor(_tihsobj?: any) {
super(_tihsobj);
}
//移动物体
public obj;
//点列表
public list;
//当前目标id
public num = 0;
//当前修正值
public xiunum = 0;
//移动速度
public speed = 10;
//初始基础偏移量
public piannum = 0.1;
//叠加偏移量
public xiudevnum = 0.025;
//初始目标向量
public v1:hw.Vector2D;
//是否循环移动
public loop:boolean = false;
//初始化
public init(_obj,_list,_speed=10,_loop=false) {
this.obj = _obj;
this.list = _list;
this.loop = _loop;
this.speed = _speed;
//初始方向默认为向右;
this.v1 = new hw.Vector2D(1,0);
hw.UPDATE.ADD_LISTENER(this.update,this);
}
//根据振频率的渲染
public update(){
//获取目标向量
var v2 = new hw.Vector2D(this.list[this.num].x-this.obj.x,this.list[this.num].y-this.obj.y);
//转换为单位向量
v2.normalize();
//根据计算偏移量来缩放向量
v2.length = this.piannum+this.xiunum;
//向量叠加偏移
this.v1 = this.v1.add(v2);
//新向量重置为单位向量
this.v1.normalize();
//旋转
this.obj.rotation = hw.MathExt.radiansToRotate(this.v1.angle);
//移动
this.obj.x +=this.v1.x*this.speed;
this.obj.y +=this.v1.y*this.speed;
//修正偏移量
this.xiunum+=this.xiudevnum;
if(this.xiunum>1-this.piannum)this.xiunum=1-this.piannum;
//画路径点
var shape1 = new hw.Shape();
this.addChild(shape1);
shape1.graphics.beginFill(0);
shape1.graphics.drawCircle(this.obj.x,this.obj.y,2);
shape1.graphics.endFill();
//判断是否到了点附近
if(this.getDistance(this.obj,this.list[this.num])=this.list.length){
this.num = 0;
if(!this.loop){
hw.UPDATE.REM_LISTENER(this.update,this);
}
}
}
}
//获取距离
public getDistance(_p1,_p2):number{
var dx = _p1.x - _p2.x;
var dy = _p1.y - _p2.y;
return Math.sqrt(dx * dx + dy * dy);
}
}

Vector2D 类

module hw {
export class Vector2D {
private _x: number;
private _y: number;
public constructor(x: number = 0, y: number = 0) {
this._x = x;
this._y = y;
}
//画出向量
public draw(graphics: egret.Graphics, color: number = 0) {
graphics.lineStyle(0, color);
graphics.moveTo(0, 0);
graphics.lineTo(this._x, this._y);
}
//克隆
public clone(): hw.Vector2D {
return new hw.Vector2D(this.x, this.y);
}
//零向量
public zero(): hw.Vector2D {
this._x = 0;
this._y = 0;
return this;
}
//是否是零向量
public isZero(): boolean {
return this._x == 0 && this._y == 0;
}
//向量长度
public set length(value: number) {
var a: number = this.angle;
this._x = Math.cos(a) * value;
this._y = Math.sin(a) * value;
}
public get length(): number {
return Math.sqrt(this.lengthSQ);
}
//获取当前向量大小的平方
public get lengthSQ(): number {
return this._x * this._x + this._y * this._y;
}
//向量角度
public set angle(value: number) {
var len: number = this.length;
this._x = Math.cos(value) * len;
this._y = Math.sin(value) * len;
}
public get angle(): number {
return Math.atan2(this._y, this._x);
}
//将当前向量转化成单位向量
public normalize(): hw.Vector2D {
if (this.length == 0) {
this._x = 1;
return this;
}
var len: number = this.length;
this._x /= len;
this._y /= len;
return this;
}
//截取当前向量
public truncate(max: number): hw.Vector2D {
this.length = Math.min(max, this.length);
return this;
}
//反转向量
public reverse(): hw.Vector2D {
this._x = -this._x;
this._y = -this._y;
return this;
}
//是否是单位向量
public isNormalized(): boolean {
return this.length == 1.0;
}
//向量积
public dotProd(v2: hw.Vector2D): number {
return this._x * v2.x + this._y * v2.y;
}
//差积 差积=0为垂直
public crossProd(v2: hw.Vector2D): number {
return this._x * v2.y - this._y * v2.x;
}
//返回两向量夹角的弦度值
public static angleBetween(v1: hw.Vector2D, v2: hw.Vector2D): number {
if (!v1.isNormalized())
v1 = v1.clone().normalize();
if (!v2.isNormalized())
v2 = v2.clone().normalize();
return Math.acos(v1.dotProd(v2));
}
//返回坐标向量
public get perp(): hw.Vector2D {
return new hw.Vector2D(-this.y, this.x);
}
// 返回当前向量与V2的距离
public dist(v2: hw.Vector2D): number {
return Math.sqrt(this.distSQ(v2));
}
//返回当前向量与V2的距离的平方
public distSQ(v2: hw.Vector2D): number {
var dx: number = v2.x - this.x;
var dy: number = v2.y - this.y;
return dx * dx + dy * dy;
}
//两向量相加
public add(v2: hw.Vector2D): hw.Vector2D {
return new hw.Vector2D(this._x + v2.x, this._y + v2.y);
}
//两向量相减
public subtract(v2: hw.Vector2D): hw.Vector2D {
return new hw.Vector2D(this._x - v2.x, this._y - v2.y);
}
//数与向量的乘积
public multiply(value: number): hw.Vector2D {
return new hw.Vector2D(this._x * value, this._y * value);
}
//数与向量的商
public divide(value: number): hw.Vector2D {
return new hw.Vector2D(this._x / value, this._y / value);
}
//相等
public equals(v2: hw.Vector2D): boolean {
return this._x == v2.x && this._y == v2.y;
}
public set x(value: number) {
this._x = value;
}
public get x(): number {
return this._x;
}
public set y(value: number) {
this._y = value;
}
public get y(): number {
return this._y;
}
public toString(): string {
return "[Vector2D (x:" + this._x + ", y:" + this._y + ")]";
}
}
}

本文作者:依十七  本文链接:http://www.is17.com/479/

本站文章若无特别说明,皆为原创,如需转载,请以超链接形式注明作者和原始出处及本声明

发布者

依十七

风逝难依,陌归十七。

发表评论

电子邮件地址不会被公开。 必填项已用*标注