写在最前:本文已将Unity3D中的Vector3.SmoothDamp翻译为CocosCreate(TS语言)版本,并将三维向量更改为二维,三维运算方式相同。
private _currentVelocity : cc.Vec2 = new cc.Vec2(0, 0); private doSmoothDamp() { let nowTime = new Date().getTime(); // 保存当前时间 let nowX = this._data._chacheX.length > 0 ? this._data._chacheX.shift() : this._data.PosX; // 保存当前位置X轴 let nowY = this._data._chacheY.length > 0 ? this._data._chacheY.shift() : this._data.PosY; // 保存当前位置Y轴 // 调用缓动函数,修改node位置 this.node.position = this.SmoothDamp( this.node.position, new cc.Vec2(nowX, nowY), this._currentVelocity, 0.34, 14.4 * 20, (nowTime - this._lastUpadtePosTime) / 1000); this._lastUpadtePosTime = nowTime; // 保存上一次时间,用于计算时间间隔 } // current: 当前的位置 // target: 我们试图接近的位置 // currentVelocity: 当前速度,这个值在每次调用这个函数在函数内被修改 // smoothTime: 到达目标的大约时间,较小的值将快速到达目标,假设客户端帧为每秒60帧, // 服务器帧为每 秒20帧,smoothTime = 20/60; // maxSpeed: 选择允许你限制的最大速度,假设帧率同smoothTime, // maxSpeed = 20 * 14.4(角色每帧行走的像素) // deltaTime: 自上次调用这个函数的时间。默认为 Time.deltaTime(Unity内置函数,这里使用 // 客户端当前时间计算得出) private SmoothDamp(current: cc.Vec2, target: cc.Vec2, currentVelocity: cc.Vec2, smoothTime: number, maxSpeed: number, deltaTime: number) { smoothTime = Math.max(0.0001, smoothTime); let finalVelocity = currentVelocity; let num1: number = 2 / smoothTime; let num2: number = num1 * deltaTime; let num3: number = (1.0 / (1.0 + num2 + 0.479999989271164 * num2 * num2 + 0.234999999403954 * num2 * num2 * num2)); let vector: cc.Vec2 = current.sub(target); let vector2_1: cc.Vec2 = new cc.Vec2(target.x, target.y); let maxLength = maxSpeed * smoothTime; let vector2_2: cc.Vec2 = this.ClampMagnitude(vector, maxLength); target = current.sub(vector2_2); let vector2_3: cc.Vec2 = (currentVelocity.add(vector2_2.mul(num1))).mul(deltaTime); currentVelocity = (currentVelocity.sub(vector2_3.mul(num1))).mul(num3); let vector2_4: cc.Vec2 = target.add(vector2_2.add(vector2_3).mul(num3)); let dot = vector2_1.sub(current).dot(vector2_4.sub(vector2_1)); if ( dot > 0.0) { vector2_4 = vector2_1; currentVelocity = vector2_4.sub(vector2_1).mul(1 / deltaTime); } finalVelocity.x = currentVelocity.x; finalVelocity.y = currentVelocity.y; return vector2_4; } private ClampMagnitude(vec2 : cc.Vec2, maxLength : number) : cc.Vec2 { let v2 = vec2.normalize(); let nowLen = vec2.mag(); nowLen = nowLen > maxLength ? maxLength : nowLen; v2.x = v2.x * nowLen; v2.y = v2.y * nowLen; return v2; }