[1日1Wonderfl]2日目:TextParticle パーティクル最適化に挑戦
1日1Wonderfl 2/30日目
4/27
テキストをプリレンダリングしてみるテスト
書き込むときにMatrixとか使わない高速な方法があるんだろうか?
4/28
Matrixとかなるべくnewしないようにしてみる
エフェクトかけてみた
加速度を導入
BitmapData.drawがやっぱりボトルネックっぽい
// forked from yd_niku's [1日1Wonderfl]1日目:TextParticle プリレンダリング演習
package {
// 1日1Wonderfl 2/30日目
// 4/27
// テキストをプリレンダリングしてみるテスト
// 書き込むときにMatrixとか使わない高速な方法があるんだろうか?
// 4/28
// Matrixとかなるべくnewしないようにしてみる
// エフェクトかけてみた
// 加速度を導入
// BitmapData.drawがやっぱりボトルネックっぽい
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import flash.filters.*;
import flash.utils.*;
import com.flashdynamix.utils.SWFProfiler;
public class FlashTest extends Sprite {
private var _canvas:BitmapData;
private var _textfield:TextField;
private var _preRenderMap:Vector.<BitmapData> = new Vector.<BitmapData>();
private var _particles:Vector.<Particle>= new Vector.<Particle>();
private var _cleanupTimer:Timer = new Timer( 1000 );
private var _statusField:TextField;
public function FlashTest() {
_canvas = new BitmapData( stage.stageWidth, stage.stageHeight, true, 0xFFFFFFFF );
addChild( new Bitmap(_canvas) );
createPreRenderMap();
stage.addEventListener( MouseEvent.CLICK, onClick );
addEventListener( Event.ENTER_FRAME, enterFrame );
_cleanupTimer.addEventListener( TimerEvent.TIMER, onCleanUp );
_cleanupTimer.start();
_statusField = new TextField();
addChild( _statusField );
_statusField.x = 200;
_statusField.y = 200;
_statusField.width= stage.stageWidth;
_statusField.selectable = false;
_statusField.mouseEnabled= false;
_statusField.defaultTextFormat = new TextFormat( "_sans", 12, 0xFF0000 );
_statusField.text = "Please Click!";
SWFProfiler.init( this );
}
public function onCleanUp( e:TimerEvent ):void {
var l:int = _particles.length;
var p:Particle
while( l-->0 ) {
p = _particles[l];
if( p.life <= 0 ) {
_particles.splice( l, 1 );
p.bitmapData = null;
}
}
_statusField.text= String(_particles.length) + " particles";
}
private var _filter:BitmapFilter = new ColorMatrixFilter( [
1.05, 0, 0, 0, 0,
0, 1.02, 0, 0, 0,
0, 0, 1.02, 0, 0,
0, 0, 0, 0.96, 0
] );
private const P:Point = new Point;
public function enterFrame( e:Event ):void {
var mat:Matrix = new Matrix(), parcent:Number;
const DIG2RAD:Number = Math.PI/180;
const W:Number = stage.stageWidth;
const H:Number = stage.stageHeight;
//p.life/100
_canvas.lock();
_canvas.applyFilter( _canvas, _canvas.rect, P, _filter );
//_canvas.fillRect( _canvas.rect, 0xFFFFFFFF );
for each( var p:Particle in _particles ) {
if( p.life < 0 ) continue;
p.ax = p.ax + ( p.vx = p.vx * 0.75 );
p.ay = p.ay + ( p.vy = p.vy * 0.75 );
p.x += p.ax;
p.y += p.ay;
p.ax *= 0.98;
p.ay *= 0.98;
p.rot = p.rot + ( p.vrot = p.vrot * 0.98 );
mat.tx = p.x;
mat.ty = p.y;
var rot :Number = p.rot*DIG2RAD;
mat.a = Math.cos( rot );
mat.b = Math.sin( rot );
mat.c = -Math.sin( rot );
mat.d = Math.cos( rot );
parcent = 1.0 - p.life*0.01;
_canvas.draw( p.bitmapData, mat, new ColorTransform( 1, 1, 1, 1.0-parcent, parcent*0xFF>>0, parcent*0xCC>>0, parcent*0x33 >>0 ) );
if( p.x < 0 ) {
p.x += W;
}
else if( p.x > W ) {
p.x -= W;
}
if( p.y < 0 ) {
p.y += H;
}
else if( p.y > H ) {
p.y -= H;
}
p.life--;
}
_canvas.unlock();
}
private var _charIndex:uint = 0;
public function onClick ( e:MouseEvent ):void {
var clickX:Number = e.localX;
var clickY:Number = e.localY;
var vLength:Number= 3;
var char:BitmapData, rad:Number, angle:Number, p:Particle;
const DIG2RAD:Number = 180/Math.PI;
const RAD:Number = Math.PI*2;
for( var i:int =0; i< 300; ++i ) {
try{
char = _preRenderMap[ _charIndex++ ];
}
catch( e:Error ) {
_charIndex =0;
char = _preRenderMap[ _charIndex++ ];
}
angle = Math.random()*RAD;
p = new Particle( char, clickX, clickY, angle*DIG2RAD,
Math.cos(angle)*vLength, Math.sin(angle)*vLength, Math.random()*30-15 );
_particles.push( p );
}
}
public function createPreRenderMap():void{
var i:int = 0;
var textfield:TextField = new TextField();
textfield.autoSize =TextFieldAutoSize.LEFT;
//textfield.defaultTextFormat = new TextFormat( "_sans", 12, 0x0000FF );
textfield.height =20;
var originText:String ="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-+/*";
while( originText.length ) {
var char:String = originText.substr( 0, 1 );
textfield.text = char;
var tmp:BitmapData = new BitmapData( 16, 16, true, 0x00 );
tmp.draw( textfield );
_preRenderMap.push( tmp );
originText = originText.substr( 1, originText.length );
}
}
}
}
import flash.display.*;
class Particle {
public var x:Number;
public var y:Number;
public var ax:Number;
public var ay:Number;
public var vx:Number;
public var vy:Number;
public var rot:Number;
public var vrot:Number;
public var bitmapData:BitmapData;
public var life:int = 100;
public function Particle( bmd:BitmapData, x:Number=0, y:Number=0, rot:Number= 0, vx:Number=0, vy:Number=0, vrot:Number=0 ){
this.x = x;
this.y = y;
this.ax = 0;
this.ay = 0;
this.rot = rot;
this.vx = vx;
this.vy = vy;
this.vrot = vrot;
this.bitmapData= bmd;
}
}