パーティクルの練習
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.ColorMatrixFilter;
import flash.geom.Rectangle;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.Timer;
[SWF(backgroundColor=0x000000)]
public class String_Particle extends Sprite
{
//パーティクルを描写するBitmapData
private var canvas:BitmapData;
//テキストを描画するBitmapData
private var textCanvas:BitmapData;
//パーティクルクラスのインスタンスを格納する配列
private var particles:Array;
//描画するパーティクルの数
private var p_num:int
private var textAry:Array;
private var index:uint=0;
//パーティクルを元の位置から移動させる最大距離
private var maxDis:int = 500;
private var timer:Timer;
public function String_Particle()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
canvas = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0x000000);
addChild(new Bitmap(canvas));
textAry = new Array;
for(var i:uint = 0; i < 3; i++){
textAry[i] = new Array(2);
}
textAry[0][0] = "Every day is Carnival";
textAry[0][1] = 40;
textAry[1][0] = "Actionscript3.0";
textAry[1][1] = 40;
textAry[2][0] = " -‐ '´ ̄ ̄`ヽ、\n / /\" `ヽ ヽ)└\\n //, '/ ヽハ⌒、 ヽ\n 〃 {_{ー' ゛'`ー リ| l │ i|\n レ!小l● ● 从 |、i| にょろにょろ言っててキモいからだよ。\n ヽ|l⊃ 、_,、_, ⊂⊃ |ノ│\n /⌒ヽ__|ヘ ゝ._) j /⌒i !\n \ /:::::| l>,、 __, イァ/ /│\n. /:::::/| | ヾ:::|三/::{ヘ、__∧ |\n `ヽ< | | ヾ∨:::/ヾ:::彡' |";
textAry[2][1] = 14;
init(textAry[0][0], textAry[0][1]);
stage.addEventListener(MouseEvent.CLICK, onClick);
timer = new Timer(33);
timer.addEventListener(TimerEvent.TIMER, loop);
timer.start();
}
private function init(str:String, size:uint):void{
var tf:TextField = new TextField;
tf.defaultTextFormat = new TextFormat("Swis721 BdRndBT", size, 0xFFFFFF );
tf.autoSize = TextFieldAutoSize.LEFT;
tf.text = str;
//文字の描画
textCanvas = new BitmapData(tf.textWidth, tf.textHeight, false, 0x000000);
textCanvas.draw(tf);
particles = new Array;
createText();
}
//文字からパーティクルの生成
private function createText():void{
//ステージを中心にテキストを配置するときの左上座標
var ofx:Number = stage.stageWidth / 2 - textCanvas.width / 2;
var ofy:Number = stage.stageHeight / 2 - textCanvas.height / 2;
//textCanvasを1pxずつ見ていく
for(var ex:uint = 0; ex < textCanvas.width; ex++){
for(var ey:uint = 0; ey < textCanvas.height; ey++){
//textCanvasの座標(ex, ey)のRGB値の取得
var c:uint = textCanvas.getPixel(ex, ey);
//黒以外の場合
if(c != 0x000000){
createParticle(ex + ofx, ey + ofy, c);
}
}
}
}
//パーティクルを一つ生成
public function createParticle(ex:Number, ey:Number, c:Number):void{
var p:Particle = new Particle;
p.ex = ex;
p.ey = ey;
p.c = c;
initParticle(p);
particles.push(p);
p_num = 0;
}
public function initParticle(p:Particle):void{
var rad:Number = Math.random() * Math.PI * 2;
var dis:Number = Math.random() * maxDis;
p.x = p.ex + dis * Math.cos(rad);
p.y = p.ey + dis * Math.sin(rad);
}
private function onClick(event:MouseEvent):void{
index = (index+1)%textAry.length;
init(textAry[index][0], textAry[index][1]);
// var n:int = particles.length;
// while(n--){
// var p:Particle = particles[n];
// initParticle(p);
// }
// p_num = 0;
}
private function loop(event:TimerEvent):void{
//キャンパスをロック
canvas.lock();
//キャンパスをクリア
canvas.fillRect(canvas.rect, 0x000000);
//パーティクルを描画
for(var i:uint = 0; i < p_num; i++){
var p:Particle = particles[i];
if(Math.abs(p.ex - p.x) < 0.5 && Math.abs(p.ey - p.y) < 0.5){
//スナップ処理
p.x = p.ex;
p.y = p.ey;
}
else{
p.x += (p.ex - p.x) / 4;
p.y += (p.ey - p.y) / 4;
}
//canvasにピクセル描画
canvas.setPixel(p.x, p.y, p.c);
}
//描画するパーティクル数を増やす
var n:uint = particles.length;
p_num = (p_num + 100 < n) ? p_num + 100 : n;
//ロック解除
canvas.unlock();
}
}
}
class Particle{
public var x:Number;
public var y:Number;
public var ex:Number;
public var ey:Number;
public var c:int;
public function Particle(){
x = 0;
y = 0;
ex = 0;
ey = 0;
c = 0;
}
}