欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一.COCOSCREATOR3D 左右抛物线和垂直抛物线

程序员文章站 2022-06-11 11:41:57
...

一.COCOSCREATOR3D 左右抛物线和垂直抛物线

  • 缺点
    • 因为是根据2点之间的距离去计算时间的,所有飞行速度都是恒定的,等有空再去改改吧,或者有大佬去帮忙改一下。
    • 第一次用C3D写3D项目,还有许多写的不好的地方,请大家多多包涵。
    /** 重力加速度 */
    private _gAcc:number = -10;
    /** 抛出去的速度,值越大顶点位置越高 */
    private _shotSpeed:number = 15;
    /** 初速度向量 */
    private _speed: Vec3 = null;
    /** 重力向量 */
    private _gravity: Vec3 = null;
    /** 当前角度 */
    private _currAngle: Vec3 = null;
    private _dTime = 0;
    private _vo: WeaponVO = null;
    private _dir: number = 1;
    private _isMoving: boolean = false;
    private _damageTeam: number = -1;

    onLoad() {
        this._speed = new Vec3();
        this._gravity = new Vec3();
        this._currAngle = new Vec3();
    }

    public launchWeapon(vo: WeaponVO, damageTeam: number, startPos: Vec3, endPos: Vec3): void {
        this.startPos = startPos;
        this.endPos = endPos;
        this._vo = vo;
        this._damageTeam = damageTeam;
        this._dTime = 0;
        //设置初始位置
        this.node.setWorldPosition(this.startPos);

        //求2点之间的距离
        Vec3.subtract(_tempVec, this.startPos, this.endPos);
        const time = _tempVec.length() / this._shotSpeed;

        this._dir = this._vo.flyType === WEAPON_FLY_TYPE.LEFT_PARABOL ? -1 : 1;
        let offsetX: number, offsetY: number = 0;
        switch (this._vo.flyType) {
            case WEAPON_FLY_TYPE.LINE:
                offsetY = 0.5 * this._gAcc * time;
                break;
            default:
                offsetX = 0.5 * this._gAcc * time * this._dir;
                break;
        }

        //计算初速度
        this._speed = new Vec3((this.endPos.x - this.startPos.x) / time - offsetX, (this.endPos.y - this.startPos.y) / time - offsetY, (this.endPos.z - this.startPos.z) / time);
        //重力初速度为0
        Vec3.zero(this._gravity);
        this._isMoving = true;
    }


    update(dt: number) {
        if (!this._isMoving) return;

        if (this._vo.flyType === WEAPON_FLY_TYPE.LINE) {   //直线抛物线
            this._gravity.y = this._gAcc * (this._dTime += dt);
        } else {    //左右抛物线
            this._gravity.x = this._gAcc * (this._dTime += dt * this._dir);
        }

        //计算抛物线位置
        let pos: Vec3 = this.node.getWorldPosition();
        Vec3.add(_tempVec, this._speed, this._gravity);
        Vec3.multiplyScalar(_tempVec, _tempVec, dt);
        Vec3.add(pos, pos, _tempVec);

        if (this._vo.flyType === WEAPON_FLY_TYPE.LINE) {   //直线抛物线
            this._currAngle.x = Math.atan((this._speed.y + this._gravity.y) / this._speed.z) * MathUtil.Rad2Deg;
        } else {    //左右抛物线
            this._currAngle.y = Math.atan((this._speed.x + this._gravity.x) / this._speed.z) * MathUtil.Rad2Deg;
        }

        this.node.eulerAngles = this._currAngle;
        this.node.setWorldPosition(pos);

        //判断是否达到目标点
        Vec3.subtract(_tempVec, this.endPos, pos);
        if (_tempVec.length() <= 0.3) {
            this.arriveTarget();
        }
    }

    /**
     * 达到目标
     */
    private arriveTarget() {
        this._isMoving = false;
        PoolUtil.setNode(this.node);
        EventMgr.dispatchEvent(BattleEvent.UPDATE_BLOOD, this._damageTeam, -this._vo.damage);
        this.playBombEffect();
    }