medama

umhr_medamaあるスクリーンセイバーを見ながら 「この部分のロジックは簡単だよ」とか言ってしまったので簡単に作ってみた。
flvを読み込んで、1フレームごとに縦に長い短冊に書き込む。すると、映画のフィルムのような画像ができあがる。さらに短冊を上下に動かしている。

やっぱりこういう時は生っぽい映像のほうが面白い。

▼Wonderfl

▼ActionScript

/*
 * あるスクリーンセイバーを見ながら
 * 「この部分のロジックは簡単だよ」とか言ってしまったので
 * 簡単に作ってみた。
 * flvを読み込んで、1フレームごとに縦に長い短冊に書き込む。
 * すると、映画のフィルムのような画像ができあがる。
 * さらに短冊を上下に動かしている。
 * 
 * 
 * */
package 
{
	import flash.display.Sprite;
	import net.hires.debug.Stats;
	import flash.events.Event;
	import flash.events.NetStatusEvent;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.media.Video;
	import flash.display.BitmapData;
	import flash.display.Bitmap;
	import flash.system.Security;
	import flash.geom.Matrix;
	[SWF(backgroundColor="0x000000")]
	/**
	 * ...
	 * @author umhr
	 */
	public class Main extends Sprite
	{
		private var baseURL:String = "";
		private var count:int;
		private var bmp_data : BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight , false , 0);
		private var bmp_data0 : BitmapData = new BitmapData(140, 735 , false , 0);
		private var bmp_data1 : BitmapData = new BitmapData(120, 720 , false , 0);
		private var bmp_data2 : BitmapData = new BitmapData(80, 600 , false , 0);
		private var bmp_data3 : BitmapData = new BitmapData(60, 660 , false , 0);
		private var bmp_data4 : BitmapData = new BitmapData(40, 600 , false , 0);
		private var bmp_data5 : BitmapData = new BitmapData(20, 600 , false , 0);
		private var bmp : Bitmap = new Bitmap(bmp_data);
		private var stageWidth:int = stage.stageWidth;
		private var stageHeight:int = stage.stageHeight;
		
		function Main() {
			stage.scaleMode = "noScale";
			addChild(bmp);
			addChild(new Stats());
			
			
			//ビデオファイルを読み込み、再生。最後までいくと、頭に戻る。
			if(isMztmjp()){
			}else{
				baseURL = "http://mztm.jp/wonderfl/";
				Security.loadPolicyFile("http://mztm.jp/crossdomain.xml");
			}
			var connection:NetConnection = new NetConnection();
			connection.connect(null);
			var netStream:NetStream = new NetStream(connection);
			netStream.addEventListener (NetStatusEvent.NET_STATUS ,NET_STATUS);
			function NET_STATUS (event : NetStatusEvent):void {
				if(event.info.code == "NetStream.Play.Stop"){
					netStream.seek(0);
				}
			}
			netStream.client = new Object();
			netStream.play(baseURL+"medama.flv");
			var video_obj : Video = new Video(140,105);
			video_obj.attachNetStream(netStream);
			
			//書き込み処理を行い続ける。
			stage.addEventListener(Event.ENTER_FRAME,ENTER_FRAME);
			function ENTER_FRAME(e:Event):void {
				count++;
				//Macのマウス座標を補正するために。
				var _x:Number = Math.min(Math.max(stage.mouseX,0),stageWidth);
				var _y:Number = Math.min(Math.max(stage.mouseY,0),stageHeight);
				
				//適当に中央からの距離になるように。
				_y = (_y-stageHeight/2)/200;
				
				//短冊に画像を書き込む。
				bmp_data0.draw(video_obj,new Matrix(1,0,0,1,0,105*(count%7)));
				bmp_data1.draw(video_obj,new Matrix(0.858,0,0,0.858,0,90*(count%8)));
				bmp_data2.draw(video_obj,new Matrix(0.572,0,0,0.572,0,60*(count%10)));
				bmp_data3.draw(video_obj,new Matrix(0.429,0,0,0.429,0,45*(count%13)));
				bmp_data4.draw(video_obj,new Matrix(0.286,0,0,0.286,0,30*(count%18)));
				bmp_data5.draw(video_obj,new Matrix(0.143,0,0,0.143,0,15*(count%34)));
				
				//短冊を動かしながら書き込む
				bmp_data.lock();
				bmp_data.draw(bmp_data0,new Matrix(1,0,0,1,0,-(count*_y*(70-_x)/30)%105-105));
				bmp_data.draw(bmp_data1,new Matrix(1,0,0,1,141,-(count*_y*(200-_x)/30)%90-90));
				bmp_data.draw(bmp_data2,new Matrix(1,0,0,1,262,-(count*_y*(300-_x)/30)%60-60));
				bmp_data.draw(bmp_data3,new Matrix(1,0,0,1,343,-(count*_y*(370-_x)/30)%45-45));
				bmp_data.draw(bmp_data4,new Matrix(1,0,0,1,404,-(count*_y*(420-_x)/30)%30-30));
				bmp_data.draw(bmp_data5,new Matrix(1,0,0,1,445,-(count*_y*(450-_x)/30)%15-15));
				bmp_data.unlock();
			}
		}
		private function isMztmjp():Boolean{
			var _str:String = stage.loaderInfo.url;
			return (_str.substr(0,5) == "file:" || _str.indexOf("mztm.jp") > -1);
		}
	}
}