// forked from clockmaker's [Alternativa3D] Basic Template package { import flash.display.DisplayObject; import alternativ5.engine3d.materials.*; import alternativ5.engine3d.primitives.*; import alternativ5.engine3d.core.*; import alternativ5.types.Texture; import alternativ5.types.Point3D; import alternativ5.utils.* import flash.display.Sprite; import flash.display.BitmapData; import flash.display.Bitmap; import flash.events.Event; import flash.display.BlendMode [SWF(width = 465, height = 465, frameRate = 60, backgroundColor=0)] /** * Alternativa3D Sprite3Dを使っての、Particle処理 * * Particle処理、明日の為の第2歩w * * @narutohyper */ /** * Alternativa3D を簡単に扱うためのベーシックテンプレート * @author Yasu (clockmaker) */ public class SimpleDemo extends Sprite { public function SimpleDemo():void { // テンプレートを作成します var template:BasicTemplate = new BasicTemplate(); addChild(template); // FPS display launch FPS.init(stage); //Planeの作成 var plane:Plane=new Plane(1000,1000,10,10) plane.cloneMaterialToAllSurfaces(new FillMaterial(0x333333,1,BlendMode.NORMAL,1,0x666666)); template.scene.root.addChild(plane); plane.rotationX=MathUtils.toRadian(90) plane.y=21 var box:Object3D=new Object3D() template.scene.root.addChild(box); template.onPreRender = function():void { var temp:Particle=new Particle(this,template.scene,box,20,0xFF0000) //var rateX:Number = mouseY / stage.stageWidth; //template.camera.x += ( - 1000 * rateX - template.camera.x) * 0.1; // カメラの高さの座標を調整 // イージングの公式 対象の値 += (目標値 - 現在の値) * 減速率 var rateY:Number = mouseY / stage.stageHeight; template.camera.y += ( - 1000 * rateY - template.camera.y) * 0.1; // カメラの座標を中央に向かせる template.cameraContoller.lookAt(new Point3D()); } } } } import alternativ5.engine3d.materials.*; import alternativ5.engine3d.primitives.*; import alternativ5.engine3d.core.Sprite3D; import alternativ5.engine3d.physics.Collision import alternativ5.engine3d.physics.EllipsoidCollider import alternativ5.types.Texture; import alternativ5.types.Point3D; import alternativ5.types.Matrix3D; import alternativ5.types.Set; import flash.display.DisplayObject; import flash.display.Sprite; import flash.display.BitmapData; import flash.display.Bitmap; import flash.geom.Matrix import flash.filters.BlurFilter; import flash.filters.BitmapFilterQuality; import flash.display.BlendMode import flash.utils.Timer; import flash.events.TimerEvent; class Particle extends Sprite3D{ private var parent3D:Object3D; private var parentMc:Sprite; private var myTimer:Timer private var lastEffect:Boolean=false; //衝突感知用変数 private var collider:EllipsoidCollider; private var collision:Collision; private var nowPoint:Point3D; //現在の位置 private var newPoint:Point3D; //移動位置 private var speed:Point3D; //スピード private var deceleration:Number; //跳ね private var acceleration:Point3D; //加速 private var tempPoint:Point3D; public function Particle(mc:Sprite,scene:Scene3D,mc3D:Object3D,size:Number,color:uint,life:Number=2000):void { //----------------------------------------------- // スプライト3Dの作成 //----------------------------------------------- parentMc=mc parent3D=mc3D parent3D.addChild(this); // スプライト3Dを作成します this.material=makeMaterial(size,color); // 衝突用変数の登録 tempPoint= new Point3D(); nowPoint = new Point3D(); newPoint = new Point3D(); speed=new Point3D(0,-(20+(Math.random()*10)),0); //スピード deceleration=0.7; //減速 acceleration=new Point3D(Math.random()*1-0.5,1,Math.random()*2-0.5); //加速 //衝突判定に使う球の作成 collider = new EllipsoidCollider(scene,size,size,size); collision = new Collision(); collider.collisionSet=new Set() //衝突判定に使うFace(Mesh)の登録 //collider.collisionSet.add(this); this.coords=new Point3D() parentMc.addEventListener(Event.ENTER_FRAME, onRenderTick); //寿命 var timer:Timer = new Timer(life, 1); timer.start(); timer.addEventListener(TimerEvent.TIMER_COMPLETE, completeHandler); } private function del():void { parentMc.removeEventListener(Event.ENTER_FRAME, onRenderTick); parent3D.removeChild(this); delete this; } private function completeHandler(e:TimerEvent):void { lastEffect=true; } private function onRenderTick(e:Event):void { speed.add(acceleration); //現在地(nowPoint)から移動分(speed ベクトル)を移動させ、衝突を判定した上で、新しい移動座標をdestinationPointに返します collider.calculateDestination(nowPoint, speed ,newPoint); //何かに衝突したかどうかをcheckし、真なら衝突情報をcollisionに返す if (collider.getCollision (nowPoint, speed, collision)) { //衝突方向と進行方向の内積をとり、新たな方向を割り出す。 tempPoint=collision.normal tempPoint.multiply(2 * Point3D.dot(tempPoint, speed)); speed.subtract(tempPoint); speed.multiply(deceleration); } nowPoint=newPoint; this.coords = nowPoint; if (lastEffect) { this.material.alpha-=0.01 if (this.material.alpha<=0) { del() } } } private function makeMaterial(size:Number,color:uint):SpriteTextureMaterial { var tempSprite:Sprite = new Sprite() tempSprite.graphics.beginFill(color,1) tempSprite.graphics.drawCircle(0,0,size/2) tempSprite.graphics.beginFill(0xFFFFFFF,1) tempSprite.graphics.drawCircle(0,0,size/4) var filter:BlurFilter = new BlurFilter(5, 5,3); var myFilters:Array = [filter] tempSprite.filters = myFilters; // スプライト3D用のマテリアルを作成します var bmd:BitmapData = new BitmapData(tempSprite.width*2,tempSprite.height*2,true, 0x00000000) var mtr:Matrix=new Matrix(); mtr.translate(tempSprite.width, tempSprite.height) bmd.draw(tempSprite,mtr) var material:SpriteTextureMaterial = new SpriteTextureMaterial(new Texture(bmd),1,true,BlendMode.ADD); return material; } } /** * ソースが長くなるので、comment削除しちゃいました * コメントはフォーク元をご覧ください。 * BasicTemplate for Alternativa3D * Alternativa3Dを扱いやすくするためのテンプレートです * @author Yasu */ 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 flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageQuality; import flash.display.StageScaleMode; import flash.events.Event; class BasicTemplate extends Sprite{ public var scene:Scene3D; public var view:View; public var camera:Camera3D; public var cameraContoller:CameraController; private var _viewWidth:int; private var _viewHeight:int; private var _scaleToStage:Boolean; public function BasicTemplate(viewWidth:int=640, viewHeight:int=480, scaleToStage:Boolean = true) { _viewWidth = viewWidth; _viewHeight = viewHeight; _scaleToStage = scaleToStage; // Creating scene scene = new Scene3D(); scene.splitAnalysis = false; // not analysis for performance scene.root = new Object3D(); // Adding camera camera = new Camera3D(); camera.z = -1000; scene.root.addChild(camera); // camera contoller cameraContoller = new CameraController(this); cameraContoller.camera = camera; // set view view = new View(); view.camera = camera; addChild(view); // stage if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init); } protected function atInit():void {} private var _onInit:Function = function():void { }; public function get onInit():Function { return _onInit; } public function set onInit(value:Function):void { _onInit = value; } protected function atPreRender():void {} private var _onPreRender:Function = function():void{}; public function get onPreRender():Function { return _onPreRender; } public function set onPreRender(value:Function):void { _onPreRender = value; } protected function atPostRender():void { } protected var _onPostRender:Function = function():void{}; public function get onPostRender():Function { return _onPostRender; } public function set onPostRender(value:Function):void { _onPostRender = value; } public function startRendering():void { addEventListener(Event.ENTER_FRAME, onRenderTick); } public function stopRendering():void { removeEventListener(Event.ENTER_FRAME, onRenderTick); } public function singleRender():void { onRenderTick(); } private function init(e:Event = null):void { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; stage.quality = StageQuality.HIGH; stage.addEventListener(Event.RESIZE, onResize); onResize(null); startRendering(); atInit(); _onInit(); } private function onRenderTick(e:Event = null):void { atPreRender(); _onPreRender(); scene.calculate(); atPostRender(); _onPostRender(); } private function onResize(event:Event = null):void { if (_scaleToStage) { view.width = stage.stageWidth; view.height = stage.stageHeight; }else { view.width = _viewWidth; view.height = _viewHeight; } } } forked from: Alternativa3D Sprite3Dを使っての、Particle処理 明日の為の第2歩