初めてのFrocessing


前に作った音量に反応して波紋を描くやつをFrocessingを使って書きなおしてみました。
とりあえず、HSVが簡単に使えるのがとてもよかった。

colorMode("hsv", 255, 1, 1);


これを書いておくと、それ以降の色の指定が色相:0〜255, 彩度:0〜1, 明度:0〜1で指定することができる。


そして、このように書くと円が描けます。

//線の色の設定
stroke(128, 1, 1);
//円を描く
circle(0, 0, 100);


今回出来上がったものはこんな感じ(BrowseをクリックしてMP3ファイルを選択して再生してください。音量注意)


すこし波紋が違うバージョン


ソース

package {
	import __AS3__.vec.Vector;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.media.SoundChannel;
	import flash.net.FileFilter;
	import flash.net.FileReference;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	
	import frocessing.display.F5MovieClip2D;
	
	import org.audiofx.mp3.MP3FileReferenceLoader;
	import org.audiofx.mp3.MP3SoundEvent;

	[SWF(backgroundColor=0x000000, width=512, height=612, frameRate = 30)]

	public class SoundTest6 extends Sprite
	{
		private var view:Bitmap;
		private var bmpData:BitmapData;
		private var canvas:F5MovieClip2D;
		private var channel:SoundChannel;
		private var vec:Vector.<Hamon>;
		private var r_count:int = 0;
		private var l_count:int = 255;
		private var browse_btn:TextField;
		private var file:FileReference;
		private var title:TextField;
		
		public function SoundTest6()
		{
			if(stage)
				init();
			else
				addEventListener(Event.ADDED_TO_STAGE, init);
				
		}
		
		private function init(event:Event = null):void{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			bmpData = new BitmapData(512, 512, false, 0x000000);
			view = new Bitmap(bmpData);
			addChild(view);
			
			browse_btn = new TextField();
			browse_btn.text = "Browse";
			browse_btn.autoSize = TextFieldAutoSize.LEFT;
			addChild(browse_btn);
			browse_btn.textColor = 0xFFFFFF;
			browse_btn.y = 580;
			browse_btn.addEventListener(MouseEvent.CLICK, onClick);
			
			title = new TextField();
			title.textColor = 0xFFFFFF;
			addChild(title);
			title.x = 200;
			title.y = 580;
			
			vec = new Vector.<Hamon>();
			
			//描画をするためのクラス
			canvas = new F5MovieClip2D();
			//どうような色で描くかを設定する
			//HSV色空間で色相:0〜255, 彩度:0〜1, 明度:0〜1に設定
			canvas.colorMode("hsv", 255, 1, 1);
			//描いた図を塗りつぶさないように設定
			canvas.noFill();
			
			canvas.blendMode = BlendMode.ADD;
			//canvas.filters = [new BlurFilter(5,5,1)];
		}
		
		private function onClick(event:MouseEvent):void{
			file = new FileReference();
			//呼び出すファイルの種類を制限する
            var filter:FileFilter = new FileFilter("mp3ファイル" ,"*.mp3");
			file.addEventListener(Event.SELECT, onSelect);
			
			//ブラウズ開始
			file.browse([filter]);
		}
		
		private function onSelect(event:Event):void{
			var loader:MP3FileReferenceLoader = new MP3FileReferenceLoader();
			loader.addEventListener(MP3SoundEvent.COMPLETE, onComplete);
			loader.getSound(file);
		}
		
		private function onComplete(event:MP3SoundEvent):void{
			if(channel != null) channel.stop();
			if(hasEventListener(Event.ENTER_FRAME)) removeEventListener(Event.ENTER_FRAME, loop_a);
			channel = event.sound.play();
			title.text = "Song Name: " + file.name.split(".")[0];
			title.autoSize = TextFieldAutoSize.LEFT;
			
			addEventListener(Event.ENTER_FRAME, loop_a);
		}
		
		private function loop_a(event:Event):void{
			var ham:Hamon;
			var right:Number = channel.rightPeak;
			var left:Number = channel.leftPeak;
			if(right > 0.1){
				ham = new Hamon();
				if(right > 0.98)
					ham.a_speed=0.015;
				else
					ham.a_speed=(1-right)*0.75;
				vec.push(ham);
				ham.x = Math.random()*256+256;
				ham.y = Math.random()*512;
				ham.radius = 1;
				ham.alpha = 0.8;
				ham.col = r_count;
				ham.speed = right*right*right*7.5;
				r_count = (r_count + 1)%255;
			}
			
			if(left > 0.1){
				ham = new Hamon()
				if(left > 0.98)
					ham.a_speed = 0.015;
				else
					ham.a_speed = (1-left)*0.75;
				vec.push(ham);
				ham.x = Math.random()*256;
				ham.y = Math.random()*512;
				ham.radius = 1;
				ham.alpha = 0.8;
				ham.col = l_count;
				ham.speed = left*left*left*7.5;
				l_count--;
				if(l_count<0)l_count=255;
			}
	
			canvas.clear();
			for(var i:int = vec.length-1; i > -1; i--){
				ham = vec[i];
				canvas.strokeWeight(ham.alpha*20);
				canvas.stroke(ham.col, 1, ham.alpha);
				canvas.circle(ham.x, ham.y, ham.radius);
				ham.radius += ham.speed;
				ham.alpha -= ham.a_speed;
	            if(ham.alpha <= 0)
	            	vec.splice(i, 1);
			}
			bmpData.fillRect(bmpData.rect, 0x000000);
			bmpData.draw(canvas);
		}
	}
}	

class Hamon{
	public var x:Number, y:Number;
	public var radius:Number;
	public var speed:Number;
	public var a_speed:Number;
	public var col:uint;
	public var alpha:Number;
}