forked from: SoundEffectクラス [テスト版]
//////////////////////////////////////////////////////////////////////////////
SoundEffectクラス [テスト版]
ここはこうした方がいいんでねぇえの?的なところがあったら、
forkしてくださいまし♪
//////////////////////////////////////////////////////////////////////////////
forkしようとおもったけどごっっそりオレオレなSoundManagerクラスと入れ替えた、、
自分でつくって置きながら手元に最新版がなくてたしかバグがのこってます
後日ver1.5.1と入れ替える、、
何か突っ込みどころがあればぜひ、、
/**
* Copyright selflash ( http://wonderfl.net/user/selflash )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/n3kn
*/
// forked from ProjectNya's SoundEffectクラス [テスト版]
////////////////////////////////////////////////////////////////////////////////
// SoundEffectクラス [テスト版]
//
// ここはこうした方がいいんでねぇえの?的なところがあったら、
// forkしてくださいまし♪
////////////////////////////////////////////////////////////////////////////////
// forkしようとおもったけどごっっそりオレオレなSoundManagerクラスと入れ替えた、、
// 自分でつくって置きながら手元に最新版がなくてたしかバグがのこってます
// 後日ver1.5.1と入れ替える、、
// 何か突っ込みどころがあればぜひ、、
package {
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.net.URLRequest;
[SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")]
public class Main extends Sprite {
private var snd:Sound;
private var sm:SoundManager;
private var source:String = "http://www.project-nya.jp/images/flash/click.mp3";
private var label:Label;
public function Main() {
init();
}
private function init():void {
snd = new Sound();
snd.load(new URLRequest(source));
snd.addEventListener(Event.COMPLETE, complete, false, 0, true);
}
private function complete(e:Event):void {
snd.removeEventListener(Event.COMPLETE, complete);
// サウンド}ネージャー
sm = new SoundManager();
sm.registerSound( snd, "explosion" );
sm.setSound( "explosion" );
// ラベル
label = new Label(120, 40);
addChild(label);
label.x = 232 - 60;
label.y = 232 - 30;
label.text = "♪click";
label.textColor = 0x333333;
stage.addEventListener(MouseEvent.CLICK, click, false, 0, true);
}
private function click(evt:Event):void {
sm.play();
}
}
}
/**
* SoundManager
*
* @author selflash
* @version 1.5.0
*
* Soundを扱いやすくするクラスです.
* クラス内にSoundを登録する事で複数のSoundを扱いやすくなります.
*
* // TODO 一時停止機能
* // TODO 再生中のサウンドを再度頭から再生
* // TODO 現在再生中のサウンドを外部から取得
* // TODO リストに登録されているサウンドの総数
* 済// TODO サウンドリストを外部からごっそり入れ替えれる様に
*
*
*/
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.*;
import flash.display.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
/**
*
* @example <listing version="3.0" >
* // SoundManager インスタンスを作成する
* var soundMg:SoundManager = new SoundManager();
*
* // サウンドを登録する
* sound.registerSound( new Sound( new URLRequest( "sound.mp3") ), "sound.mp3" ) )
*
* // サウンドの登録を解除する
* sound.deregisterSound( "sound.mp3" )
*
* // サウンドを再生
* sound.play();
*
* // サウンドを停止
* sound.stop();
*
* // サウンドをフェードイン
* sound.feedIn();
*
* // サウンドをフェードアウト
* sound.feedOut();
*
* // ボリュームの変更( 0~100 )
* sound.volume = 100;
*
* // 登録されているサウンドを取得
* sound.getSound( "sound.mp3" );
*
* // 曲切替時に途中から再生します
* sound.switchMode = true;
*
* // 現在の状態を取得
* trace( sound.state );
*
* // 放出されるイベント一覧
* // 再生時に放出されます.
* SoundManagerEvent.SOUND_PLAY
* // 停止時に放出されます.
* SoundManagerEvent.SOUND_STOP
* // フェード処理中に放出されます.
* SoundManagerEvent.PROCESS
* // 再生開始時に放出されます.
* SoundManagerEvent.PROCESS_COMPLETE
* // 曲変更時に放出されます.
* SoundManagerEvent.SOUND_CHANGE
* // 曲登録時に放出されます.
* SoundManagerEvent.SOUND_REGISTER
* // 曲登録解除時に放出されます.
* SoundManagerEvent.SOUND_DEREGISTER
* // 音量変更時に放出されます.
* SoundManagerEvent.VOLUME_CHANGE
* // 曲の再生完了時に放出されます.
* SoundManagerEvent.SOUND_COMPLETE
*
* </listing>
*/
class SoundManager extends EventDispatcher {
/*------------------- プライベートメンバ ----------------------------------*/
private var _sound:Sound
private var _position:Number;
private var _channel:SoundChannel;
private var _transform:SoundTransform;
//private var _timer:Timer;
// 再生中のサウンド
private var _nowSoundObj:Object;
/*------------------- パラメーター ----------------------------------------*/
private var _volume:int;
private var _startVol:int;
private var _targetVol:int;
private var _tempVol:int;
private var _counter:int;
private const _PLAY:String = "play";
private const _STOP:String = "stop";
private const _RUN:String = "run";
private const _WAIT:String = "wait";
/**=================================================================*//**
* サウンドリストを入れ替える事ができます.注意点としてはサウンドリストはオブジェクト方であり
* key( String型 )プロパティにsound( Sound型 )プロパティ,position( Number型 )プロパティを持たせたオブジェクトを
* 持たせなければ互換性が保てません.
* @param object サウンドリスト Object[String] = { sound:Sound, position:Number };
*/
public function set soundList( value:Object ):void { _soundList = value; }
private var _soundList:Object;
/**=================================================================*//**
* 音量を設定します.
* @param value 音量
*/
public function set volume( value:int ):void {
if ( value < 0 || value > 100 ) throw new ArgumentError( "Error #2012: volumeを0以下または100以上を指定する事はできません." );
//if ( _targetVol == 0 ) return;
_volume = value;
_targetVol = _volume;
_setVolume();
}
/**=================================================================*//**
* 現在の音量
* @return volume 音量
*
*/
public function get volume():int { return _transform.volume * 100; }
/**=================================================================*//**
* 現在の状態を文字列で返します. 再生中:"play" フェード中:"run" 停止中:"stop" 一時停止中:"wait" 読み取り専用.
* @return state
*/
public function get state():String { return _state; }
private var _state:String;
/**=================================================================*//**
* 曲切り替え時に前回位置から再生するかどうかのプロパティです.
* @param value trueで前回位置から再生.falseで頭から再生.
*
*/
public function set switchMode( value:Boolean ):void { _switchMode = value; }
/**=================================================================*//**
* @return switchMode 現在のモード
*/
public function get switchMode():Boolean { return _switchMode; }
private var _switchMode:Boolean;
/**=================================================================*//**
* リピート回数を設定します.
* @param value -1を指定すると永遠にリピート.
*
*/
public function set loops( value:Number ):void { _loops = value; }
/**=================================================================*//**
* @return loops リピート回数.
*/
public function get loops():Number { return ( _loops < 0 ) ? Infinity : _loops; }
private var _loops:Number;
/**=================================================================*//**
* @return loopCnt 現在のリピート回数.
*/
public function get loopCount():int { return _loopCnt; }
private var _loopCnt:int;
/**=================================================================*//**
* SoundManagerを生成します.初期状態ではサウンドが設定されていないのでregisterSound()でサウンドを設定してください.
* @param switchMode 曲切り替え時に途中再生させるか // TODO 未実装
* @param volume 初期音量
*/
public function SoundManager( switchMode:Boolean = false, volume:Number = 100 ):void {
_switchMode = switchMode;
_volume = volume;
_initialize();
}
/**=================================================================*//**
* 初期化.
*
*/
private function _initialize():void {
_soundList = { };
//_timer = new Timer( 0 );
//_timer.addEventListener( TimerEvent.TIMER, _fading );
//_timer.addEventListener( TimerEvent.TIMER_COMPLETE, _fadeComplete );
_transform = new SoundTransform();
_state = _STOP;
}
/**=================================================================*//**
* 指定した回数分リピートします. 0だとずっとリピートします.
* @param startTimer
* @param loops リピート回数
* @param sndTransform
*/
public function play( startTime:Number = 0, loops:Number = 0 ):void {
trace( "曲開始" );
if ( !_nowSoundObj ) throw new ArgumentError( "Error #2012: 曲が選択されていません.");
if ( _state == _PLAY || _state == _RUN ) return; // TODO 何もエラーを返さない
_targetVol = _volume;
_transform.volume = _targetVol / 100;
_channel = _sound.play( startTime, loops, _transform );
_loops = loops;
_loopCnt = 0;
_channel.addEventListener( Event.SOUND_COMPLETE, _completeHandler );
_state = _PLAY;
dispatchEvent( new Event( SoundManagerEvent.SOUND_PLAY ) );
}
/**=================================================================*//**
* 再生を停止します
*
*/
public function stop():void {
if ( _state == _STOP || _state == _RUN ) return; // TODO 何もエラーを返さない
_channel.stop();
_channel.removeEventListener( Event.SOUND_COMPLETE, _completeHandler );
_channel = null;
_state = _STOP;
dispatchEvent( new Event( SoundManagerEvent.SOUND_STOP ) );
}
/**=================================================================*//**
* 指定した秒数でフェードインさせます.
* @param time フェードインにかける時間
* @param loops リピート回数
*/
public function fadeIn( time:Number = 1, loops:Number = 0 ):void {
if ( /*_state == _RUN || */_state == _PLAY ) return; // TODO 何もエラーを返さない
_loops = loops;
_loopCnt = 1;
_transform.volume = 0;
_channel = _sound.play( 0, loops, _transform );
_startVol = 0;
_fade( _volume, time );
dispatchEvent( new Event( SoundManagerEvent.SOUND_PLAY ) );
}
/**=================================================================*//**
* 指定した秒数でフェードアウトさせます.先に再生をしている必要があります.
* @param time フェードアウトにかける時間
*/
public function fadeOut( time:Number = 1 ):void {
if ( /*_state == _RUN || */_state == _STOP ) return; // TODO 何もエラーを返さない
_channel.removeEventListener( Event.SOUND_COMPLETE, _completeHandler );
_startVol = _volume;
_fade( 0, time );
}
/**=================================================================*//**
* サウンドを登録します.登録解除時やサウンドを取り出す時に必要なキーの設定が必要です.
* @param sound リストに登録するサウンド
* @param key 登録解除や取り出す時に必要なキー
*/
public function registerSound( sound:Sound, key:String ):void {
if ( _soundList.hasOwnProperty( key ) ) throw new ArgumentError( "Error #2012: その曲は既に登録済みです.");
_soundList[key] = { sound:sound, position:0, volume:100 };
dispatchEvent( new Event( SoundManagerEvent.SOUND_REGISTER ) );
}
/**=================================================================*//**
* サウンドをリストから取得します.登録時に設定したキーをつかってください.
* @param key 登録時に設定したキー
*
*/
public function getSound( key:String ):Sound {
if ( !_soundList.hasOwnProperty( key ) ) throw new ArgumentError( "Error #2012: そんな曲はありません.");
return _soundList[key].sound as Sound;
}
/**=================================================================*//**
* サウンドをリストから登録解除します.登録時に設定したキーをつかってください.
* @param key 登録時に設定したキー
* @return sound 登録解除と同時にサウンドを取得できます
*/
public function deregisterSound( key:String ):Sound {
if ( !_soundList.hasOwnProperty( key ) ) throw new ArgumentError( "Error #2012: そんな曲はありません.");
var sound:Sound = _soundList[key].sound as Sound;
_soundList[key] = undefined;
dispatchEvent( new Event( SoundManagerEvent.SOUND_DEREGISTER ) );
return sound;
}
/**=================================================================*//**
* 再生したいサウンドを設定します.登録時に設定したキーをつかってください.
* @param key 登録時に設定したキー
*
*/
public function setSound( key:String ):void {
if ( !_soundList.hasOwnProperty( key ) ) throw new ArgumentError( "Error #2012: そんな曲はありません.");
var soundObj:Object = _soundList[key];
if ( _nowSoundObj == soundObj && _state == _PLAY || _state == _RUN ) return;
// 再生中のサウンドの再生位置を保持
if ( _state == _PLAY ) _nowSoundObj.position = _channel.position;
_sound = ( soundObj.sound as Sound || null );
_position = ( _switchMode ) ? soundObj.position : 0;
_nowSoundObj = soundObj;
stop();
//play( _position, _loops );
// 再生中のサウンドを保持
dispatchEvent( new Event( SoundManagerEvent.SOUND_CHANGE ) );
}
/**=================================================================*//**
* 現在再生中のサウンドを取得できます.
* @return currentSound 再生中のサウンド
*
*/
public function get currentSound():Sound { return _nowSoundObj.sound; }
/**=================================================================*//**
* 現在再生中のサウンドの再生位置を取得できます.
* @return position 再生中のサウンドの再生位置
*
*/
public function get position():Number { return _channel.position; }
/**=================================================================*//**
* 削除
*
*/
private function destroy():void {
_sound = null;
_channel = null;
_transform = null;
//if( _timer.running )_timer.stop();
//_timer = null;
_nowSoundObj = null;
_soundList = null;
_volume = NaN;
_startVol = NaN;
_targetVol = NaN;
_tempVol = NaN;
_counter = NaN;
}
/*------------------- イベント処理 -------------------------------------*/
/**=================================================================*//**
*
*/
private function _fading( e:TimerEvent ):void {
//trace( "■volume:" + _volume );
_counter++;
var tempVol:Number =_counter * 0.1 * ( _targetVol - _startVol ) + _startVol;
_transform.volume = tempVol * 0.01;
_channel.soundTransform = _transform;
dispatchEvent( new Event( SoundManagerEvent.PROCESS ) );
}
/**=================================================================*//**
* フェード完了時の処理
*/
private function _fadeComplete( e:TimerEvent ):void {
e.target.removeEventListener( TimerEvent.TIMER, _fading );
e.target.removeEventListener( TimerEvent.TIMER_COMPLETE, _fadeComplete );
//Timer( e.target ).stop();
if ( _targetVol == 0 )
stop();
else
_setVolume();
_state = ( _targetVol == 0 ) ? _STOP : _PLAY ;
dispatchEvent( new Event( SoundManagerEvent.PROCESS_COMPLETE ) );
}
/*======================================================================================================*//**
* サウンドのループ
* @param e イベント
*/
private function _completeHandler( e:Event):void {
dispatchEvent( new Event( SoundManagerEvent.SOUND_COMPLETE ) );
if ( _loopCnt >= _loops && _loops >= 0 ) {
stop();
return;
}
_channel = _sound.play( 0, 0, _transform );
_channel.addEventListener( Event.SOUND_COMPLETE, _completeHandler );
_loopCnt ++;
dispatchEvent( new Event( SoundManagerEvent.SOUND_PLAY ) );
}
/*------------------- ユーティリティ------------------------------------*/
/**=================================================================*//**
* フェード.
* @param targetVol 目的の音量
* @param time フェードアウトにかける時間
*/
private function _fade( volume:Number, time:Number ):void {
_targetVol = volume;
_counter = 0;
// TODO 毎回newしてる
var timer:Timer = new Timer( time * 1000 / 10, 10 );
timer.addEventListener( TimerEvent.TIMER, _fading );
timer.addEventListener( TimerEvent.TIMER_COMPLETE, _fadeComplete );
timer.start();
_state = _RUN;
}
/**=================================================================*//**
* ボリュームを目的の音量に設定します.
*
*/
private function _setVolume():void {
if ( _state == _STOP || _state == _RUN ) return;
_transform.volume = _targetVol * 0.01;
_channel.soundTransform = _transform;
dispatchEvent( new Event( SoundManagerEvent.VOLUME_CHANGE ) );
}
}
/**
* SoundManagerEvent
*
* @author Tatsuya Yokoda
* @version 1.0.0
*
*
*/
import flash.events.Event;
/**
*
* @example <listing version="3.0" >
*
* </listing>
*/
class SoundManagerEvent extends Event {
//--------------------------------------------------------------------------
// CLASS CONSTANTS
//--------------------------------------------------------------------------
/** 再生時に放出されます. */
public static const SOUND_PLAY:String = "soundPlay";
/** 停止時に放出されます. */
public static const SOUND_STOP:String = "soundStop";
/** フェード処理中に放出されます. */
public static const PROCESS:String = "soundProcess";
/** 再生開始時に放出されます. */
public static const PROCESS_COMPLETE:String = "processComplete";
/** 曲変更時に放出されます. */
public static const SOUND_CHANGE:String = "soundChange";
/** 曲登録時に放出されます. */
public static const SOUND_REGISTER:String = "soundRegister";
/** 曲登録解除時に放出されます. */
public static const SOUND_DEREGISTER:String = "soundDeregister";
/** 音量変更時に放出されます. */
public static const VOLUME_CHANGE:String = "volumeChange";
/** 再生完了時に放出されます. */
public static const SOUND_COMPLETE:String = "soundComplete";
/**=================================================================*//**
* SoundManagerEventを生成します.
* @param type
* @param bubbles
* @param cancelable
*
* */
public function SoundManagerEvent( type:String, bubbles:Boolean = false, cancelable:Boolean = false ):void {
super( type, bubbles, cancelable );
}
/**=================================================================*//**
* overrided clone method
* @return
*/
override public function clone():Event {
return new SoundManagerEvent( type, bubbles, cancelable );
}
}
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFieldAutoSize;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
class Label extends Sprite {
private var txt:TextField;
private static var fontType:String = "Arial";
private var txtWidth:uint;
private var fontSize:uint;
public function Label(w:uint, s:uint) {
txtWidth = w;
fontSize = s;
draw();
}
private function draw():void {
txt = new TextField();
txt.width = txtWidth;
addChild(txt);
txt.autoSize = TextFieldAutoSize.CENTER;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = fontSize;
tf.align = TextFormatAlign.CENTER;
txt.defaultTextFormat = tf;
}
public function set text(param:String):void {
txt.text = param;
}
public function set textColor(param:uint):void {
txt.textColor = param;
}
}