一.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();
}