パーティクルシステム その3 改良
「初めてのActionScript3.0」(O'REILLY)の7章モーションにパーティクルシステムがあり、
これが2Dで実現されていたので、これをpapervision3dを使用し3Dに変えてみました。
/**
* Copyright hankuro ( http://wonderfl.net/user/hankuro )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/m1dD
*/
package {
import flash.display.Sprite;
import flash.events.*;
[SWF(width = 540, height = 560, backgroundColor = 0x000000)]
/*
* 「初めてのActionScript3.0」(O'REILLY)の7章モーションにパーティクルシステムがあり、
* これが2Dで実現されていたので、これをpapervision3dを使用し3Dに変えてみました。
*/
public class Main extends Sprite{
public var num:Number = 0;
public var ballnum:Number = 10;
public var scr:Sprite = new Sprite();
public function Main() {
Const_data.mousex = mouseX;
Const_data.mousey = mouseY;
stage.addEventListener(Event.ENTER_FRAME, onLoop, false, 0, true);
for (var i:Number = 0; i < ballnum;i++){
var p:Part = new Part(Math.random() * 0xFFFFFF);
addChild(p);
}
var pl:Part_plane = new Part_plane();
addChild(pl);
scr.graphics.beginFill(0xFFFFFF, 0);
scr.graphics.drawRect(0, 0, 540, 560);
scr.graphics.endFill();
scr.buttonMode = true;
addChild(scr);
scr.addEventListener(MouseEvent.CLICK, onClick);
Const_data.balls = ballnum;
}
public function onClick(evt:MouseEvent):void {
removeEventListener(MouseEvent.CLICK, onClick);
removeChild(scr);
Const_data.open_sw = true;
}
private function onLoop(evt:Event):void {
Const_data.mousex = mouseX;
Const_data.mousey = mouseY;
}
}
}
import flash.events.Event;
import flash.geom.Point;
import org.papervision3d.core.effects.view.ReflectionView;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.view.BasicView;
import org.papervision3d.materials.shadematerials.GouraudMaterial;
import org.papervision3d.materials.utils.MaterialsList;
class Part extends ReflectionView{
private var _xpos:Number = 0;
private var _ypos:Number = 0;
private var _zpos:Number = 0;
public var vx:Number;
public var vy:Number;
public var vz:Number;
public var ball:Sphere;
private var pointLight:PointLight3D;
private var bounce:Number = -0.7;
// public var radius:Number = Math.random() * 35;
public var radius:Number = 25;
public function Part(col:uint) {
super(540,560,false, false,"free");
surfaceHeight = -30;
camera.z = -500;
vx = Math.random() * 10 - 3;
vy = Math.random() * 10 - 3;
vz = Math.random() * 10 - 3;
Const_data.b_obj.push(this);
pointLight = new PointLight3D();
pointLight.x = -200;
pointLight.y = 200;
pointLight.z = -90;
scene.addChild(pointLight);
ball = new Sphere(new GouraudMaterial(pointLight, col, 0x000000), radius, 8, 6);
scene.addChild(ball);
ball.x = Math.random() * 10 - 5;
ball.y = Math.random() * 10 - 5;
ball.z = Math.random() * 10 - 5;
ball.alpha = .08;
addEventListener(Event.ENTER_FRAME,onRun , false, 0, true);
}
private function onRun(evt:Event):void {
if (b_check.ball_check(this)) {
var xx:Number = ball.x;
var yy:Number = ball.y;
var zz:Number = ball.z;
scene.removeChild(ball);
ball = new Sphere(new GouraudMaterial(pointLight, Math.random() * 0xFFFFFF , 0x000000), radius, 8, 6);
ball.y = xx;
ball.y = yy;
ball.z = zz;
scene.addChild(ball);
}
_xpos += vx;
_ypos += vy;
_zpos += vz;
if(_xpos > Const_data.right && !Const_data.open_sw)
{
_xpos = Const_data.right ;
vx *= -1;
}
else if(_xpos < Const_data.left && !Const_data.open_sw)
{
_xpos = Const_data.left;
vx *= -1;
}else {
ball.x = _xpos;
}
if (_ypos < Const_data.bottom)
{
_ypos = Const_data.bottom;
vy *= -1;
}
else if(_ypos > Const_data.top)
{
_ypos = Const_data.top;
vy *= -1;
}else {
ball.y = _ypos;
}
if(_zpos > Const_data.front && !Const_data.open_sw )
{
_zpos = Const_data.front;
vz *= -1;
}
else if(_zpos < Const_data.back && !Const_data.open_sw)
{
_zpos = Const_data.back;
vz *= -1;
}else {
ball.z = _zpos;
}
var mousePos:Point = new Point(Const_data.mousex, Const_data.mousey);
mousePos.offset( -Const_data.stage_width / 2, -Const_data.stage_height / 2);
ball.rotationY += mousePos.x / 20;
singleRender();
if ( ball.z < -300 || ball.z > 400 ) {
removeEventListener(Event.ENTER_FRAME, onRun);
parent.removeChild(this);
}
}
}
import flash.display.BitmapData;
import flash.display.Shape;
import flash.events.Event;
import flash.geom.Point;
import org.papervision3d.core.effects.view.ReflectionView;
import org.papervision3d.core.geom.Lines3D;
import org.papervision3d.core.geom.renderables.Line3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.geom.Vertices3D;
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.materials.MovieMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.view.BasicView;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.lights.PointLight3D;
import org.papervision3d.materials.shadematerials.GouraudMaterial;
import org.papervision3d.materials.ColorMaterial
import org.papervision3d.materials.special.LineMaterial;
class Part_plane extends ReflectionView {
private var pointLight:PointLight3D;
private var plane:Plane;
private var lines:Lines3D;
private var cube:Cube;
public function Part_plane() {
super(540, 560, false, false,"free");
surfaceHeight = -30;
camera.z = -500;
var wiMaterial:WireframeMaterial = new WireframeMaterial(0xFFFFFF, 1);
var sh1:Shape = new Shape();
sh1.graphics.beginFill(0x0000FF, 0.2);
sh1.graphics.drawRect(0, 0, 200, 170);
sh1.graphics.endFill();
var sh2:Shape = new Shape();
sh2.graphics.beginFill(0x00FFFF, 0.2);
sh2.graphics.drawRect(0, 0, 200, 170);
sh2.graphics.endFill();
var movieMat1:MovieMaterial = new MovieMaterial(sh1, true, true, false);
var movieMat2:MovieMaterial = new MovieMaterial(sh2, true, true, false);
var materials:MaterialsList = new MaterialsList();
materials.addMaterial(movieMat1, "top");
materials.addMaterial(movieMat1, "bottom");
materials.addMaterial(movieMat1, "front");
materials.addMaterial(movieMat1, "back");
materials.addMaterial(movieMat2, "right");
materials.addMaterial(movieMat2, "left");
cube = new Cube(materials, 270, 270, 190, 1);
cube.y = 85;
scene.addChild(cube);
addEventListener(Event.ENTER_FRAME, onRun , false, 0, true);
singleRender();
}
private function onRun(evt:Event):void {
var mousePos:Point = new Point(Const_data.mousex, Const_data.mousey);
mousePos.offset( -Const_data.stage_width / 2, -Const_data.stage_height / 2);
cube.rotationY += mousePos.x / 20;
if (Const_data.open_sw) {
scene.removeChild(cube);
removeEventListener(Event.ENTER_FRAME, onRun );
}
singleRender();
}
}
class b_check
{
public static function ball_check(p:Part):Boolean
{
var tx:Number;
var ty:Number;
var tz:Number;
var ax:Number;
var ay:Number;
var az:Number;
var angle:Number;
var dist:Number;
var minDist:Number;
var dx:Number;
var dy:Number;
var dz:Number;
var spring:Number = 0.01;
var part0:Part = p;
var rtn:Boolean = false;
for (var j:uint = 0; j < Const_data.balls; j++)
{
var part1:Part = Const_data.b_obj[j];
if(part0 != part1){
dx = part1.ball.x - part0.ball.x;
dy = part1.ball.y - part0.ball.y;
dz = part1.ball.z - part0.ball.z;
// trace ("x "+dx+" y " +dy+ " z "+dz);
dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
minDist = part0.radius + part1.radius;
if(dist < part0.radius + part1.radius)
{
// trace("hit");
rtn = true;
angle = Math.atan2(dy, dx);
tx = part0.ball.x + dx / dist * minDist;
ty = part0.ball.y + dy / dist * minDist;
tz = part0.ball.z + dz / dist * minDist
ax = (tx - part1.ball.x) * spring;
ay = (ty - part1.ball.y) * spring;
az = (tz - part1.ball.z) * spring;
part0.vx -= ax;
part0.vy -= ay;
part0.vz -= az;
part1.vx += ax;
part1.vy += ay;
part1.vz += az;
}
}
}
return rtn;
}
}
class Const_data
{
public static var xp:Number;
public static var yp:Number;
public static var mousex:Number;
public static var mousey:Number;
public static const stage_width:int = 540;
public static const stage_height:int = 400;
public static const right:int = 100;
public static const left:int = -100;
public static const top:int = 150;
public static const bottom:int = 20;
public static const front:Number = 90;
public static const back:Number = -100;
public static var center_width:int = stage_width / 2;
public static var center_height:int = stage_height / 2;
public static var open_sw:Boolean = false;
public static var b_obj:Array = new Array();
public static var balls:Number;
}