Beautifl - Flash Gallery

Thumbnail : Alternativa3D and box2D = simple kaleidoscope
Alternativa3D and box2D = simple kaleidoscope
narutohyper 2010-02-09 MIT License

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

package {
	import flash.accessibility.Accessibility;
	/*
	Alternativa3D & box2D = simple kaleidoscope
	愚直な万華鏡
	別にAlternativa3Dじゃなくてもいいんだけど、複数のcameraとViewをテストしたかっただけ
	@narutohyper
	*/
	import alternativ5.engine3d.controllers.CameraController;
	import alternativ5.engine3d.core.Camera3D;
	import alternativ5.engine3d.core.Object3D;
	import alternativ5.engine3d.core.Scene3D;
	import alternativ5.engine3d.display.View;
	import alternativ5.types.Point3D;
	import alternativ5.utils.*

	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.events.Event;

	import flash.filters.BitmapFilter;
	import flash.filters.BitmapFilterQuality;
	import flash.filters.BlurFilter;

	import Box2D.Dynamics.b2Body;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Matrix;

	[SWF(width = 465, height = 465, frameRate = 30, backgroundColor=0)]
	public class SimpleDemo extends Sprite {

		private var view2d:b2View;
		private var kaleidoscope:Sprite;
		private var msk:Shape;

		public function SimpleDemo():void {
			
			FPS.init(stage); 

			// テンプレートを作成します
			// Creating scene
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.quality = StageQuality.HIGH;

			var scene:Scene3D = new Scene3D();
			scene.splitAnalysis = false; // not analysis for performance
			scene.root = new Object3D();

			kaleidoscope=new Sprite();
			kaleidoscope.x=465/2
			kaleidoscope.y=465/2
			addChild(kaleidoscope)

			msk=new Shape();
			msk.graphics.beginFill(0x000000)
			msk.graphics.drawCircle(x, y, 600/2);
			msk.x=465/2
			msk.y=465/2
			addChild(msk)
			kaleidoscope.mask=msk


			var mirrorArray:Array=[];

			var tempY:Array=[2.5,3, 1.5,1, 0.5,0, 1.5,2, 3.5,3];
			var mtr:Matrix=new Matrix()
			var radius:Number=100/Math.sin(60 * Math.PI / 180)
			
			for (var i:uint=0;i<34;i++) {
				mirrorArray.push(new mirrorView(scene));
				kaleidoscope.addChild(mirrorArray[i])

				mtr.createBox(
				(i%7%2)?1:-1,
				(Math.floor(i/7)%2)?-1:1,
				(i%7*60-180) * Math.PI / 180,
				i%7*100-300,
				((i>13)?-1:1)*radius*tempY[(i%7%2)+Math.floor(i/7)*2]
				)
				mirrorArray[i].transform.matrix=mtr;

			}

			view2d = new b2View(scene.root)

			for (var n:uint=0;n<20;n++) {
				view2d.CreateBeads((Math.random()*60+240) / b2View.SCALE, (Math.random()*60+240) / b2View.SCALE);
			}

			stage.addEventListener(Event.RESIZE, onResize);

			addEventListener(Event.ENTER_FRAME, onRendering);
			var pitch:Number=0.5
			function onRendering(e:Event):void {
				kaleidoscope.rotation+=pitch
				for (var i:uint=0;i<mirrorArray.length;i++) {
					mirrorArray[i].onRendering(pitch);
				}
				view2d.onRendering(pitch)
				scene.calculate();
			}

		}

		private function onResize(event:Event = null):void {
			kaleidoscope.x=stage.stageWidth/2;
			kaleidoscope.y=stage.stageHeight/2;

			msk.x=stage.stageWidth/2;
			msk.y=stage.stageHeight/2;

		}


	}

}



//cloneView
//真上からcameraで取った物をlocalなViewに表示。View自体は、DisplayObjectなので、加工が可能
//Matrixで変換して、並べる

import alternativ5.engine3d.controllers.CameraController;
import alternativ5.engine3d.core.Camera3D;
import alternativ5.engine3d.core.Scene3D;
import alternativ5.engine3d.display.View;
import alternativ5.types.Point3D;

import flash.display.Sprite;
import flash.display.GradientType;
import flash.display.Shape;
import flash.geom.Matrix;
import frocessing.color.ColorHSV;

class mirrorView extends Sprite{
	private var camera:Camera3D
	private var back:Shape
	private var hs:ColorHSV
	private var he:ColorHSV
	private var counter:Number=0

