forked from: with EFLA
forked from with EFLA (diff: 132)
ActionScript3 source code
/**
* Copyright monodreamer ( http://wonderfl.net/user/monodreamer )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/uPlb
*/
// forked from Blue_fox_and_red_grape's with EFLA
// forked from codeonwort's transition 3D rotatable
// forked from codeonwort's transition 3D
// forked from codeonwort's forked from: transition
// forked from Nyarineko's transition
package {
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.geom.ColorTransform;
import flash.display.Shape;
import flash.geom.Vector3D
import flash.geom.Point;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.display.Graphics;
import flash.filters.BlurFilter
import net.hires.debug.Stats;
[SWF(width = "465", height = "465", backgroundColor = "0xffffff", frameRate = "60")]
public class Main extends Sprite {
private const M_WIDTH:Number = 465;
private const M_HEIGH:Number = 465;
private const OX:Number = 465 / 2;
private const OY:Number = 465 / 2;
private const V:Number = 2
private const VR:Number = V * Math.PI/180;
private const OBJ_MAX:Number = 15;
private var max:uint = 5;
private var amax:uint = 0;
private var _canvas:BitmapData
private var _bmp:Bitmap;
private var first:Particle;
private var _tmp:BitmapData;
//------------------------------------------------------
//コンストラクタ
//------------------------------------------------------
public function Main() {
graphics.beginFill(0)
graphics.drawRect(0, 0, M_WIDTH, M_HEIGH)
graphics.endFill()
_canvas = new BitmapData(M_WIDTH, M_HEIGH, true, 0 );
_tmp = _canvas.clone();
_bmp = new Bitmap(_canvas);
addChild(_bmp)
addChild(new Stats());
// Particle.originX = OX, Particle.originY = OY
init();
stage.addEventListener(MouseEvent.CLICK,onClick);
stage.addEventListener(Event.ENTER_FRAME,enterframeHandler);
}
//------------------------------------------------------
//初期化
//------------------------------------------------------
private function init():void {
first = new Particle
var p:Particle = first;
for(var i:uint = 0;i < max;i++){
p.phi = Math.PI * 2 * i / max; //360 * i / max
p.theta = Math.random() * Math.PI //180 * i / max
p.phiVel = VR
p.radius = 1
p.thetaVel = 0
p.color = Math.random() * 0x404040 + 0xC0C0C0;
if(i != max - 1){
p.next = new Particle
p = p.next;
}
}
}
private var zero:Point = new Point
private var blur:BlurFilter = new BlurFilter(8, 8)
private function enterframeHandler(e:Event):void {
//_canvas.fillRect(_canvas.rect, 0x0 );
update();
}
private function onClick(e:MouseEvent):void {
_canvas.lock();
_canvas.fillRect(_canvas.rect, 0x0);
_canvas.unlock();
init();
}
// Extremely Fast Line Algorithm : http://wonderfl.net/c/A69m
private function efla(bmd:BitmapData, x:int, y:int, x2:int, y2:int, color:uint):void {
var shortLen:int = y2 - y;
var longLen:int = x2 - x;
if (!longLen) if (!shortLen) return;
var i:int, id:int, inc:int;
var multDiff:Number;
// bmd.lock();
// TODO: check for this above, swap x/y/len and optimize loops to ++ and -- (operators twice as fast, still only 2 loops)
if ((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31)) {
if (shortLen < 0) {
inc = -1;
id = -shortLen & 3;
} else {
inc = 1;
id = shortLen & 3;
}
multDiff = !shortLen ? longLen : longLen / shortLen;
if (id) {
bmd.setPixel32(x, y, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
}
}
}
while (i != shortLen) {
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
bmd.setPixel32(x + i * multDiff, y + i, color);
i += inc;
}
} else {
if (longLen < 0) {
inc = -1;
id = -longLen & 3;
} else {
inc = 1;
id = longLen & 3;
}
multDiff = !longLen ? shortLen : shortLen / longLen;
if (id) {
bmd.setPixel32(x, y, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
if (--id) {
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
}
}
}
while (i != longLen) {
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
bmd.setPixel32(x + i, y + i * multDiff, color);
i += inc;
}
}
//bmd.unlock();
}
/////////////////////////////////////////
private var ran:Number
private var p:Particle
private var cnt:uint
private var zRate:Number, pos:Pos, track:Array;
private var i:int, len:int
private var prevX:int, prevY:int;
private var b:uint;
// private var sh:Shape = new Shape;
// private var g:Graphics = sh.graphics;
private var _ct:ColorTransform = new ColorTransform(1,1,1,.5);
private function update():void {
p = first
cnt = 0
// rotate
// Particle.theta0 += (mouseX-OX)/OX*2
// Particle.phi0 += (mouseY-OY)/OY*2
_rx += (mouseX-OX) / OX * VR;
_ry += (mouseY-OY) / OY * VR;
_canvas.lock();
_canvas.colorTransform(_canvas.rect, _ct);
while(p){
cnt++;
if(p.radius > 400){
p.reset();
// p = p.next;
continue;
}
ran = Math.random();
if(ran < 0.1){
p.phiVel = p.thetaVel = 0;
p.radVel = V;
}else if(ran < 0.2){
p.phiVel = -VR;
p.radVel = p.thetaVel = 0;
}else if(ran < 0.3){
p.phiVel = VR;
p.radVel = p.thetaVel = 0;
}else if(ran < 0.4){
p.thetaVel = VR
p.phiVel = p.radVel = 0
}else if(ran < 0.5){
p.thetaVel = -VR
p.phiVel = p.radVel = 0
}else if(ran < 0.504 && amax < OBJ_MAX){
var newP:Particle = new Particle();
newP.phi = p.phi
newP.theta = p.theta
newP.radius = p.radius
newP.color = Math.random() * 0x404040 + 0xC0C0C0;
if(p.phiVel == 0){
newP.phiVel = 0
newP.radVel = 1
}else{
newP.phiVel = Math.random() < 0.5 ? -VR : VR
newP.radVel = 0
}
newP.next = p.next;
p.next = newP;
}
p.radius += p.radVel
p.phi += p.phiVel
p.theta += p.thetaVel
p.saveCurrentCoord()
track = p.track;
var pr:Number, pc:uint = p.color, rp:Number, rt:Number, nx:Number, ny:Number;
//g.moveTo(track[0].x, track[0].y)
pos = track[0];
pr = pos.r;
rp = pos.phi + _ry;
rt = pos.theta + _rx;
prevX = pr * Math.sin(rp) * Math.sin(rt) + OX;
prevY = pr * Math.cos(rp) + OY;
//g.moveTo(prevX, prevY);
len = track.length
_tmp.fillRect(_tmp.rect, 0);
for(i=1; i<len; i++){
pos = track[i];
pr = pos.r;
rp = pos.phi + _ry;
rt = pos.theta + _rx;
zRate = -(pr*Math.sin(rp)*Math.cos(rt))/800 + .6;
nx = pr * Math.sin(rp) * Math.sin(rt) + OX;
ny = pr * Math.cos(rp) + OY;
//g.lineStyle(1+zRate*0.5, p.color, zRate)
//g.lineTo(pos.x, pos.y)
efla( _tmp, prevX, prevY, nx, ny, (zRate*0xFF)<<24 | pc);
prevX = nx;
prevY = ny;
}
_canvas.draw(_tmp, null, null, 'add');
p = p.next;
}
_canvas.unlock();
amax = cnt;
}
private var _rx:Number = 0;
private var _ry:Number = 0;
}
}
internal class Particle {
// public static var originX:Number, originY:Number
//public static var t0:Number = 0 // theta0
// public static var p0:Number = 0 // phi0
// public static function get theta0():Number { return t0 * Kinv }
// public static function set theta0(v:Number):void { t0 = v * K }
// public static function get phi0():Number { return p0 * Kinv }
// public static function set phi0(v:Number):void { p0 = v * K }
// private static const K:Number = Math.PI / 180
// private static const Kinv:Number = 180 / Math.PI
private static const GO_FORWARD:uint = 0
private static const ROTATE:uint = 1
public var theta:Number = 0
public var phi:Number = 0
public var radius:Number = 0
public var thetaVel:Number = 0, phiVel:Number = 0, radVel:Number = 0
public var track:Array = [];
public var next:Particle
public var color:uint;
private var state:uint = GO_FORWARD
public function saveCurrentCoord():void {
var newState:uint = radVel ? GO_FORWARD : ROTATE
var pos:Pos = new Pos;
pos.r = radius;
pos.phi = phi;
pos.theta = theta;
//pos.x = radius * Math.cos(c.phi) * Math.cos(c.theta);
//pos.y = radius * Math.sin(c.phi);
//pos.z = radius * Math.cos(c.phi) * Math.sin(c.theta);
if(state == GO_FORWARD && newState == state){
track.pop()
}
track.push(pos);
state = newState
}
public function reset():void
{
track = [];
phi = Math.PI * 2 * Math.random(); //360 * i / max
theta = Math.random() * Math.PI //180 * i / max
phiVel = 2 * Math.PI/180;
radius = 1
thetaVel = 0
color = Math.random() * 0x404040 + 0xC0C0C0;
}
// public function get phi():Number { return _phi * Kinv }
// public function set phi(v:Number):void { _phi = v * K }
// public function get theta():Number { return _theta * Kinv }
// public function set theta(v:Number):void { _theta = v * K }
}
//internal class Coord {
// public var r:Number, phi:Number, theta:Number
//}
internal class Pos {
public var r:Number, phi:Number, theta:Number;
}
