Beautifl - Flash Gallery

Thumbnail : 【Pixel3D練習】整列したりランダムしたり
【Pixel3D練習】整列したりランダムしたり
yooKo 2009-10-10 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/**
 * 
 * @author yooKo@selflash
 * @version 1.2 
 * Pixel3Dの練習
 * Click毎にPixelが整列したりランダムになったりします。
 * 
 * コード整理してないから汚すぎ
 * あまりまじまじと見ないでください
 * 
 * 2009/10/9 ちょっと整理。軽く説明追加。でもまだ冗長な感じが否めない・・
 * removeAllpixels → removePixel3D に変更して並び替えの際徐々に
 * pixelを削除するようにした
 * 
 * new しまくってた箇所配列につっこんで使いまわした
 **/
package {
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.filters.BitmapFilterQuality;
	import flash.geom.ColorTransform;
	import flash.geom.Point;
	import flash.utils.Timer;
	import flash.utils.getTimer;

	import org.papervision3d.core.effects.BitmapLayerEffect;
	import org.papervision3d.core.effects.BitmapColorEffect;
	import org.papervision3d.core.effects.utils.BitmapClearMode;
	import org.papervision3d.core.geom.Pixels;
	import org.papervision3d.core.geom.renderables.Pixel3D;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.view.layer.BitmapEffectLayer;	
	import net.hires.debug.Stats;

	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]

	public class Pixel3D_test extends BasicView {
		private var _pixels:Pixels;
		private var _particles:Array/*Particle*/ = [];
		private var _pixel3Ds:Array/*Pixel3D*/ = [];
			
		private var _startTime:int;
		private var _rotateX:Number = 0;
		private var _rotateY:Number = 0;
		private var _flg:int = 0;
		
		private const SQUARE_LENGTH:int = 100;
		private const INTERVAL:int = 8;
		private const RADIUS:Number = SQUARE_LENGTH * .5;
		private const SPEED:Number = .1;
		private const COLOR_LIST:Array/*int*/ = [0xFF33CCFF, 0xFF3399FF, 0xFF88FF33]
		
		//========================================================================
		// コンストラクタ	
		//========================================================================
		public function Pixel3D_test() {			
			super(0, 0, true, true);
			
			if (!stage)
                addEventListener(Event.ADDED_TO_STAGE, init);
            else
                init();
        }        
		//========================================================================
		// 初期化。 おおまかな流れは
		// 1.BlurやColorのエフェクトをする為のBitmapEffectLayerの生成。
		//
		// 2.Pixelsの生成。2Dの時のCamvas:BitmapDataに相当するみたい。
		//   これにremoveAllpixels,removePixel3DしたりaddPixel3Dしたりして描画をする。
		//
		// 3.Particleを生成
		//
		// 4.毎回Pixelの描画を更新する
		//
		// 5.クリックイベントの追加
		//========================================================================
        private function init(e:Event = null):void {
            removeEventListener(Event.ADDED_TO_STAGE, init);
		
			var _layer:BitmapEffectLayer = new BitmapEffectLayer(viewport, stage.stageWidth, stage.stageHeight, true, 0, BitmapClearMode.CLEAR_PRE, false);
			viewport.containerSprite.addLayer(_layer);
            //_layer.drawCommand.blendMode = BlendMode.ADD;
			_layer.addEffect(new BitmapColorEffect(1, 1, 1, .9));
			_layer.addEffect(new BitmapLayerEffect(new BlurFilter(4, 4, BitmapFilterQuality.LOW), false)); 
			
			camera.z = - 150;

			_pixels = new Pixels(_layer);
			scene.addChild(_pixels);

			//createSquare3D();
			square3D();
			
			
			addEventListener(MouseEvent.CLICK, onClickHandler);
						
			startRendering();
			
			addChild(new Stats());
		}
		//========================================================================
		// ClickHandler
		// なんか知らないけど _flg = !_flg がうまくいかなかったから冗長なコードになってしまった
		//========================================================================
		public function onClickHandler(e:MouseEvent = null):void {
			(_flg <= 2) ? _flg++ : _flg = 0;
			switch (_flg) {
				case 0: square3D();
				break;
				case 1: ramdamSquare3D();
				break;
			}
		}
		//========================================================================
		// きちんと並べられた立方体にする	
		// 冗長な感じがするが数学が得意じゃないのでこんな感じ・・
		//========================================================================
		private function square3D():void {
			_startTime = getTimer();
			var i:int = 0;
			for (var _x:int = 0; _x < SQUARE_LENGTH; _x += INTERVAL) {
				for (var _y:int = 0; _y < SQUARE_LENGTH; _y += INTERVAL) {
					for (var _z:int = 0; _z < SQUARE_LENGTH; _z += INTERVAL) {
						var p:Particle = _particles[i]||new Particle();
							p.tx = _x - RADIUS;
							p.ty = _y - RADIUS;
							p.tz = _z - SQUARE_LENGTH * .5;
						if (_z == 0 || SQUARE_LENGTH - _z < INTERVAL ) {
							p.c = COLOR_LIST[0];
							if(!_particles[i]) _particles[i] = p;
							i++;
							continue;
						}else if (_x == 0 || SQUARE_LENGTH - _x < INTERVAL) {
							p.c = COLOR_LIST[1];
							if(!_particles[i]) _particles[i] = p;
							i++;
							continue;
						}else if (_y == 0 || SQUARE_LENGTH - _y < INTERVAL) {
							p.c = COLOR_LIST[2];
							if(!_particles[i]) _particles[i] = p;
							i++;
							continue;
						}
					}
				}
			}
		}
        //========================================================================
		// ランダムな立方体にする
		// Particle3Dライブラリのサンプル内にあったランダムな立方体のアルゴリズムをそのまま流用。
		//========================================================================
		private function ramdamSquare3D():void {
			_startTime = getTimer();
			
			for (var i:int = 0; i < _particles.length; i++) {
				var p:Particle = _particles[i];
				var s1:Number = 2 * Math.floor(Math.random() * 2) - 1;
				var s2:Number = 2 * Math.random() - 1;
				var s3:Number = 2 * Math.random() - 1;
				var sArray:Array/*Number*/ = [s1, s2, s3];
				var shift:int = Math.floor(Math.random() * 3);				
				p.tx = SQUARE_LENGTH * .5 * sArray[shift];
				p.ty = SQUARE_LENGTH * .5 * sArray[(shift + 1) % 3];
				p.tz = SQUARE_LENGTH * .5 * sArray[(shift + 2) % 3];
			}
		}
		
		//========================================================================
		// 描画の更新	
		// particleの座標x,y,zを自身が持つ座標プロパティtx,ty,tzに常にイージング
		//========================================================================
		override protected function onRenderTick(event:Event = null):void { 
			renderer.renderScene(scene, _camera, viewport);

			_rotateX += (-viewport.containerSprite.mouseX - _rotateX) * 0.1;
			_rotateY += (-viewport.containerSprite.mouseY - _rotateY) * 0.1;
			_pixels.rotationY = _rotateX;
			_pixels.rotationX = _rotateY;
		
			var wait:Number;
			var now:int = getTimer();		
			
			//_pixels.removeAllpixels(); これを使えば一気に消せる
			for (var i:int = 0; i < _particles.length; i++) {
				var p:Particle = _particles[i];						
				wait = (1 - (p.ty - SQUARE_LENGTH *.6)) * 20;
				if (_startTime + wait > now) continue ; 
				if(_pixel3Ds[i])_pixels.removePixel3D(_pixel3Ds[i]);
				if (Math.abs(p.tx - p.x) < .5 && Math.abs(p.ty - p.y) < .5 && Math.abs(p.tz - p.z) < .5) {
					p.x = p.tx;
					p.y = p.ty;
					p.z = p.tz;
				}else {
					p.x += (p.tx - p.x) * SPEED;
					p.y += (p.ty - p.y) * SPEED;
					p.z += (p.tz - p.z) * SPEED;
				}				
				var px:Pixel3D;
				if (_pixel3Ds[i]) {
					px = _pixel3Ds[i];
					px.color = p.c;
					px.x = p.x;
					px.y = p.y;
					px.z = p.z;
				}else {
					px = new Pixel3D(p.c, p.x, p.y, p.z);
					_pixel3Ds[i] = px;
				}
				_pixels.addPixel3D(px);
			}
		}
	}
}

//========================================================================
// 座標情報を保持するクラス		
//========================================================================
class Particle {
	public var x:Number = 0;
	public var y:Number = 0;
	public var z:Number = 0;
	public var tx:Number = 0;
	public var ty:Number = 0;
	public var tz:Number = 0;
	public var c:int = 0x000000;
}