forked from: Ballの回転
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix3D;
import flash.geom.Vector3D;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class Main extends Sprite
{
private var points:Vector.<Ball>; //Balls
private static const POINT_NUM:int = 200; //Ballの数
private static const RANGE_X:int = 250; //Ball範囲
private static const RANGE_Y:int = 250; //Ball範囲
private static const RANGE_Z:int = 250; //Ball範囲
private var rotateX:Number = 0;
private var rotateY:Number = 0;
private var rotateZ:Number = 0;
private var scaleManagerObj:ScaleManager;
private var radiusAddParam:Number = 0;
public function Main()
{
this.init();
}
private function init():void
{
this.createPoints(); //Ball作成
this.rotateChange(); //回転
this.scaleManagerObj = new ScaleManager(this);
this.addEventListener(Event.ENTER_FRAME , onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
if (Math.random() > 0.95)
{
this.rotateChange();
this.scaleManagerObj.changeScale();
this.radiusAddParam = 20;
}
else if(this.radiusAddParam > 0)
{
this.radiusAddParam--;
}
this.rotate(); //回転
this.startMove(); //Ball移動の目標地点変更
this.move(); //Ballの移動
this.draw(); //Ballを描画
}
/**
* 回転
*/
public function rotateChange():void
{
this.rotateX = (Math.random() * 10) - 5;
this.rotateY = (Math.random() * 10) - 5;
this.rotateZ = (Math.random() * 10) - 5;
}
/**
* 回転する
*/
private function rotate():void
{
var mat:Matrix3D = new Matrix3D();
mat.appendRotation(this.rotateX, Vector3D.X_AXIS);
mat.appendRotation(this.rotateY, Vector3D.Y_AXIS);
this.x = this.stage.stageWidth / 2;
this.y = this.stage.stageHeight / 2;
this.z = 0;
var i:int;
for (i = 0; i < POINT_NUM; i++)
{
var point:Ball = this.points[i];
var vectorPoint:Vector3D = mat.transformVector(point as Vector3D);
point.x = vectorPoint.x;
point.y = vectorPoint.y;
point.z = vectorPoint.z;
}
}
/**
* Ballを作る
*/
private function createPoints():void
{
var i:int;
this.points = new Vector.<Ball>();
for (i = 0; i < POINT_NUM; i++)
{
var x:int = (Math.random() * RANGE_X) - RANGE_X / 2;
var y:int = (Math.random() * RANGE_Y) - RANGE_Y / 2;
var z:int = (Math.random() * RANGE_Z) - RANGE_Z / 2;
var point:Ball = new Ball();
point.x = x;
point.y = y;
point.z = z;
point.radius = 1;
point.initTween(); //Tweenオブジェクトを生成
this.points.push(point);
}
}
/**
* Ballの目標地点を変更する
*/
private function startMove():void
{
var i:int;
for (i = 0; i < this.points.length; i++)
{
if (Math.random() > 0.999)
{
var point:Ball = this.points[i];
var x:int = (Math.random() * RANGE_X) - RANGE_X / 2;
var y:int = (Math.random() * RANGE_Y) - RANGE_Y / 2;
var z:int = (Math.random() * RANGE_Z) - RANGE_Z / 2;
point.tweenObj.setTargetPoint(x,y,z);
}
}
}
/**
* Ballを目標地点へ移動する
*/
private function move():void
{
var i:int;
for (i = 0; i < this.points.length; i++)
{
var point:Ball = this.points[i];
point.tweenObj.move();
}
}
/**
* Ballを表示する
*/
private function draw():void
{
this.graphics.clear();
//中央の大きいBallを一時的に作成
var centerBall:Ball = new Ball();
var centerBallNum:int = 0;
var centerBallRadius:int = 2000;
centerBall.z = 1;
centerBall.radius = centerBallRadius;
centerBall.initTween();
this.points.push(centerBall);
//Zソートする
this.points = this.points.sort(compare);
//描画する
var i:int;
for (i = 0; i < this.points.length; i++)
{
var point:Ball = this.points[i];
//色
var color8:int = int((point.z + (RANGE_Z)) * 0.6);
var color:int = color8 << 16 | color8 << 8 | color8;
if (color < 0) color = 0;
//直径
var radius:Number = Math.abs(((point.z * point.radius) * 0.6 - (RANGE_Z / 2)) * 0.1);
if (point.radius != centerBallRadius) radius += this.radiusAddParam ;
this.graphics.beginFill(color, 1);
this.graphics.drawCircle(point.x, point.y, radius);
this.graphics.endFill();
//中央の大きいBallの配列番号を保持
if (point.radius == centerBallRadius) centerBallNum = i;
}
//中央の大きいBallを削除
this.points.splice(centerBallNum, 1);
}
/**
* Zソート
*/
private function compare( x:Ball, y:Ball ):Number
{
return y.z - x.z;
}
}
}
/**
* Tweenクラスを持つ
*/
import flash.geom.Vector3D;
class Ball extends Vector3D
{
public var tweenObj:Tween;
public var radius:Number = 0;
public function initTween():void
{
this.tweenObj = new Tween(this);
}
}
/**
* Tweenクラス
*/
import flash.utils.Timer;
class Tween
{
//移動する対象
private var vector3dObj:Ball;
//Tweenタイマー
private var timer:Timer = new Timer(10 * 1000, 1);
//目標地点
private var targetX:Number = 0;
private var targetY:Number = 0;
private var targetZ:Number = 0;
//速度
private var speedX:Number = 0;
private var speedY:Number = 0;
private var speedZ:Number = 0;
//加速度
private var acX:Number = 0;
private var acY:Number = 0;
private var acZ:Number = 0;
private static const FRICTION:Number = 0.95;
private static const FIRST_VELOCITY:int = 20;
public function Tween(vec:Ball)
{
this.vector3dObj = vec;
this.targetX = this.vector3dObj.x;
this.targetY = this.vector3dObj.y;
this.targetZ = this.vector3dObj.z;
}
public function setTargetPoint(x:int, y:int, z:int):void
{
if (this.timer.running)
{
//タイマー動いていたら
this.timer.stop();
}
this.timer.reset();
//目標地点セット
this.targetX = x;
this.targetY = y;
this.targetZ = z;
//初速セット
this.speedX = (Math.random() * FIRST_VELOCITY) - FIRST_VELOCITY / 2;
this.speedY = (Math.random() * FIRST_VELOCITY) - FIRST_VELOCITY / 2;
this.speedZ = (Math.random() * FIRST_VELOCITY) - FIRST_VELOCITY / 2;
this.timer.start();
}
public function move():void
{
//タイマー動いていたら
if (this.timer.running)
{
//目標地点までの差
var difX:Number = this.targetX - this.vector3dObj.x;
var difY:Number = this.targetY - this.vector3dObj.y;
var difZ:Number = this.targetZ - this.vector3dObj.z;
this.speedX += difX * 0.01;
this.speedY += difY * 0.01;
this.speedZ += difZ * 0.01;
this.speedX *= FRICTION;
this.speedY *= FRICTION;
this.speedZ *= FRICTION;
this.vector3dObj.x += this.speedX;
this.vector3dObj.y += this.speedY;
this.vector3dObj.z += this.speedZ;
}
}
}
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.events.Event;
class ScaleManager
{
private var main:Main;
public var targetScale:Number = 1.2;
private static const FRIC:Number = 0.8;
private var speed:Number = 0.1;
private var timer:Timer = new Timer(1000 * 1 , 1);
private var isAddEvent:Boolean = false;
public function ScaleManager(main:Main)
{
this.main = main;
}
public function changeScale():void
{
if (!this.isAddEvent)
{
this.main.addEventListener(Event.ENTER_FRAME , changeScaling);
}
if (!this.timer.running)
{
this.targetScale = Math.random() * 1 + 0.8;
this.timer.start();
this.timer.addEventListener(TimerEvent.TIMER_COMPLETE , onTimerComplete);
}
this.isAddEvent = true;
}
private function changeScaling(e:Event):void
{
var ac:Number = this.targetScale - this.main.scaleX;
this.speed += ac;
this.speed *= FRIC;
this.main.scaleX = this.main.scaleY = this.main.scaleX + this.speed;
}
private function onTimerComplete(te:TimerEvent):void
{
this.isAddEvent = false;
this.main.removeEventListener(Event.ENTER_FRAME , changeScaling);
this.timer.removeEventListener(TimerEvent.TIMER_COMPLETE , onTimerComplete);
this.timer.stop();
this.timer.reset();
}
}