画面が粉々になるエフェクト

(サンプル一覧を表示する)

FlashDevelop を使って、画面が粉々になるエフェクトのテストをしてみました。

1 回画面をクリックすると粉々になります。
もう一度クリックすると元の画像に戻ります。
Flash の実行画面
画面が粉々になるエフェクト

Flashプレーヤーが入っていないか、JavaScriptが無効になっているようです。

Get Adobe Flash player

画面が粉々になるエフェクト
処理が重いので、10 フレーム/秒で表示しています。

ソースコード

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.geom.Point;
	
	/**
	 * 画面が粉々になるエフェクトのサンプル
	 * @author Hikipuro
	 */
	public class Main extends Sprite 
	{
		/**
		 * 埋め込み画像
		 */
		[Embed(source='../image/test001.png')]
		private var image:Class;
		
		/**
		 * 埋め込み画像を入れるビットマップ
		 */
		private var sourceBitmap:Bitmap;
		
		/**
		 * 表示用ビットマップデータ
		 */
		private var bitmapData:BitmapData;
		
		/**
		 * 粒を表現するオブジェクトの配列
		 */
		private var particles:Array;
		
		/**
		 * マウスが押された時 True
		 */
		private var mouseDownFlag:Boolean;
		
		/**
		 * 画面描画平滑化用フィルター
		 */
		private var blur:BlurFilter;
		
		/**
		 * コンストラクタ
		 */
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		/**
		 * 初期化メソッド
		 * @param	e
		 */
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			// 変数の初期化
			mouseDownFlag = false;
			particles = new Array();
			
			// 2x2 サイズの画面平滑化用フィルター初期化
			blur = new BlurFilter(2, 2, 1);
			
			// 埋め込み画像をビットマップに入れる
			sourceBitmap = Bitmap(new image);
			bitmapData = new BitmapData(320, 240);
			bitmapData.draw(sourceBitmap);
			
			// 画面のピクセルを全て粒のオブジェクトに入れる
			for (var y:int = 0; y < 240; y++)
			{
				for (var x:int = 0; x < 320; x++)
				{
					var particle:Particle;
					particle = new Particle(x, 
											y, 
											5 - Math.random() * 10, 
											Math.random() * -10,
											bitmapData.getPixel(x, y),
											200);
					particles.push(particle);
				}
			}
			
			// ビットマップデータを一旦クリア
			bitmapData = new BitmapData(320, 240);
			
			// 転送先ビットマップデータを画面に表示する
			addChild(new Bitmap(bitmapData));
			
			// イベントの登録
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
		}
		
		/**
		 * マウスが押された時のイベント
		 * @param	event
		 */
		private function onMouseDown(event:MouseEvent):void 
		{
			if (mouseDownFlag == false) {
				mouseDownFlag = true;
			} else {
				mouseDownFlag = false;
				bitmapData.draw(sourceBitmap);
				
				particles = new Array();
				for (var y:int = 0; y < 240; y++)
				{
					for (var x:int = 0; x < 320; x++)
					{
						var particle:Particle;
						particle = new Particle(x, 
												y, 
												5 - Math.random() * 10, 
												Math.random() * -10,
												bitmapData.getPixel(x, y),
												200);
						particles.push(particle);
					}
				}
			}
		}
		
		/**
		 * フレーム開始イベント
		 * @param	event
		 */
		private function onEnterFrame(event:Event):void 
		{
			// 一定時間が経った粒を消した後の配列
			var newParticles:Array = new Array();
			
			for each (var particle:Particle in particles)
			{
				// 画面が押された時は粒を移動
				if (mouseDownFlag == true)
				{
					particle.sy += 1;
					particle.x += particle.sx;
					particle.y += particle.sy;
				} else {
					particle.energy--;
				}
				
				// ピクセルを描画
				bitmapData.setPixel(particle.x, particle.y, particle.color);
				
				// 一定時間経ったものは画面からクリア
				if (particle.energy <= 0)
					continue;
				newParticles.push(particle);
			}
			
			// 粒リストを更新
			particles = newParticles;
			
			// 画面平滑化フィルターを適用
			bitmapData.applyFilter(bitmapData, bitmapData.rect, new Point(), blur);
		}
	}
	
}
		

Flash 10 以降の場合、BitmapData クラスに lock(), unlock() というメソッドが使用できます。それらのメソッドを、setPixel() メソッドの呼び出しの前後に入れることで、setPixel() の処理を高速化することができます。
詳しくは ActionScript リファレンスの、 BitmapData の項目をご覧になってください。

外部リンク