SoundVisualizer(5)
FP11.3で見るとうまく動かないっぽいのでFP11.2以下推奨
/**
* Copyright okoi ( http://wonderfl.net/user/okoi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/yEha
*/
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.StatusEvent;
import flash.geom.Matrix;
[SWF(width="465",height="465",frameRate="60")]
/**
* ...
* @author okoi
*/
public class Main extends Sprite
{
public static const WIDTH:int = 465;
public static const HEIGHT:int = 465;
private var _mp3player:SimpleMP3Player;
private var _progressbar:ProgressBar;
private var _visualizer:Visualizer3;
public function Main():void
{
if (stage)
init();
else
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
graphics.beginFill(0);
var mat:Matrix = new Matrix();
mat.createGradientBox(WIDTH, HEIGHT, Math.PI / 2);
graphics.beginGradientFill("linear", [0, 0x333333, 0], [1, 1, 1], [0, 128, 255], mat);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
_visualizer = new Visualizer3();
addChild(_visualizer);
_mp3player = new SimpleMP3Player(startLoad, completedLoad);
_mp3player.x = WIDTH / 2;
addChild(_mp3player);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function startLoad():void
{
completedLoad();
_progressbar = new ProgressBar();
_progressbar.x = WIDTH / 2;
_progressbar.y = HEIGHT / 2;
addChild(_progressbar);
}
private function completedLoad():void
{
if (_progressbar)
{
removeChild(_progressbar);
_progressbar = null;
}
}
private function enterFrameHandler(e:Event):void
{
if (_mp3player.isPlaying())
{
_visualizer.update(_mp3player.spectrumData);
}
}
}
}
import flash.system.Capabilities;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.media.SoundTransform;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.IOErrorEvent;
import flash.events.SecurityErrorEvent;
import flash.events.ProgressEvent;
import flash.net.FileReference;
import flash.net.FileFilter;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundMixer;
import flash.utils.ByteArray;
import flash.filters.BlurFilter;
import flash.filters.ColorMatrixFilter;
import flash.geom.ColorTransform;
import flash.geom.Point;
/**
* ...
* @author okoi
*/
class Visualizer3 extends Sprite
{
private static const SPECTRUM_NUM:int = 512;
private var _back:BitmapData;
private var _front:Sprite;
private var _leftSpectrumFactorRecordList:Vector.<SpectrumFactorRecord>;
private var _rightSpectrumFactorRecordList:Vector.<SpectrumFactorRecord>;
private var _time:int;
private static const ONESIDE_WAVELINE_COUNT:int = 8;
private var _leftWaveList:Array /*WaveLine*/;
private var _rightWaveList:Array /*WaveLine*/;
private var _radius:Number = 0;
private var _colorMatrixFilter:ColorMatrixFilter;
private var _blurFilter:BlurFilter;
public function Visualizer3()
{
var i:int;
_back = new BitmapData(Main.WIDTH, Main.HEIGHT, true, 0);
addChild(new Bitmap(_back));
_front = new Sprite();
_leftSpectrumFactorRecordList = new Vector.<SpectrumFactorRecord>(SPECTRUM_NUM / 2, true);
_rightSpectrumFactorRecordList = new Vector.<SpectrumFactorRecord>(SPECTRUM_NUM / 2, true);
for (i = 0; i < SPECTRUM_NUM / 2; i++)
{
_leftSpectrumFactorRecordList[i] = new SpectrumFactorRecord();
_rightSpectrumFactorRecordList[i] = new SpectrumFactorRecord();
}
_time = 0;
_leftWaveList = [];
_rightWaveList = [];
for (i = 0; i < ONESIDE_WAVELINE_COUNT; i++)
{
_leftWaveList.push(new WaveLine(120));
_rightWaveList.push(new WaveLine(120));
}
_colorMatrixFilter = new ColorMatrixFilter([1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0.99, 0]);
_blurFilter = new BlurFilter(8, 8, 3);
}
public function update(spectrumData:SpectrumData):void
{
var i:int;
var position:int = spectrumData.soundPosition;
//--------------------------------------
// analyze
//--------------------------------------
var listSize:int = SPECTRUM_NUM / 2;
var totalConsecutiveOverAverage:int = 0;
var totalValue:Number = 0;
for (i = 0; i < SPECTRUM_NUM; i++)
{
if (i < listSize)
{
_leftSpectrumFactorRecordList[i].addRecord(spectrumData.soundPosition, spectrumData.data[i]);
}
else
{
_rightSpectrumFactorRecordList[i - listSize].addRecord(spectrumData.soundPosition, spectrumData.data[i]);
}
totalValue += spectrumData.data[i];
}
_radius *= 0.5;
_radius += totalValue;
var wavePower:Number = 0;
var wavePowerList:Array = new Array(ONESIDE_WAVELINE_COUNT);
var rightWavePointList:Array = new Array(ONESIDE_WAVELINE_COUNT);
for (i = 0; i < ONESIDE_WAVELINE_COUNT; i++)
{
wavePowerList[i] = 0;
rightWavePointList[i] = 0;
}
var waveIndex:int = 0;
listSize = _leftSpectrumFactorRecordList.length;
for (i = 0; i < listSize; i++)
{
waveIndex = int(i / (listSize / ONESIDE_WAVELINE_COUNT));
wavePowerList[waveIndex] += _leftSpectrumFactorRecordList[i].getLatestValue();
}
listSize = _rightSpectrumFactorRecordList.length;
for (i = 0; i < listSize; i++)
{
waveIndex = int(i / (listSize / ONESIDE_WAVELINE_COUNT));
rightWavePointList[waveIndex] += _rightSpectrumFactorRecordList[i].getLatestValue();
}
for (i = 0; i < ONESIDE_WAVELINE_COUNT; i++)
{
var angle:Number = ((360 / ONESIDE_WAVELINE_COUNT) * i + _time);
var y:Number = Math.sin(angle * Math.PI / 180) * _radius;
_leftWaveList[i].update(new Point(0, Main.HEIGHT / 2 + y), new Point(Main.WIDTH, Main.HEIGHT / 2 + y), wavePowerList[i], angle);
_rightWaveList[i].update(new Point(Main.WIDTH, Main.HEIGHT / 2 - y), new Point(0, Main.HEIGHT / 2 - y), rightWavePointList[i], angle);
}
//--------------------------------------
// draw
//--------------------------------------
var g:Graphics = _front.graphics;
g.clear();
for (waveIndex = 0; waveIndex < ONESIDE_WAVELINE_COUNT; waveIndex++)
{
var wave:WaveLine = _leftWaveList[waveIndex];
var points:Array /*Point*/ = wave.getDividePoints();
g.lineStyle(0.5, 0xFFFFFF, wave.alpha);
for (i = 0; i < points.length; i++)
{
if (i == 0)
g.moveTo(points[i].x, points[i].y);
else
g.lineTo(points[i].x, points[i].y);
}
wave = _rightWaveList[waveIndex];
points = wave.getDividePoints();
g.lineStyle(0.5, 0xFFFFFF, wave.alpha);
for (i = 0; i < points.length; i++)
{
if (i == 0)
g.moveTo(points[i].x, points[i].y);
else
g.lineTo(points[i].x, points[i].y);
}
}
_back.lock();
_back.applyFilter(_back, _back.rect, new Point(), _colorMatrixFilter);
_back.applyFilter(_back, _back.rect, new Point(), _blurFilter);
_back.draw(_front, null, new ColorTransform(0, 0, 0, 0, 150, 150, 255, 70), "add");
_back.unlock();
_time++;
}
}
/**
*
* @author okoi
*/
class WaveLine
{
private var _length:Number = 0; // start,end間の長さ
private var _divideCount:int;
private var _divideVec:Point; // start-endを分割したときのベクトル
private var _dividePoints:Array /*Point*/; //
private var _powerVec:Point;
private var _noise:BitmapData;
private var _noiseOffset:Array /*Point*/;
private var _noiseSeed:int;
private var _alpha:Number = 0;
//-------------------------------------------------
// getter / setter
//-------------------------------------------------
public function get alpha():Number
{
return _alpha;
}
public function WaveLine(divideCount:int)
{
var i:int;
_divideCount = divideCount;
_noise = new BitmapData(512, 10, true, 0);
_noiseOffset = [new Point(), new Point()];
_noiseSeed = int(Math.random() * 256);
}
public function getLength():Number
{
return _length;
}
public function getDividePoints():Array /*Point*/
{
return _dividePoints;
}
private function _updateNoise():void
{
_noiseOffset[0].x -= 3; // 最初のオクターブだけスクロール
_noiseOffset[1].x += 0;
_noise.perlinNoise(30, // x 方向で使用する周波数(幅)
0, // y 方向で使用する周波数(高さ)
1, // 重ねる回数 やりすぎると重い
_noiseSeed, // 適当な整数
true, // 補正があり、タイリング可能なノイズ生成を試みる(第09引数でスクロール時に効果的)
false, // フラクタルノイズの有無。falseの場合、炎や海の波のような視覚効果
8, // (8 | 4 | 2 | 1), // ノイズ生成のチャンネル
false, // グレースケール化
_noiseOffset // 第03引数で決めた各レイヤーをスクロールするためのPoint型の配列データ
);
}
public function update(startPoint:Point, endPoint:Point, wavePower:Number, waveAngle:Number):void
{
var dx:Number = endPoint.x - startPoint.x;
var dy:Number = endPoint.y - startPoint.y;
// ラインの長さ更新
_length = Math.sqrt(dx * dx + dy * dy);
// 分割した時のベクトル更新
_divideVec = new Point(dx, dy);
_divideVec.normalize(_length / _divideCount);
var normal:Point = new Point(dx / _length, dy / _length);
//x' = x * cosθ - y * sinθ
//y' = x * sinθ + y * cosθ
_powerVec = new Point(normal.x * 0 - normal.y * 1, normal.x * 1 + normal.y * 0); // 90度回転
// ノイズ更新
_updateNoise();
_dividePoints = [];
var waveAngleSin:Number = -Math.sin(waveAngle * Math.PI / 180);
for (var i:int = 0; i <= _divideCount; i++)
{
var sweep:Number = Math.sin(Math.PI * (i / _divideCount)) * waveAngleSin;
var flick:Number = _noise.getPixel32((i * 1) % 512, 1);
var a:Number = (((flick >> 24) & 0xff) - 128);
var power:Number = a * sweep * wavePower * 0.1;
var px:Number = startPoint.x + _divideVec.x * i + _powerVec.x * power;
var py:Number = startPoint.y + _divideVec.y * i + _powerVec.y * power;
_dividePoints.push(new Point(px, py));
}
// アルファ値
_alpha *= 0.05;
_alpha += wavePower;
}
}
/**
* ...
* @author okoi
*/
class SpectrumValueHistory
{
private static const SIZE:int = 60; // 記録量
private var _data:Vector.<Number>;
private var _average:Number;
private var _countConsecutiveOverAverage:int = 0;
//-------------------------------------------
// getter / setter
//-------------------------------------------
public function get average():Number
{
return _average;
}
public function get countConsecutiveOverAverage():int
{
return _countConsecutiveOverAverage;
}
public function SpectrumValueHistory()
{
_data = new Vector.<Number>(SIZE, true);
for (var i:int = 0; i < SIZE; i++)
_data[i] = 0;
_average = 0;
}
/**
* 記録を追加する、古いデータは削除される
* @param value
*/
public function add(value:Number):void
{
var i:int;
for (i = SIZE - 1; i > 0; i--)
{
_data[i] = _data[i - 1];
}
_data[0] = value;
// 平均値計算
_average = 0;
for (i = 0; i < SIZE; i++)
_average += _data[i];
_average = _average / SIZE;
if (_data[0] > _average)
{
_countConsecutiveOverAverage += 1;
}
else
{
_countConsecutiveOverAverage = 0;
}
}
/**
* 最新の値を取得する
*/
public function get latestValue():Number
{
return _data[0];
}
/**
* 履歴の平均値を取得する
*/
public function get averageValue():Number
{
var ret:Number = 0;
for (var i:int = 0; i < SIZE; i++)
ret += _data[i];
return ret / SIZE;
}
/**
* 履歴の前半と後半を比べて、急激に値が増加していたらtrueを返す
* @return
*/
public function isSteepUp():Boolean
{
var i:int;
var first:Number = 0;
var last:Number = 0;
for (i = 0; i < SIZE / 2; i++)
{
first += _data[SIZE / 2 + i];
last += _data[i];
}
first /= (SIZE / 2);
last /= (SIZE / 2);
return ((last / first) > 100);
}
/**
* 最新の値が平均値以上かどうかを取得できる
* @return
*/
public function isLatestValueUpperAverage():Boolean
{
return (latestValue > averageValue);
}
}
/**
* ...
* @author ...
*/
class SpectrumData
{
private var _data:Array;
private var _soundPosition:int;
//------------------------------------------
// getter / setter
//------------------------------------------
public function get data():Array
{
return _data;
}
public function get soundPosition():int
{
return _soundPosition;
}
public function SpectrumData(data:Array, soundPosition:int)
{
_data = data;
_soundPosition = soundPosition;
}
}
/**
* ...
* @author ...
*/
class SpectrumFactorRecord
{
private static const SIZE:int = 60;
private var _record:Vector.<Number>;
private var _average:Number;
private var _latestSoundPosition:int;
private var _countConsecutiveOverAverage:int = 0;
//--------------------------------------------
// getter / setter
//--------------------------------------------
public function get average():Number
{
return _average;
}
public function get nowSoundPosition():int
{
return _latestSoundPosition;
}
public function get countConsecutiveOverAverage():int
{
return _countConsecutiveOverAverage;
}
//--------------------------------------------
//--------------------------------------------
public function SpectrumFactorRecord()
{
_record = new Vector.<Number>(SIZE, true);
for (var i:int = 0; i < SIZE; i++)
_record[i] = 0;
_latestSoundPosition = 0;
}
/**
* 記録を追加する、古いデータは削除される
* @param value
*/
public function addRecord(soundPosition:int, value:Number):void
{
var i:int;
for (i = SIZE - 1; i > 0; i--)
{
_record[i] = _record[i - 1];
}
_record[0] = value;
_latestSoundPosition = soundPosition;
// 平均値計算
_average = 0;
for (i = 0; i < SIZE; i++)
_average += _record[i];
_average = _average / SIZE;
if (_record[0] > _average)
{
_countConsecutiveOverAverage += 1;
}
else
{
_countConsecutiveOverAverage = 0;
}
}
/**
* 最新の記録を取得
* @return {Number}
*/
public function getLatestValue():Number
{
return _record[0];
}
/**
* 最新の値が平均値以上かどうかを取得できる
* @return
*/
public function isLatestValueUpperAverage():Boolean
{
return (getLatestValue() > _average);
}
}
/**
* ...
* @author okoi
*/
class SimpleMP3Player extends Sprite
{
public static const WIDTH:int = 450;
public static const HEIGHT:int = 50;
public static const ANM_NONE:int = 0;
public static const ANM_FADEIN:int = 1;
public static const ANM_FADEOUT:int = 2;
private var _bytes:ByteArray;
private var _fr:FileReference;
private var _sound:Sound = null;
private var _soundChannel:SoundChannel = null;
private var _pausePosition:Number;
private var _loadStartCallback:Function /*():void*/;
private var _loadEndCallback:Function /*():void*/;
private var _btn_play:Button;
private var _flg_play:Boolean = false;
private var _btn_load:Button;
private var _flg_loading:Boolean;
private var _titleBoard:TitleBoard;
private var _animationId:int;
private var _playerDisp:Boolean;
private var _waveBuffer:Array;
private var _fftBuffer:Array;
private var _spectrumData:SpectrumData;
//----------------------------------------------------
// getter / setter
//----------------------------------------------------
public function get waveBuffer():Array
{
return _waveBuffer;
}
public function get fftBuffer():Array
{
return _fftBuffer;
}
public function get spectrumData():SpectrumData
{
return _spectrumData;
}
public function SimpleMP3Player(loadstartcallback:Function, loadendcallback:Function)
{
_fr = new FileReference();
_fr.addEventListener(Event.SELECT, FileSelectHandler);
_fr.addEventListener(ProgressEvent.PROGRESS, ProgressHandler);
_fr.addEventListener(Event.COMPLETE, FileLoadCompleteHandler);
_fr.addEventListener(IOErrorEvent.IO_ERROR, FileLoadIOErrorHandler);
_fr.addEventListener(SecurityErrorEvent.SECURITY_ERROR, FileLoadSecurityError);
_flg_loading = false;
_bytes = new ByteArray();
_loadStartCallback = loadstartcallback;
_loadEndCallback = loadendcallback;
CreateUI();
_animationId = ANM_NONE;
setPlayerDisplay(true, false);
_waveBuffer = GetSpectrumData(false);
_fftBuffer = GetSpectrumData(true);
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function OpenFileSelectDialog():void
{
var filter:FileFilter = new FileFilter("mp3 file", "*.mp3");
_fr.browse([filter]);
}
private function FileSelectHandler(e:Event):void
{
_fr.load();
_flg_loading = true;
_btn_play.Selectable(false);
_titleBoard.SetTitle("");
if (_loadStartCallback != null)
_loadStartCallback();
}
private function ProgressHandler(e:ProgressEvent):void
{
}
private function FileLoadCompleteHandler(e:Event):void
{
_flg_loading = false;
_pausePosition = 0;
_sound = new Sound();
_sound.loadCompressedDataFromByteArray(_fr.data, _fr.data.length);
SetTitleBoardText(_fr.name);
resetSoundChannel();
_btn_play.Selectable(true);
_flg_play = true;
onClickPlayButton();
if (_loadEndCallback != null)
_loadEndCallback();
}
private function FileLoadIOErrorHandler(e:IOErrorEvent):void
{
_flg_loading = false;
_sound = null;
changePlayButton(false);
_btn_play.Selectable(false);
}
private function FileLoadSecurityError(e:SecurityErrorEvent):void
{
_flg_loading = false;
_sound = null;
changePlayButton(false);
_btn_play.Selectable(false);
}
private function resetSoundChannel():void
{
if (_soundChannel != null)
{
_soundChannel.stop();
_soundChannel.removeEventListener(Event.SOUND_COMPLETE, SoundCompleteHandler);
_soundChannel = null;
}
_titleBoard.SetScrollFlag(false);
}
/**
* サウンドの再生、再開を行う
*/
private function play():void
{
if (_sound)
{
_soundChannel = _sound.play(_pausePosition);
_soundChannel.addEventListener(Event.SOUND_COMPLETE, SoundCompleteHandler);
_pausePosition = 0;
_titleBoard.SetScrollFlag(true);
var trans:SoundTransform = new SoundTransform(0.5);
_soundChannel.soundTransform = trans;
}
}
/**
* サウンドの一時停止を行う
*/
private function pause():void
{
if (_soundChannel)
{
_pausePosition = _soundChannel.position;
resetSoundChannel();
}
}
private function SoundCompleteHandler(e:Event):void
{
_pausePosition = 0;
resetSoundChannel();
play();
}
public function GetSpectrumData(FFTMode:Boolean = false):Array
{
var i:int;
var buf:Array = new Array(512);
if (!_soundChannel)
{
for (i = 0; i < 512; i++)
buf[i] = 0;
return buf;
}
SoundMixer.computeSpectrum(_bytes, FFTMode, 0);
_bytes.position = 0;
for (i = 0; i < 512; i++)
buf[i] = _bytes.readFloat();
return buf;
}
/**
* 再生中かどうかを受け取る
* @return
*/
public function isPlaying():Boolean
{
return _flg_play;
}
public function enterFrameHandler(e:Event):void
{
_waveBuffer = GetSpectrumData(false);
_fftBuffer = GetSpectrumData(true);
var position:int = 0;
if (_soundChannel != null)
{
position = _soundChannel.position;
}
_spectrumData = new SpectrumData(_fftBuffer, position);
// 右クリックアニメーション
if (_animationId == ANM_FADEIN)
{
this.alpha += 0.05;
if (this.alpha >= 1)
stopAnimation();
}
else if (_animationId == ANM_FADEOUT)
{
this.alpha -= 0.05;
if (this.alpha <= 0)
stopAnimation();
}
}
//--------------------------------------------------------------------
//
// アニメーション関連
//
//--------------------------------------------------------------------
/**
* プレイヤーの表示非表示状態を設定する
* @param flag
*/
public function setPlayerDisplay(flag:Boolean, animation:Boolean = true):void
{
_playerDisp = flag;
this.mouseEnabled = flag;
this.mouseChildren = flag;
if (animation)
startAnimation((_playerDisp) ? ANM_FADEIN : ANM_FADEOUT);
else
{
stopAnimation();
if (_playerDisp)
this.alpha = 1;
else
this.alpha = 0;
}
}
/**
* プレイヤーの表示状態かどうかを受け取る
*
* @return
*/
public function isPlayerDisplay():Boolean
{
return _playerDisp;
}
/**
* アニメーションの再生を開始する
* @param animeId
*/
public function startAnimation(animeId:int):void
{
if (_animationId != ANM_NONE)
stopAnimation();
_animationId = animeId;
}
/**
* アニメーションの再生を終了する
*/
public function stopAnimation():void
{
if (_animationId == ANM_FADEIN)
this.alpha = 1;
if (_animationId == ANM_FADEOUT)
this.alpha = 0;
_animationId = ANM_NONE;
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
private function CreateUI():void
{
var g:Graphics;
g = graphics;
// 背景
CreatePlayButton();
CreateLoadButton();
CreateTitleBoard();
}
private function CreatePlayButton():void
{
_btn_play = new Button(58, 18, "play", onClickPlayButton);
_btn_play.x = -35;
_btn_play.y = 20;
_btn_play.Selectable(false);
addChild(_btn_play);
}
/**
* 再生ボタンが押された
*/
private function onClickPlayButton():void
{
_flg_play = (_flg_play) ? false : true;
changePlayButton(_flg_play);
if (_flg_play)
{
play();
}
else
{
pause();
}
}
private function changePlayButton(flg:Boolean):void
{
if (flg)
{
_btn_play.setLabelText("stop");
}
else
{
_btn_play.setLabelText("play");
}
}
/**
* 曲ロードボタンを作成
*/
private function CreateLoadButton():void
{
_btn_load = new Button(58, 18, "load", onClickLoadButton);
_btn_load.x = 35;
_btn_load.y = 20;
addChild(_btn_load);
}
/**
* 曲ロードボタンが押された
*/
private function onClickLoadButton():void
{
if (_flg_loading)
return;
OpenFileSelectDialog();
}
private function CreateTitleBoard():void
{
_titleBoard = new TitleBoard();
_titleBoard.x = -TitleBoard.WIDTH / 2;
_titleBoard.y = 40;
addChild(_titleBoard);
}
private function SetTitleBoardText(text:String):void
{
_titleBoard.SetTitle(text);
}
}
class TitleBoard extends Sprite
{
public static const WIDTH:int = 300;
public static const HEIGHT:int = 20;
private var text:TextField;
private var _mask:Shape;
private var _flg_scroll:Boolean;
public function TitleBoard()
{
this.alpha = 0.5;
graphics.lineStyle(1, 0x474a4d);
graphics.beginFill(0xc0c6c9);
graphics.drawRect(0, 0, WIDTH, HEIGHT);
graphics.endFill();
var tf:TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 14;
tf.color = 0xFFFFFF;
tf.align = TextFormatAlign.CENTER;
text = new TextField();
text.autoSize = "left";
text.selectable = false;
text.defaultTextFormat = tf;
text.x = WIDTH / 2;
addChild(text);
_mask = new Shape();
_mask.graphics.beginFill(0);
_mask.graphics.drawRect(0, 0, WIDTH, HEIGHT);
_mask.graphics.endFill();
this.mask = _mask;
addChild(_mask);
_flg_scroll = false;
addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
}
public function SetTitle(title:String):void
{
text.text = title;
text.x = WIDTH / 2 - text.textWidth / 2;
}
private function EnterFrameHandler(e:Event):void
{
//if ( text.textWidth >= WIDTH ) {
if (_flg_scroll)
{
text.x -= 1;
if (text.x < -text.textWidth)
{
text.x = WIDTH;
}
}
}
public function SetScrollFlag(flg:Boolean):void
{
_flg_scroll = flg;
}
}
/**
* 汎用ボタンクラス
* @author okoi
*/
class Button extends Sprite
{
private var label:TextField;
private var _onclick:Function /*():void*/ = null;
private var _width:Number;
private var _height:Number;
private var _selectable:Boolean;
public function Button(w:Number, h:Number, text:String, onclick:Function)
{
graphics.lineStyle(1, 0x474a4d);
graphics.beginFill(0x2b2b2b);
graphics.drawRect(-w / 2, -h / 2, w, h);
graphics.endFill();
_width = w;
_height = h;
var tf:TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 12;
tf.color = 0xFFFFFF;
tf.align = TextFormatAlign.CENTER;
label = new TextField();
label.mouseEnabled = false;
label.autoSize = "center";
label.multiline = false;
label.defaultTextFormat = tf;
label.selectable = false;
label.text = text;
label.x = -w / 2;
label.y = -h / 2;
label.width = w;
label.height = h;
addChild(label);
this._onclick = onclick;
this.buttonMode = true;
this.addEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
}
private function MouseDownHandler(e:MouseEvent):void
{
this.removeEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
this.addEventListener(MouseEvent.MOUSE_UP, MouseUpHandler);
this.addEventListener(MouseEvent.ROLL_OUT, RollOutHandler);
ChangeColor(true);
}
private function MouseUpHandler(e:MouseEvent):void
{
this.removeEventListener(MouseEvent.MOUSE_UP, MouseUpHandler);
this.removeEventListener(MouseEvent.ROLL_OUT, RollOutHandler);
this.addEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
ChangeColor(false);
if (_onclick != null)
{
_onclick();
}
}
private function RollOutHandler(e:MouseEvent):void
{
this.removeEventListener(MouseEvent.MOUSE_UP, MouseUpHandler);
this.removeEventListener(MouseEvent.ROLL_OUT, RollOutHandler);
this.addEventListener(MouseEvent.MOUSE_DOWN, MouseDownHandler);
ChangeColor(false);
}
private function ChangeColor(press:Boolean):void
{
graphics.clear();
graphics.lineStyle(1, 0x474a4d);
if (press)
{
graphics.beginFill(0x727171);
}
else
{
graphics.beginFill(0x2b2b2b);
}
graphics.drawRect(-_width / 2, -_height / 2, _width, _height);
graphics.endFill();
}
public function setLabelText(text:String):void
{
label.text = text;
}
public function Selectable(flg:Boolean):void
{
_selectable = flg;
this.mouseChildren = flg;
this.mouseEnabled = flg;
if (!flg)
{
ChangeColor(false);
this.alpha = 0.5;
}
else
{
this.alpha = 1;
}
}
}
/**
* ...
* @author okoi
*/
class ProgressBar extends Sprite
{
private var _mask:Shape;
private var text:TextField;
private var ct:int;
private static const PARTICLE_LIFE:int = 60;
private var particleList: /*Object*/Array;
private var _rate:Number = 0;
public function ProgressBar()
{
ct = 0;
particleList = [];
var format:TextFormat = new TextFormat();
format.font = "Arial";
format.bold = true;
format.color = 0xFFFFFF;
text = new TextField();
text.defaultTextFormat = format;
text.text = "LOADING";
text.selectable = false;
text.x = -text.textWidth / 2;
text.y = -text.textHeight / 2;
addChild(text);
_mask = new Shape();
_mask.graphics.beginFill(0);
_mask.graphics.drawRect(-100, -25, 200, 50);
_mask.graphics.endFill();
this.mask = _mask;
addChild(_mask);
addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
}
public function Destroy():void
{
removeEventListener(Event.ENTER_FRAME, EnterFrameHandler);
}
private function EnterFrameHandler(e:Event):void
{
var g:Graphics = graphics;
g.clear();
if (int(Math.random() * 10) == 0)
AddParticle();
for (var i:int = particleList.length - 1; i >= 0; i--)
{
g.lineStyle(2, 0xFFFFFF, 0.5 - (1 - particleList[i].life / PARTICLE_LIFE) * 0.5);
particleList[i].y += particleList[i].vy;
particleList[i].life -= 1;
g.drawCircle(particleList[i].x, particleList[i].y, particleList[i].radius);
if (particleList[i].life == 0)
{
particleList.splice(i, 1);
}
}
if (ct % 4 == 0)
text.alpha = 0;
else
text.alpha = 0.5;
ct++;
}
private function AddParticle():void
{
var particle:Object = new Object();
particle.x = Math.random() * 100 - 50;
particle.y = 35;
particle.radius = Math.random() * 5 + 5;
particle.vy = (Math.random() * 1 + 0.5) * -1;
particle.life = PARTICLE_LIFE;
particleList.push(particle);
}
public function set rate(val:Number):void
{
_rate = val;
}
}