- 2008年7月 2日 23:57
- ActionScript 3.0
今回のサンプルは入力されたテキストを読み込んで、パーティクルを生成、文字の形に沿って積もっていきます。
これを実現するために、以下のように手順を踏みます。
- 入力されたテキストを読み込んでテキストフィールドにする
- このテキストフィールドをビットマップデータに変換する
- ビットマップデータからビットマップを生成
- ビットマップを表示
- 表示されたビットマップのカラー値をピクセル単位で取得
- カラー値をローカル座標に置き換え、グローバル座標に変換
- パーティクルを生成してTweenerで座標に向けてアニメーション
このように、幾つかの手順を踏む必要があります。ここで肝となるのはパーティクルの一つ一つを特定の座標へ向かわせるためにテキストをビットマップ化しているところです。
特定の座標をとるためにBitMapClassのGetpixel()を、取得した座標をグローバル座標に変換するのにDisplayObjectClassのlocalToGlobal()用います。
以下ピックアップソースです
OutPutTextImage.as
package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.EventDispatcher;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
/**/
public class OutPutTextImage extends EventDispatcher {
private var pointArray:Array;
public function OutPutTextImage():void {
//座標を格納する配列
pointArray = new Array();
//テキスト取得イベントを登録
InputBar.instance.addEventListener(TextInputEvent.TEXT_INPUT, textInputHandler)
}
private function textInputHandler(e:TextInputEvent):void {
InputBar.instance.removeEventListener(TextInputEvent.TEXT_INPUT, textInputHandler)
createText(e.inputText)
}
//入力された文字を元にテキストフィールドを作成
private function createText(string:String ):void {
var inputText:TextField = new TextField();
inputText.text = string;
inputText.autoSize = TextFieldAutoSize.LEFT;
//テキストフォーマットで調整
var textFormat:TextFormat = new TextFormat();
textFormat.color = 0xFFFFFF;
textFormat.size = 100
textFormat.font = "メイリオ"
inputText.setTextFormat(textFormat)
createBitMap(inputText);
}
//テキストフィールドをもとにビットマップを生成
private function createBitMap(targetTextField:TextField):void{
var bitmapSource:BitmapData = new BitmapData(targetTextField.width, targetTextField.height,true,0x000000)
bitmapSource.draw(targetTextField)
pixelScan(new Bitmap(bitmapSource));
}
//ビットマップのカラー値の走査
private function pixelScan(bitmap:Bitmap,heightCount:Number = 0):void{
var bitmap:Bitmap = bitmap as Bitmap;
if (heightCount <= bitmap.height) {
for (var i:int = 0; i < bitmap.width; i++) {
var pixeldata:int = bitmap.bitmapData.getPixel(i, heightCount)
if (pixeldata != 0) {
var point:Point = new Point(i,heightCount)
pointArray.push(point)
}
//繰り返し
if (i >= bitmap.width - 1 && heightCount <= bitmap.height) {
pixelScan(bitmap,heightCount += 1)
}
}
}else {//終了
var textinputEventObject:TextInputEvent = new TextInputEvent(TextInputEvent.OUTPUT_BITMAP)
textinputEventObject.outputBitmap = bitmap;
textinputEventObject.pointArray = pointArray;
dispatchEvent(textinputEventObject)
}
}
}
}
このソースは比較的単調に事を進めています。ビットマップのカラー値を取得するエンジンがpixelScan()です。
このメソッドではbitmapdataクラスのgetPixel()を使ってカラー値を取得しているのは前述したとおりですが、
getPixelは1pxごとしか取得することができません。
そこでforを使い、繰り返し処理を行います。ここでは、y値を固定し、x:0からbitmapのwidth値までを1インターバルとしています。
一回目の動作が終わると、現在走査したy値とbitmapのhightを比べ、次のy値を設定し終わるまで走査します。
走査したx,y座標はPoinインスタンスを生成してそれぞれ引数として渡します。
一通り座標を取得したら、bitmapをrootの表示リストに追加後、雪を生成します。
生成した雪を先ほど取得した座標に向かわせるわけですが、取得した座標はローカル座標(ここではbitmap内における座標)のため、意図した挙動になりません。
そこで、DisplayObjectクラスのlocalToGlobal()を使い、ローカル座標をグローバル座標に変換し、そこに向かわます。
移動においては、例によってTweenerを用いています。
private static function moving():void {
var bug:Bug = new Bug();
bugPocket.addChild(bug)
if (targetPointArray[count] != null) {
Tweener.addTween(bug, {
//ローカル座標をグローバル座標に変換
x:targetBitmap.localToGlobal(targetPointArray[count]).x,
y:targetBitmap.localToGlobal(targetPointArray[count]).y,
time:Math.floor(Math.random()*10)+1
});
if (count < targetPointArray.length -1) {
var timer:Timer = new Timer(5,1)
timer.addEventListener(TimerEvent.TIMER, function() {
timer.stop()
count += 1
moving()
})
timer.start()
}
}
}




