Egret之Sound壓縮方案
一 : 前景
如果一個遊戲需要一次預載入多個Sound(比如說10個),傳統的方案那就需要網路請求10次來載入這些資源.耗費在網路上的時間成本是很大的.那麼方案來了 : 壓縮Sound!我前段時間糾結於將Sounds壓縮到Zip中,然後解壓成一個一個的Sound來播放.But,隨之而來的問題是,我沒有找到方法或者是API能將Zip中的Sound資源還原成egret.Sound物件.其實我挺喜歡這種方案的,奈何能力有限,如有讀者有這方面的方法或者思路請留言或者私信我,不勝感激.最後我找到了另一種方案 : 將所有的Sounds拼接到一個Sound檔案中.如將10個Mp3拼接到1個Mp3中.本文講解此方案的實現:
二 : 實現
Ⅰ: 音效方面
我將飄金幣的音效(money.mp3)和踢足球的音效(football.mp3)按順序拼接在了一個mp3檔案中(golds_football.mp3),其中在0.674秒進入到football.mp3的播放.如圖:
Ⅱ:播放器的實現(DemoSound)
module demo{
/**
* 音樂Demo
* <b style="color:red">一個MP3中分段播放多個音效</b>
* <b style="color:green">
* 目的 : 將幾個短的音效拼接成一個mp3檔案,這樣減少網路請求,可以加快載入進度.尤其是零碎音效比較多的情況
* </b>
* @author Aonaufly
*/
export class DemoSound{
private static _instance : DemoSound = null;
public static get Instance() : DemoSound{
if( !DemoSound._instance )
DemoSound._instance = new DemoSound();
return DemoSound._instance;
}
private _sound : egret.Sound = null;
private _soundChannel : egret.SoundChannel = null;
private _is_playing : boolean = false;
private _interval_id : number = null;
private readonly _sound_start : Array<number> = null;
private _over_position : number = null;
private constructor(){
this._sound_start = [
0,
0.674
];
}
public play( $ty : TYPE_SOUND ) : void{
if( !this._is_playing ){
this._is_playing = true;
if( !this._sound )
this._sound = RES.getRes(`golds_football_mp3`);
let $start_postion : number = null;
switch( $ty ){
case TYPE_SOUND.___MONEY___:
$start_postion = this._sound_start[0];
this._over_position = this._sound_start[1] - 0.001;
break;
case TYPE_SOUND.___FOOTBALL___:
$start_postion = this._sound_start[1];
this._over_position = null;
break;
}
this._soundChannel = this._sound.play( $start_postion,1 );
this.listener2Handler( true );
}
}
private listener2Handler( $isAdd : boolean ) : void{
if( $isAdd ){
this._interval_id = setInterval(
this.onLoopCheck.bind(this),
10
);
if( !this._soundChannel.hasEventListener(egret.Event.SOUND_COMPLETE) )
this._soundChannel.addEventListener( egret.Event.SOUND_COMPLETE , this.onTimeUpdate , this );
}else{
if( this._interval_id && this._interval_id > 0 ){
clearInterval( this._interval_id );
this._interval_id = 0;
}
if( this._soundChannel.hasEventListener(egret.Event.SOUND_COMPLETE) )
this._soundChannel.removeEventListener( egret.Event.SOUND_COMPLETE , this.onTimeUpdate , this );
this._is_playing = false;
}
}
private onTimeUpdate( $e : egret.Event ) : void{
if(!this._over_position){
egret.log(`播放完畢!!!`);
this.sound_over();
}else{
if( this._soundChannel.hasEventListener(egret.Event.SOUND_COMPLETE) )
this._soundChannel.removeEventListener( egret.Event.SOUND_COMPLETE , this.onTimeUpdate , this );
}
}
private onLoopCheck() : void{
if( this._over_position ){
let $position : number = this._soundChannel ? this._soundChannel.position : 0;
egret.log(`sound pos : ${$position}`);
if( $position >= this._over_position ){
this._soundChannel.stop();
this.sound_over();
}
}else{
if( this._interval_id && this._interval_id > 0 ){
clearInterval( this._interval_id );
this._interval_id = 0;
}
}
}
private sound_over() : void{
this.listener2Handler(false);
}
}
export enum TYPE_SOUND{
___MONEY___ = 1,
___FOOTBALL___ = 2
}
}
解釋 :
① :
this._sound_start = [
0,
0.674
];
0 : money音效播放的position(秒) / 0.674 : football音效播放的position
②:
export enum TYPE_SOUND{
MONEY = 1,
FOOTBALL = 2
}
MONEY : 播momey音效 / FOOTBALL : 播football音效
Ⅲ : 互動介面
注意 : 每一種音效播放完畢後 , 才能繼續播放音效
三 : 效果
四:資源
「其他文章」
- Android——一個簡單的銀行系統
- 可以讓你寫到簡歷上的“網約車”專案,太讚了!!!
- git clone early EOF解決方法
- ES6(三) Promise 的基本使用方式
- Linux的哲學思想
- 為什麼阿里巴巴不建議 boolean 型別變數用 isXXX?
- 微信之夜,張小龍說視訊化表達將會成為下一個十年內容領域的主題
- WEB入門.九 導航選單
- 探索 .Net Core 的 SourceLink
- EdgeBERT:極限壓縮,比ALBERT再輕13倍!樹莓派上跑BERT的日子要來了? - 知乎
- shell 中if [ -e/d/f ..... ] 詳解
- 寫“好”程式碼的十九條準則
- 自學第三十五天
- 謝煙客---------二進位制安裝MariaDB,管理關係型資料庫的基本元件
- Egret之Sound壓縮方案
- Android studio 解決編譯速度慢 Download maven-metadata.xml速度很慢
- Flutter 中 BottomNavigationBar 定義底部導航條
- 肖四背背背
- nginx配置檔案
- yanghui三角形