« 2005年11月 | Main | 2006年01月 »

2005年12月22日

ブロックが崩れるトランジッション - copyPixels

コードが長くて整理できないので、今のところ、簡単な手順説明だけで。ちゃんとしたら載せます。

1. MC1に画像を読み込む。
2. ビットマップ1にMC1をdrawでコピー。(→不要になったMC1は削除。)
3. MC2を作成。
4. MC2の中にブロックMC216個を並べて配置。
5. ブロックMCと同じサイズのビットマップ2を作成。
6. ビットマップ2にビットマップ1をcopyPixelsで開始位置(Point)を変更してコピー。
7. それぞれのブロックMCにビットマップ2をatatchBitmapで貼り付け。
8. 1~7までを繰り返す。(二つのMC2をそれぞれMC2a、MC2bとする。)
9. onMouseDownでMC2a内のブロック崩壊。
10. MC2a内の全ブロック落下後、MC2aの深度をMC2bと入れ替えて背面に配置。

2005年12月18日

ゆらゆら揺れる文字 - DisplacementMapFilter

DisplacementMapFilterは、特定のビットマップ(置き換えビットマップイメージ)のピクセル値に基づいて、ムービークリップやビットマップを変形させることができます。PhotoShopでいうと、[フィルタ]メニューから[変形]→[置き換え]で同様の効果。

下図の場合、赤を基準にY方向へ移動させているため、置き換えビットマップの赤の値が中間値(128)より小さいピクセルほど下(正)方向に移動し、赤の値が大きいピクセルほど上(負)方向に変化します。

DisplacementMapFilterイメージ

慣れるまで結構しんどいフィルタですが、よく使う変形のグラデーションパターンを一度作ってしまえば、あとは使いまわすことができます。特に厳密な計算をする必要がない場合は、ステージ上で置き換えマップを作ってしまってもよいかと思います。
以下のサンプルでは、埋め込みフォントを使用する際、必要な文字を埋め込んだダイナミックテキストを別途ステージに配置しておくか、リンケージ設定で書き出しておく必要があります。

import flash.display.*;
import flash.filters.*;
import flash.geom.*;

var w:Number = 360;
var h:Number = 240;

// --- 置き換えマップイメージ作成
var map:BitmapData = new BitmapData(w,h, true ,0);
var mc:MovieClip = this.createEmptyMovieClip("m", 1);
var matrix:Matrix = new Matrix();
matrix.createGradientBox(30, 1, 0, 15, 0);
mc.beginGradientFill("linear", [0xFF0000, 0x0000FF], [100, 100], [34, 220], matrix, "reflect");
mc.moveTo(0, 0);
mc.lineTo(w, 0);
mc.lineTo(w, h);
mc.lineTo(0, h);
mc.lineTo(0, 0);
mc.endFill();

map.draw(mc);
mc.removeMovieClip();
// --- テキスト作成
var txtbox:MovieClip = this.createEmptyMovieClip("txt_mc", 2);
var copytxt:TextField = txtbox.createTextField("copy_txt", 1, 0, 15, 200, 20);
var fmt:TextFormat = new TextFormat();
fmt.font = "フォントを入力";
fmt.size = 20;
copytxt.setNewTextFormat(fmt);
copytxt.embedFonts = true;
copytxt.text = "ゆらゆらゆらゆら";
copytxt.selectable = false;
copytxt.textColor = 0xFFFFFF;
copytxt.autoSize = true;

txtbox._x = (w-txtbox._width)/2;
txtbox._y = (h-txtbox._height)/2;
txtbox.blendMode = "add";
// --- フィルタ 変数
var glow:GlowFilter = new GlowFilter(0x0044CC, 20, 10, 10, 5, 3, false, false);
var blurx:Number = 20; 
var blury:Number = 10;
var alp:Number = 5;

var pos:Point = new Point(-txtbox._width, 0);
var goal:Point = new Point(txtbox._width+240, 0)

// --- フィルタ適用
this.onEnterFrame = function():Void {
	var dmf:DisplacementMapFilter = new DisplacementMapFilter(map, pos, 1, 1, 10, 25, "clamp");
	var blur:BlurFilter = new BlurFilter(blurx, blury, 3);
	var matrix:Array = [
		1, 1, .5, 0, 1, 
		1, 1, .5, 0, 1, 
		2, .5, 1, 0, 1, 
		0, 0, 0, alp, 0
		];
	var clrmrx:ColorMatrixFilter = new ColorMatrixFilter(matrix);
	txtbox.filters = [dmf, glow, blur, clrmrx];
	if(Math.abs(pos.x-goal.x) <= 120){
		pos.x = -txtbox._width;
		blurx = 20;
		blury = 10;
		alp = 5;
	}
	pos.x += (goal.x-pos.x)*0.01;
	blurx += -blurx*0.035;
	blury += -blury*0.035;
	alp += (1-alp)*0.07;
}

2005年12月04日

迫りくる光 - draw

matrixを使いこなせるようになると、drawメソッドでビットマップを自由に操作することができます。

draw イメージ

サンプルでは、matrix.scaleで拡大させていますが、左上を基準に拡大されるため、このままだと中心がズレてしまうので、matrix.translateで移動量だけ中心に戻しています。カラーはタイムラインで変化させて、フレームに飛ばしてます。

import flash.display.*;
import flash.geom.*;
import flash.filters.*;

var scale:Number = 1.24;
var blur:BlurFilter = new BlurFilter(1, 1, 2);
var dep:Number = 0;

this.createEmptyMovieClip("src_mc",1);
this.createEmptyMovieClip("cap_mc",2);

var src:BitmapData = new BitmapData(360, 240, true, 0);
var cap:BitmapData = src.clone(); 
src_mc.attachBitmap(src, 1);
 
var matrix:Matrix = new Matrix();
var clr:ColorTransform = new ColorTransform();

matrix.scale(scale, scale); 
matrix.translate((cap.width-cap.width*scale)/2, (cap.height-cap.height*scale)/2);

this.onEnterFrame = function():Void {
	createParticle();
	cap.draw(this);
	cap.applyFilter(cap, cap.rectangle, new Point(0,0), blur);
	src.draw(cap, matrix, clr, "normal", src.rectangle, true);
}

function createParticle():Void {
	dep++;
	var part:MovieClip = cap_mc.attachMovie("star", "star_mc" + dep, dep);
	part.blendMode = "hardlight";
	part._x = cap_mc._xmouse;
	part._y = cap_mc._ymouse;
	part.gotoAndPlay(Math.floor(dep%part._totalframes)+1);
	part._xscale = part._yscale = 25 + 75*Math.random();
	part.vx = (Math.random()*2-1)*10;
	part.vy = (Math.random()*2-1)*10;
	part.onEnterFrame = scatter;
}

function scatter():Void {
	this._x += this.vx *= .9;
	this._y += this.vy *= .9;
	this._xscale = this._yscale *= .9;
	if (this._xscale < 10){
		this.removeMovieClip();
	}
}