	public function mirrorView(scene:Scene3D) {
		//メインcameraをViewを作成
		camera = new Camera3D();
		camera.z = -650;
		scene.root.addChild(camera);
		camera.rotationZ=1*Math.PI/180
		
		// set view
		var view:View = new View();
		view.width=465
		view.height=465
		view.camera = camera;

		var sp:Sprite=new Sprite()
		sp.rotation=30

		hs=new ColorHSV();
		he=new ColorHSV();

		hs.h=0
		hs.s=0.05
		he.h=0
		he.s=0.3
		he.v=0.7

		back=new Shape()
		drawBack(0)

		sp.addChild(back);
		sp.addChild(view);
		view.x=-465/2
		view.y=-465/2

		this.addChild(sp);


	}

	public function onRendering(no:Number=1):void {
		counter+=0.5
		drawBack(counter)
		camera.rotationZ+=no*Math.PI/180
	}

	private function drawBack(no:Number):void {
		hs.h=no
		he.h=no
		back.graphics.clear();

		var colors:Array=new Array(hs.value32,he.value32)
		var alphas:Array=new Array(1,1)
		var ratios:Array=new Array(0,255)
		var matrix:Matrix=new Matrix()
		matrix.createGradientBox(200,200,Math.PI/2,-100,-100)
		back.graphics.beginGradientFill(GradientType.RADIAL ,colors, alphas, ratios, matrix)

		var radius:Number=100/Math.sin(60 * Math.PI / 180)

		var star_commands:Vector.<int> = new Vector.<int>(4, true);
		star_commands[0] = 1;
		star_commands[1] = 2;
		star_commands[2] = 2;
		star_commands[3] = 2;

		var star_coord:Vector.<Number> = new Vector.<Number>(8, true);
		star_coord[0]=Math.sin((120*0-30)*Math.PI/180)*radius
		star_coord[1]=Math.cos((120*0-30)*Math.PI/180)*radius
		star_coord[2]=Math.sin((120*1-30)*Math.PI/180)*radius
		star_coord[3]=Math.cos((120*1-30)*Math.PI/180)*radius
		star_coord[4]=Math.sin((120*2-30)*Math.PI/180)*radius
		star_coord[5]=Math.cos((120*2-30)*Math.PI/180)*radius
		star_coord[6]=Math.sin((120*0-30)*Math.PI/180)*radius
		star_coord[7]=Math.cos((120*0-30)*Math.PI/180)*radius
		back.graphics.lineStyle(2,0x333333)
		back.graphics.drawPath(star_commands, star_coord);
	}



}




import alternativ5.engine3d.primitives.Cone;
import alternativ5.engine3d.materials.FillMaterial;
import alternativ5.utils.MeshUtils
import alternativ5.engine3d.core.Object3D;

import Box2D.Collision.b2AABB;
import Box2D.Collision.Shapes.b2CircleDef;
import Box2D.Dynamics.b2Body;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2World;
import Box2D.Common.Math.b2Vec2;
import Box2D.Collision.Shapes.b2PolygonDef;

import flash.display.Sprite;
import flash.display.BlendMode;

import flash.events.Event;
import flash.geom.Point;


internal class b2View extends Sprite
{
	public static var SCALE:int = 100;

	private var _world:b2World;
	private var _gravity:b2Vec2;
	private var _doSleep:Boolean;
	private var _worldAABB:b2AABB;
	private var _body:b2BodyDef;
	private var _bodyPolygon:b2Body;
	
	private var _altView:Object3D
	private var donut:b2Body
	public function b2View(altView:Object3D) {
		
		_altView=altView;

		//	world;
		_worldAABB = new b2AABB();
		_worldAABB.lowerBound.Set( -500.0, -500.0);
		_worldAABB.upperBound.Set( 500.0, 500.0);

		_gravity = new b2Vec2(0.0, 6.5);
		_doSleep = true;
		_world = new b2World(_worldAABB, _gravity, _doSleep);
		_body = new b2BodyDef();
		_body.position.Set(0,0);
		_bodyPolygon = _world.CreateBody(_body);

		donut=CreateRegularPolygon(3,200 / SCALE, 50 / SCALE,new Point(240 / SCALE, 240/ SCALE));

	}
	
	public function onRendering(no:Number=1):void {
		_world.Step(1 / 60, 10);
		// Sprite の場所を更新する
		for (var b:b2Body = _world.GetBodyList(); b; b = b.GetNext()) {
			var sprite:Object3D = b.GetUserData() as Object3D;
			if (sprite){
				sprite.x = b.GetWorldCenter().x * SCALE-465/2;
				sprite.y = b.GetWorldCenter().y * SCALE-465/2;
				sprite.rotationZ = b.GetAngle();
			}

		}
		donut.SetXForm(donut.GetPosition(), donut.GetAngle() + no*Math.PI/180);
	}


