可方便的实现火箭弹追踪效果
import MathE from "./MathE";
import Script = Laya.Script;
import Image = Laya.Image;
import Point = Laya.Point;
export default class MoveAngleToTarget extends Script {
private _targetPos: Point = null;
public get targetPos(): Point {
return this._targetPos;
}
public set targetPos(val: Point) {
this._targetPos = val;
}
private img: Image;
/** 每秒移动多少像素 */
private speed: number = 200;
/** 每秒偏移多少角度 */
private rotateSpeed: number = 120;
// 最小旋转距离, 如果在这个距离内 向目标点偏转 会转一个圆圈,从而永远到不了目标点
private minRotateDistance: number;
constructor() {
super();
}
onAwake() {
this.img = this.owner as Image;
}
onStart() {
// 周长 = pi * 直径 = 速度 * 时间, 转一周的时间t = 360 / 角速度, 最短偏转距离就是直径
this.minRotateDistance = this.speed * (360 / this.rotateSpeed) / Math.PI;
}
onUpdate() {
if (this.targetPos == null) return;
let delta: number = Laya.timer.delta;
let ownerPos: Point = this.getPos();
let distance: number = MathE.distanceV2(ownerPos, this.targetPos);
let angle: number = MathE.angle(ownerPos, this.targetPos);
if (distance > this.minRotateDistance || (Math.abs(angle - this.img.rotation) < 90 || Math.abs(this.img.rotation - angle) < 90)) { // 到目标点的距离大于最大偏转距离时再进行偏转
if (this.img.rotation != angle) {
// 慢慢朝目标点偏移过去
if (Math.abs(angle - this.img.rotation) <= 180) {
if (angle - this.img.rotation > 0) {
if (this.img.rotation + this.rotateSpeed * delta / 1000 < angle) {
this.img.rotation += this.rotateSpeed * delta / 1000;
} else {
this.img.rotation = angle;
}
} else {
if (this.img.rotation - this.rotateSpeed * delta / 1000 > angle) {
this.img.rotation -= this.rotateSpeed * delta / 1000;
} else {
this.img.rotation = angle;
}
}
} else { // 相隔超过180度应该朝接近的地方转
if (angle - this.img.rotation > 0) { // 倒转
let targetRotation: number = this.img.rotation - this.rotateSpeed * delta / 1000;
if (targetRotation < 0) {
targetRotation += 360;
if (targetRotation <= angle) {
this.img.rotation = angle;
} else {
this.img.rotation -= this.rotateSpeed * delta / 1000;
}
} else {
this.img.rotation -= this.rotateSpeed * delta / 1000;
}
} else { // 正转
let targetRotation: number = this.img.rotation + this.rotateSpeed * delta / 1000;
if (targetRotation > 360) {
targetRotation -= 360;
if (targetRotation >= angle) {
this.img.rotation = angle;
} else {
this.img.rotation += this.rotateSpeed * delta / 1000;
}
} else {
this.img.rotation += this.rotateSpeed * delta / 1000;
}
}
}
}
if (this.img.rotation < 0) {
this.img.rotation += 360;
} else if (this.img.rotation > 360) {
this.img.rotation -= 360;
}
}
let dir: Point = MathE.angleToV2(this.img.rotation);
let speedX: number = this.speed * dir.x * delta;
let speedY: number = this.speed * dir.y * delta;
// x方向移动
if (speedX / Math.abs(speedX) == (this.targetPos.x - this.img.x) / Math.abs(this.targetPos.x - this.img.x)) { // 相同方向
if (speedX > 0) { // 增加可读性
if (this.img.x + speedX / 1000 >= this.targetPos.x) {
this.img.x = this.targetPos.x;
} else {
this.img.x += speedX / 1000;
}
} else {
if (this.img.x + speedX / 1000 <= this.targetPos.x) {
this.img.x = this.targetPos.x;
} else {
this.img.x += speedX / 1000;
}
}
} else { // 不同方向
this.img.x += speedX / 1000;
}
// y方向移动
if (speedY / Math.abs(speedY) == (this.targetPos.y - this.img.y) / Math.abs(this.targetPos.y - this.img.y)) { // 相同方向
if (speedY > 0) {
if (this.img.y + speedY / 1000 >= this.targetPos.y) {
this.img.y = this.targetPos.y;
} else {
this.img.y += speedY / 1000;
}
} else {
if (this.img.y + speedY / 1000 <= this.targetPos.y) {
this.img.y = this.targetPos.y;
} else {
this.img.y += speedY / 1000;
}
}
} else {
this.img.y += speedY / 1000;
}
if (this.img.x == this.targetPos.x && this.img.y == this.targetPos.y) { // 到达终点停止
this.targetPos = null;
}
}
public getPos(): Point {
return new Point(this.img.x, this.img.y);
}
}
MathE工具类在这里