10万パーティクル60FPS(最適化)
これ以上は無理っぽい
/**
* Copyright saharan ( http://wonderfl.net/user/saharan )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/j9tz
*/
// forked from saharan's forked from: 重力マウス100000パーティクル(更に最適化)
// forked from fumix's 重力マウス(リンクリストにしてみた)
// forked from undo's 重力マウス
// リンクリストにしてみたけどそんなに速くない??
// Math.*を最初以外全部削除。
/*
* もうちょい最適化&リファクタリング
*/
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.geom.Rectangle;
import net.hires.debug.Stats;
[SWF(frameRate="60", width="465", height="465")]
public class ParticleTest1 extends Sprite {
private var bmd:BitmapData;
private var bmdRect:Rectangle;
private var ctf:ColorTransform;
private var first:Particle;
private const maxNum:int = 100000;
public function ParticleTest1() {
addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(evt:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
var prev:Particle;
bmd = new BitmapData(465, 465, false, 0x000000);
ctf = new ColorTransform(0.4, 0.95, 0.7, 1.0);
bmdRect = bmd.rect;
addChild(new Bitmap(bmd));
var debug:Stats = new Stats();
debug.alpha = 0.8;
addChild(debug);
for (var i:int = 0; i < maxNum; i++) {
var p:Particle = new Particle();
p.px = Math.random() * 465;
p.py = Math.random() * 465;
if (first == null)
prev = first = p;
else {
prev.next = p;
prev = p;
}
}
addEventListener(Event.ENTER_FRAME, onEnter);
}
private function onEnter(evt:Event):void {
bmd.lock();
var p:Particle = first;
const mX:Number = mouseX;
const mY:Number = mouseY;
bmd.colorTransform(bmdRect, ctf);
const pixels:Vector.<uint> = bmd.getVector(bmdRect);
while(p) {
const diffX:Number = mX - p.px;
const diffY:Number = mY - p.py;
const grav:Number = 50 / (diffX * diffX + diffY * diffY);
p.px += p.vx = (p.vx + diffX * grav) * 0.96;
p.py += p.vy = (p.vy + diffY * grav) * 0.96;
if(p.px > 465)
p.px = 0;
else if(p.px < 0)
p.px = 465;
if(p.py > 465)
p.py = 0;
else if(p.py < 0)
p.py = 465;
const intX:uint = p.px - 0.5;
const intY:uint = p.py - 0.5;
pixels[intY * 465 + intX] = 0xffffff;
p = p.next;
}
bmd.setVector(bmdRect, pixels);
bmd.unlock();
}
}
}
class Particle {
public var vx:Number;
public var vy:Number;
public var px:Number;
public var py:Number;
public var next:Particle;
public function Particle() {
vx = vy = 0;
}
}