	public function CreateRegularPolygon( num:int, radiusIn:Number, radiusWidth:Number,center:Point) : b2Body {
		var b2body:b2Body = _world.CreateBody(_body);
		var divisionAngle:Number = 360 / num;
		
		for ( var a:int = 0; a < num; a ++ ) {
			var angle:Number = divisionAngle * a * Math.PI / 180 ;
			var radiusOut:Number = radiusIn + radiusWidth;
			
			var cos:Number = Math.cos(angle);
			var sin:Number = Math.sin(angle);
			
			var rI:Point = new Point(cos * radiusIn, sin * radiusIn);
			var rO:Point = new Point(cos * radiusOut, sin * radiusOut);
			
			var angleN:Number = divisionAngle * (a+1) * Math.PI / 180  ;
			var cosN:Number = Math.cos(angleN);
			var sinN:Number = Math.sin(angleN);
			
			var rIN:Point = new Point(cosN * radiusIn, sinN * radiusIn);
			var rON:Point = new Point(cosN * radiusOut, sinN * radiusOut);
			
			var poly:b2PolygonDef = new b2PolygonDef();

			poly.vertexCount = 4;
			poly.vertices[0].Set(rI.x, rI.y);
			poly.vertices[1].Set(rO.x, rO.y);
			poly.vertices[2].Set(rON.x, rON.y);
			poly.vertices[3].Set(rIN.x, rIN.y );

			poly.density = 0;
			poly.restitution = 0;
			poly.friction = 0;
		
			b2body.CreateShape(poly);
		}
			
		b2body.SetXForm(new b2Vec2(center.x, center.y),0)
			
		return b2body;
	}


	//-----------------------------------------------------------
	//ビーズを作成する
	//-----------------------------------------------------------
	public function CreateBeads( x:Number, y:Number):void {

		var b2body:b2Body = _world.CreateBody(_body);

		var radius:Number=(Math.random() * 5 + 20)

		var beads:*
		var r:uint=15 * (Math.random()*0.7)
		var g:uint=15 * (Math.random()*0.7)
		var b:uint=15 * (Math.random()*0.7)
		var color:uint=(r<<20|r<<16|g<<12|g<<8|b<<4|b)
		var material:FillMaterial=new FillMaterial(color,1,BlendMode.OVERLAY);

		var beads3d:Cone;

		switch (Math.round(Math.random()*2)) {
			case 0:
				//四角の作成
				beads= new b2PolygonDef(); 
				beads.SetAsBox(radius / SCALE, radius / SCALE); 
				beads3d=new Cone(10,radius*Math.sqrt(2),radius*Math.sqrt(2),1,4,true);
				beads3d.rotationZ=-45*Math.PI/180
				break;

			case 1:
				//三角の作成
				beads= new b2PolygonDef(); 
				beads.SetAsBox(radius / SCALE, radius / SCALE); 
				var vertexCount:Number=3;
				beads.vertexCount = vertexCount;

				// 底辺の半分の長さと高さを設定  
				var h:Number=Math.tan(60 * Math.PI / 180) * radius;

				// 角の数を設定して頂点の位置を設定する  
				beads.vertices[0].Set(-1 * radius / SCALE, -1 * h / 2 / SCALE);
				beads.vertices[1].Set(radius / SCALE, -1 * h / 2 / SCALE);
				beads.vertices[2].Set(0, h / 2 / SCALE);

				beads3d=new Cone(10,radius,radius,1,3,true);
				beads3d.rotationZ=-30*Math.PI/180
				break;

			default:
				//丸の作成
				beads = new b2CircleDef();
				beads.radius = radius / SCALE;
				beads3d=new Cone(10,radius,radius,1,8,true);
				break;
		}

		beads3d.removeSurface('side')
		beads3d.removeSurface('bottom')
		MeshUtils.removeSingularFaces(beads3d);
		MeshUtils.removeIsolatedVertices(beads3d);
		beads3d.cloneMaterialToAllSurfaces(material);

		beads.density = 10;
		beads.restitution = 0.5;
		beads.friction = 0.3;

		b2body.CreateShape(beads);
		b2body.SetXForm(new b2Vec2(x ,y), 0);
		b2body.SetMassFromShapes();

		b2body.m_userData = new Object3D();
		b2body.GetUserData().x = b2body.GetWorldCenter().x;
		b2body.GetUserData().y = b2body.GetWorldCenter().y;
		b2body.GetUserData().addChild( beads3d);
		_altView.addChild(b2body.GetUserData());

	}



}