cocoscreator 游戏音效卡顿优化

发牢骚

最近在做一款物理小游戏的时候,在大量物体碰撞的时候,出现了游戏卡顿,甚至帧数降到10以下,直接卡住很久的情况。

cocoscreator的物理引擎性能经常被开发者诟病,由于短时间了,200-300个刚体发生碰撞,数量有点多,我一度怀疑是物理引擎的锅,找着找着,原来是频繁调用play音效的问题。几百个刚体碰撞,就会调用几百次的play方法来播放碰撞音效,这才是根本原因。

相信你也很快就能找到解决

方法1

既然一次性调用太多次play导致卡,那就分帧播放,分担每一帧的压力 实现如下:

//声明回调方法
export type CallbackVoid = () => void;
...
//创建播放音效的回调函数列表
private willPlayEffects: CallbackVoid[] = [];
...
/**
* 在碰撞的时候,将播放声音的回调压入到列表李里面
*/
protected beginContact(contact: cc.PhysicsContact, selfCollider: cc.PhysicsCollider, otherCollider: cc.PhysicsCollider): void {
    if (otherCollider.node.group === "Column"){
        const fun: CallbackVoid = () => {
            AudioPlayer.playEffectCache(ResPath.Sound.Collision);
        }
        this.willPlayEffects.push(fun);
    }
}
...
protected update(dt: number){
    if (this.willPlayEffects.length === 0) return;
    const fun = this.willPlayEffects.shift();
    fun(); 
}

//如果音效太多,可以一帧多播放几个,比如播放10个,否则你会发现,声音会让你产生如蚊子飞到你耳朵附近的那种难受的感觉
protected update(dt: number){
    for (let i = 0; i < 10; i++) {
        if (this.willPlayEffects.length === 0) return;
        const fun = this.willPlayEffects.shift();
        fun(); 
    }    
}
复制代码

方法2

可以将短时间重复播放的音效合成一个,来循环播放,或者直接单音循环播放也可以起到优化的效果。在碰撞或者动画结束的时候,暂停(pause)音效播放即可,下次只要resume 就好。或者可以设置在几秒之内重复收到同样的音效不执行。

总之就是避免频繁的 执行 play。

分类:
前端