这是我参照unity3d的抛物线修改的,写的不好请大家多多包涵。
废话不多说,直接上代码:
/*
* @Author: David.Huang
* @Date: 2020-09-25 09:33:51
* @LastEditTime: 2020-09-25 21:31:49
* @LastEditors: Please set LastEditors
* @Description: 抛物线轨迹
*/
import { _decorator, Component, Node, Vec3} from 'cc';
import { MathUtil } from '../../../core/utils/MathUtil';
import { PoolUtil } from '../../../core/utils/PoolUtil';
import { WEAPON_FLY_TYPE } from '../../battle/data/BattleConfig';
import { BaseWeapon } from '../base/BaseWeapon';
const { ccclass, property } = _decorator;
const _tempVec: Vec3 = new Vec3();
@ccclass('ParabolaLocus')
export class ParabolaLocus extends BaseWeapon {
/** 重力加速度 */
private _g = -10;
/** 抛出去的速度,值越大顶点越高 */
private _shotSpeed: number = 15;
/** 初速度向量 */
private _speed: Vec3 = null;
/** 重力向量 */
private _gravity: Vec3 = null;
/** 当前角度 */
private _currAngle: Vec3 = null;
private _dTime = 0;
private _flyType: number = -1;
private _dir: number = 1;
private _isMoving: boolean = false;
onLoad() {
this._speed = new Vec3();
this._gravity = new Vec3();
this._currAngle = new Vec3();
}
public launchWeapon(flyType: number, startPos: Vec3, endPos: Vec3): void {
this.startPos = startPos;
this.endPos = endPos;
this._flyType = flyType;
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._flyType === WEAPON_FLY_TYPE.LEFT_PARABOL ? -1 : 1;
let offsetX: number, offsetY: number = 0;
switch (this._flyType) {
case WEAPON_FLY_TYPE.LINE:
offsetY = 0.5 * this._g * time;
break;
default:
offsetX = 0.5 * this._g * 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._flyType === WEAPON_FLY_TYPE.LINE) { //直线抛物线
this._gravity.y = this._g * (this._dTime += dt);
} else { //左右抛物线
this._gravity.x = this._g * (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._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;
console.warn('达到终点~~~~~~~~~~~');
PoolUtil.setNode(this.node);
}
}