laya2d 物体从起点移动到目标点(按一定角速度平滑偏转)

12 篇文章 2 订阅
7 篇文章 0 订阅

可方便的实现火箭弹追踪效果

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工具类在这里

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值