PhysicsControl.ts 2.96 KB
export class PhysicsControl {

    static UPDATE_FRAME_RATE: number = 60;
    private static UPDATE_FRAME_TIME: number = 1 / 60;
    static TIME_SCALE: number = 1;

    private static _ins: PhysicsControl = null;
    static get ins(): PhysicsControl {
        this._ins == null && (this._ins = new PhysicsControl());

        return this._ins;
    }

    private _manager: cc.PhysicsManager;

    init() {

        this._manager = cc.director.getPhysicsManager();
        this._manager.enabled = true;

        CC_DEV && (this._manager.debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit);

        cc.PhysicsManager.prototype['updateClone'] = cc.PhysicsManager.prototype['update']; //缓存原来的update方法
        cc.PhysicsManager.prototype['update'] = function (dt: number) {
            return; //屏蔽原来的update方法
        }

        //添加自己的update接口
        cc.PhysicsManager.prototype['updateNew'] = function (dt: number) {
            var world = this._world;
            if (!world || !this.enabled) return;

            this.emit('before-step');

            this._steping = true;

            var velocityIterations = cc.PhysicsManager.VELOCITY_ITERATIONS;
            var positionIterations = cc.PhysicsManager.POSITION_ITERATIONS;

            this._accumulator += dt;

            let frameTime = PhysicsControl.UPDATE_FRAME_TIME;

            if (this._accumulator >= frameTime) {
                let count = Math.floor(this._accumulator / frameTime);
                this._accumulator -= (count * frameTime);

                let stepNum = count * PhysicsControl.TIME_SCALE;

                for (let i = 0; i < stepNum; ++i) {
                    world.Step(frameTime, velocityIterations, positionIterations);
                }
                // world.Step(frameTime * count * PhysicsControl.TIME_SCALE, velocityIterations, positionIterations); //不补帧,延长物理步进的时间
            }

            if (this.debugDrawFlags) {
                this._checkDebugDrawValid();
                this._debugDrawer.clear();
                world.DrawDebugData();
            }

            this._steping = false;

            var events = this._delayEvents;
            for (var i = 0, l = events.length; i < l; i++) {
                var event = events[i];
                event.target[event.func].apply(event.target, event.args);
            }
            events.length = 0;

            this._syncNode();
        }



    }

    /**设置物理刷新帧率 */
    setFrameRate(value: number) {
        PhysicsControl.UPDATE_FRAME_RATE = value;
        PhysicsControl.UPDATE_FRAME_TIME = 1 / value;
    }

    /**设置物理世界时间缩放倍数 */
    setTimeScale(value: number) {
        PhysicsControl.TIME_SCALE = value;
    }

    setPhysicsEnable(value: boolean) {
        this._manager.enabled = value;
    }

    getPhysicsEnable(): boolean {
        return this._manager.enabled;
    }

    update(dt: number) {
        this._manager['updateNew'](dt);
    }
}