Home > flash

flash Archive

FlashBuilderの便利機能とかショートカットとか

【1.ソース解析偏】

下記はhoge.method()と書いてある箇所や、public function method():voidという箇所あったとして、methodの部分にカーソルを置いて行う。

重要度★★★★★ (必須)

定義元にジャンプ

F3

実装部分を探す

⌘+G

F3で参照元に飛ぶとインターフェースに飛んでしまう場合に威力を発揮

関数がどこから呼ばれているか探す

右クリック → 呼び出し階層を開く (Control + Alt + H)

戻る/進む

⌘ + [ (戻る)、⌘ + ] (進む)

F3等で定義元に飛んだ後、元の場所に戻る。マウスの戻る、進むボタンを押しても同じ。

(WindowsならAlt + ←、Alt + →)

重要度★★★★ (重要)

クラス名でファイル検索

⌘ + Shift + r

ワークスペース全体から検索

⌘ + Shift + f (flashbuilder4.5は ⌘ + h)

重要度★★★ (便利)

直近に出た単語を補完

Control + . (WindowsだとAlt + /)

Control + spaceの補完とは違い、候補を出さずに直近に出た単語から補完する。追加で連続入力できる。

コメントアウト生成

⌘ + Shift + d

comment.png

import文を整理 (不要なimportも削除してくれる)

⌘ + Shift + o

直近まで編集していた箇所に戻る

Control + q

手元が狂って妙な箇所に画面がフォーカスしてしまった際に便利

行数指定をして移動

⌘ + l

デバッグ用にパブリッシュ

⌘ + F11

重要度★★

開いているファイルを表示

⌘ + e

1行コメントアウト

⌘ + /

複数行コメントアウト

⌘ + Shift + C

重要度★

インクリメンタル検索

⌘ + J (⌘ + Shift + J)

フッター部分に『インクリメンタル検索』と表示されたら、検索したい単語をタイプする。

クラスのプロパティ、メソッドを表示

⌘ + o

ショートカット一覧を表示

⌘ + Shift + l

【2.デバッグ偏】

■ブックマーク
行数表示の部分を右クリック → ブックマークに追加 ウィンドウ → 他のビュー → ビューの表示windowが立ち上がるので、 一般フォルダからブックマークを選択。 view.png
ブックマークに追加した部分が表示される。 view2.png

■条件つきブレークポイント
普通にブレークポイントを設定
ブレークポイントマークを右クリック → ブレークポイントプロパティ
条件を使用するにチェックを入れて、条件を入れる。

■監視式の作成
プロパティを右クリック → 監視式の作成

監視式.png

ブレークポイントで止まった際、そのプロパティの値が表示されるようになる。

■プロファイラ
Mac版はバグがあるので、そのままでは使用できない。下記の手順を踏む。

Finderを開き、⌘ + Shift + Gを入力。
/private/etc/と入力してエンター。
etc.png

hostsという名のファイルがあるのでテキストエディタ等で開き、

::1             localhost

と記述されている箇所の先頭に#を書いてコメントアウトする。 ipv6.png

【参考】
Flash Builder 4 Premium でデバッグプレイヤーが起動できなくなった! | BOONDOCK RADIO

経路探索 + クォータービュー

iso

クォータービューでの経路探索を試作。いまさらですが。
青い障害物を避け、クリックした箇所に赤い箱が移動します。
障害物はランダムに配置されます。
iso + A*

見てお分かりの通り詳解 ActionScript 3.0アニメーションの3章・4章の組み合わせです。

メインとなるソースコードのみ貼っておきます。他の使用しているクラスは書籍と同じなので省きます。

package {
	import com.friendsofed.isometric.DrawnIsoBox;
	import com.friendsofed.isometric.DrawnIsoTile;
	import com.friendsofed.isometric.IsoUtils;
	import com.friendsofed.isometric.IsoWorld;
	import com.friendsofed.isometric.Point3D;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
	import flash.geom.Point;
	import org.libspark.betweenas3.BetweenAS3;
	import org.libspark.betweenas3.easing.Linear;
	import org.libspark.betweenas3.tweens._iTween;

	[SWF(backgroundColor=0xFFFFFF, width=830, height=500, frameRate=60)]
    public class GameIso extends Sprite {
		private static const _NUM_COLS:int = 20;
		private static const _NUM_ROWS:int = 20;
		private static const _CELL_SIZE:int = 20;
		private static const _BOX_HEIGHT:int = 22;

		private var _world:IsoWorld;
        private var _grid:Grid;
        private var _player:DrawnIsoBox;
        private var _index:int;
        private var _path:Array;
		private var _iTween:_iTween;

        public function GameIso() {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;

			_world = new IsoWorld();
            _world.x = stage.stageWidth / 2;
            _world.y = 50;
            addChild(_world);

            makePlayer();
            makeGrid();
			drawGrid();

            _world.addEventListener(MouseEvent.CLICK, onGridClick);
        }

        private function makePlayer():void {
			_player = new DrawnIsoBox(_CELL_SIZE, 0xff0000, _BOX_HEIGHT);
            _player.x = _CELL_SIZE * int(Math.random() * _NUM_COLS);
            _player.z = _CELL_SIZE * int(Math.random() * _NUM_ROWS);
            _world.addChildToWorld(_player);
        }

        private function makeGrid():void {
            _grid = new Grid(_NUM_COLS, _NUM_ROWS);
            for (var i:int = 0; i < 60; i++) {
                _grid.setWalkable(Math.floor(Math.random() * _NUM_COLS),
                                  Math.floor(Math.random() * _NUM_COLS),
                                  false);
            }
        }

        private function drawGrid():void {
            for (var i:int = 0; i < _grid.numCols; i++) {
                for (var j:int = 0; j < _grid.numRows; j++) {
                    var node:Node = _grid.getNode(i, j);
					if (node.walkable) {
						var tile:DrawnIsoTile = new DrawnIsoTile(_CELL_SIZE, 0xffffff);
						tile.position = new Point3D(i * _CELL_SIZE, 0, j * _CELL_SIZE);
						_world.addChildToFloor(tile);
					}
					else {
						var box:DrawnIsoBox = new DrawnIsoBox(_CELL_SIZE, 0x336699, _BOX_HEIGHT);
						box.x = i * _CELL_SIZE;
						box.z = j * _CELL_SIZE;
						_world.addChildToWorld(box);
					}
                }
            }
        }

        private function onGridClick(event:MouseEvent):void {
			var p:Point3D = IsoUtils.screenToIso(new Point(_world.mouseX, _world.mouseY));

			var xpos:int = Math.floor((p.x + _CELL_SIZE / 2) / _CELL_SIZE);
            var ypos:int = Math.floor((p.z + _CELL_SIZE / 2) / _CELL_SIZE);
            _grid.setEndNode(xpos, ypos);

			xpos = Math.floor((_player.x + _CELL_SIZE / 2) / _CELL_SIZE);
            ypos = Math.floor((_player.z + _CELL_SIZE / 2) / _CELL_SIZE);

            _grid.setStartNode(xpos, ypos);
            findPath();
        }

        /**
         * AStarのインスタンスを生成して、経路探索に用いる。
         */
        private function findPath():void {
            var astar:AStar = new AStar();
            if (astar.findPath(_grid)) {
				if(_iTween && _iTween.isPlaying) _iTween.stop();
                _path = astar.path;
                _index = -1;
				move();
            }
        }

		private function move():void {
			if (_path[++_index]) {
				var targetX:Number = _path[_index].x * _CELL_SIZE;
				var targetY:Number = _path[_index].y * _CELL_SIZE;

				_iTween = BetweenAS3.tween(_player, { x: targetX, z:targetY }, null, 0.1, Linear.easeNone);
				_iTween.onComplete = move;
				_iTween.onUpdate = _world.sort;
				_iTween.play();
            }
		}
    }
}

テトリスを作ってみた

ふとテトリスのプログラムに興味を持ち、練習がてらに作ってみました。

なんの装飾も演出ない、むき出し状態です。
スペースで回転、十字キーで移動。

去年のCEDECに行かれた方がいて、その時の資料を頂いたんですが、
その資料の中にテトリスの作り方が載っていたので、それを参考にしてみました。
資料を書いた方はゲームプログラマになる前に覚えておきたい技術の著者の方です。この方は凄いですね‥。

たかがテトリスですが、かなり勉強になりました。
色々な実装方法があるようで、奥が深いですね。

例えばflashrodさんのTetrisがありますが、ソースが短いです。
かなりテクニカルな事をしてるっぽい感じで、ぱっと見、何をしているのか分かりません。

さらに、500バイト以下のテトリスとかありますしね。

マウスで操作出来るスリットスキャン

スリットスキャンに、
マウスのインタラクションを付けるとどうなるかな、と思い、作ってみました。

最初は意識していなかったんだけど、以前教えてもらったこちらに似てしまった。

BitmapData::drawで毎フレーム動画をキャプチャし、配列に保存しています。
今回は過去400枚を保存しています。かなり多いと思うんですが、いけるもんですねぇ。

映像を縦1pxづつに区切って管理し、それぞれに何フレーム早めるか、遅らせるかを管理しています。
デフォルトでは保存したキャプチャの真ん中を表示。(今回は400枚保存してるから、200枚目を表示。)

BetweenAs3のイージングを変えるとまた違った感じになります。

ちょっとハマったのが、NetStreamインスタンスをローカル変数にすると、drawする時に下のセキュリティエラーが出る事。

SecurityError: Error #2123: セキュリティサンドボックス侵害 : BitmapData.draw: file:///hoge.swf は unknown URL にアクセスできません。ポリシーファイルへのアクセスも許可されていません。

drawする時にNetStreamインスタンスを参照して何かチェックしてるんですかね?
すぐにエラーが出ずに、しばらくすると出るのも謎でした。

一番良かったのは、絶好の映像ネタが見つかった事w
背景が固定で人が動く映像が見つかって良かった。
背景まで動いているとグチャグチャになりすぎてしまい、良く分からない映像になってしまいます。
ムーンウォークしてる人は、もちろん僕じゃないですよ!w

Fluid

前回asに書き直しただけのFluid \ Learning \ Processing 1.0のソースを解体して整理。クラス構造も大幅に変えてます。
それから、オリジナルはマス目に色を塗って動きを出していますが、パーティクルを表示して動かす形に変更しました。

オリジナルは作製途中なのかな、って感じがしました。。

気泡っぽい感じが出た。

流体パーティクル

Processingの流体サンプルをasに

[Flash]流体っぽいのを作ろうと思った | blog ViolentCoding
を見てずっと気になっていたんですが、同記事で紹介されている

Fluid \ Learning \ Processing 1.0
をそのままas3に持ってきてみました。

Processingの流体サンプルをそのまま持ってきたもの – wonderfl build flash online

変数宣言が微妙に違うぐらいで、そこを直せば割とあっさり動きました。
最適化してないせいもあるけど、やっぱFlashは重いですね。
変数名なんかはそのままです。
スパイス的な謎の定数が結構あって完全に読み解くのは大変そう。

しかし紹介して下さったe_s_jpさんが作ってるDisplacementMapFilterのバージョンですが、
よくあそこまで膨らませたなぁ、と思います。
凄いす。

僕も、processing.orgから持ってきたコードを、もうちょっと分かりやすく分解して理解してみようと思います。

変数名なんかを自分用に置き換えただけなのはコレ。

package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	[SWF(backgroundColor="0x0", width="465", height="465", frameRate="60")]
	public class Main2 extends Sprite {

		public function Main2():void {
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private var pmouseX:Number;
		private var pmouseY:Number;

		private function init(e:Event = null):void {
			removeEventListener(Event.ADDED_TO_STAGE, init);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
			stage.quality = StageQuality.MEDIUM;

			addChild(new Bitmap(canvas));

			numCols = width / resolution;
			numRows = height / resolution;

			vsquaresVectors = new Vector.>(numRows + 1);
			vbuffersVectors = new Vector.>(numRows + 1);

			for (var i:int = 0; i < numParticles; i++) {
				particles[i] = new Particle(Math.random() * width, Math.random() * height);
			}

			for (var col:int = 0; col <= numCols; col++) {
				vsquaresVectors[col] = new Vector.(numCols + 1);
				vbuffersVectors[col] = new Vector.(numCols + 1);
				for (var row:int = 0; row <= numRows; row++) {
					vsquaresVectors[col][row] = new Vsquare(col * resolution, row * resolution);
					vbuffersVectors[col][row] = new Vbuffer(col * resolution, row * resolution);
				}

				vsquaresVectors[col].fixed = true;//付け足し
				vbuffersVectors[col].fixed = true;//付け足し
			}

			vsquaresVectors.fixed = true;//付け足し
			vbuffersVectors.fixed = true;//付け足し

			addEventListener(Event.ENTER_FRAME, draw);
		}

		private function draw(e:Event):void {
			mouseX = this.mouseX;
			mouseY = this.mouseY;

			var axvel:int = mouseX - pmouseX;
			var ayvel:int = mouseY - pmouseY;

			mouseXvel = (axvel != mouseXvel) ? axvel : 0;
			mouseYvel = (ayvel != mouseYvel) ? ayvel : 0;

			for (var col:int = 0; col < numCols; col++) {
				for (var row:int = 0; row < numRows; row++) {
					vbuffersVectors[col][row].updatebuf(col, row);
					//何にも無い色の設定
					vsquaresVectors[col][row].color = 32;
				}
			}

			for each(var p:Particle in particles) {
				p.updatepos();
			}

			canvas.lock();//付け足し
			for (col = 0; col < numCols; col++) {
				for (row = 0; row < numRows; row++) {
					vsquaresVectors[col][row].addbuffer(col, row);
					vsquaresVectors[col][row].updatevels(axvel, ayvel);
					vsquaresVectors[col][row].display(col, row);
				}
			}
			canvas.unlock();//付け足し

			pmouseX = mouseX;
			pmouseY = mouseY;
		}

		private function mouseDownHandler(e:Event):void {
			mousePressed = true;
		}

		private function mouseUpHandler(e:Event):void {
			mousePressed = false;
		}
	}

}

import flash.display.BitmapData;
var width:int = 200;
var height:int = 200;
var mousePressed:Boolean;
var mouseX:Number = 0;
var mouseY:Number = 0;
var resolution:int = 5;
var penSize:int = 30;
var numCols:int;
var numRows:int;
var numParticles:int = 7000;
var vsquaresVectors:Vector.>;
var vbuffersVectors:Vector.>;
var particles:Vector. = new Vector.(numParticles, true);
var pcount:int = 0;
var mouseXvel:int = 0;
var mouseYvel:int = 0;
var canvas:BitmapData = new BitmapData(width, height, false, 0x0);

class Particle{
	public function Particle(xIn:Number, yIn:Number) {
		x = xIn;
		y = yIn;
	}

	public var x:Number;
	public var y:Number;
	public var xvel:Number = 0;
	public var yvel:Number = 0;
	public var pos:int = 0;

	public function updatepos():void {
		//var col1:Number;//使われていない
		if (x > 0 && x < width && y > 0 && y < height) {
			var col:int = int(x / resolution);//自身が属しているvsquareを見つける
			var row:int = int(y / resolution);
			var vsquare:Vsquare = vsquaresVectors[col][row];

			var ax:Number = (x % resolution) / resolution;
			var ay:Number = (y % resolution) / resolution;

			xvel += (1 - ax) * vsquaresVectors[col][row].xvel * 0.05;
			yvel += (1 - ay) * vsquaresVectors[col][row].yvel * 0.05;

			xvel += ax * vsquaresVectors[col + 1][row].xvel * 0.05;
			yvel += ax * vsquaresVectors[col + 1][row].yvel * 0.05;

			xvel += ay * vsquaresVectors[col][row + 1].xvel * 0.05;
			yvel += ay * vsquaresVectors[col][row + 1].yvel * 0.05;

			//自身がいるマスの色を濃くする
			vsquare.color += 4;

			x += xvel;
			y += yvel;
		}
		else {
			x = Math.random() * width;
			y = Math.random() * height;
			xvel = 0;
			yvel = 0;
		}

		xvel *= 0.5;
		yvel *= 0.5;
	}
}

class Vbuffer {
	public function Vbuffer(xIn:int, yIn:int) {
		x = xIn;
		y = yIn;
		pressureX = 0;
		pressureY = 0;
	}

	public var x:int;
	public var y:int;
	public var xvel:Number = 0;
	public var yvel:Number = 0;
	public var pressureX:Number = 0;
	public var pressureY:Number = 0;
	public var pressure:Number = 0;

	public function updatebuf(col:int, row:int):void {
		if (col > 0 && col < numCols && row > 0 && row < numRows) {
			pressureX = (
				  vsquaresVectors[col - 1][row - 1].xvel * 0.5
				+ vsquaresVectors[col - 1][row].xvel
				+ vsquaresVectors[col - 1][row + 1].xvel * 0.5
				- vsquaresVectors[col + 1][row - 1].xvel * 0.5
				- vsquaresVectors[col + 1][row].xvel
				- vsquaresVectors[col + 1][row + 1].xvel * 0.5
			);

			pressureY = (
				  vsquaresVectors[col - 1][row - 1].yvel * 0.5
				+ vsquaresVectors[col][row - 1].yvel
				+ vsquaresVectors[col + 1][row - 1].yvel * 0.5
				- vsquaresVectors[col - 1][row + 1].yvel * 0.5
				- vsquaresVectors[col][row + 1].yvel
				- vsquaresVectors[col + 1][row + 1].yvel * 0.5
			);

			pressure = (pressureX + pressureY) * 0.25;
		}
	}
}

import flash.geom.Rectangle;
class Vsquare{

	public function Vsquare(xIn:int, yIn:int) {
		x = xIn;
		y = yIn;
	}

	public var x:int;
	public var y:int;
	public var xvel:Number = 0;
	public var yvel:Number = 0;
	public var color:Number = 0;

	public function addbuffer(col:int, row:int):void {
		if (col > 0 && col < numCols && row > 0 && row < numRows) {
			xvel += (
				  vbuffersVectors[col - 1][row - 1].pressure * 0.5
				+ vbuffersVectors[col - 1][row].pressure
				+ vbuffersVectors[col - 1][row + 1].pressure * 0.5
				- vbuffersVectors[col + 1][row - 1].pressure * 0.5
				- vbuffersVectors[col + 1][row].pressure
				- vbuffersVectors[col + 1][row + 1].pressure * 0.5
			) * 0.25;

			yvel += (
				  vbuffersVectors[col - 1][row - 1].pressure * 0.5
				+ vbuffersVectors[col][row - 1].pressure
				+ vbuffersVectors[col + 1][row - 1].pressure * 0.5
				- vbuffersVectors[col - 1][row + 1].pressure * 0.5
				- vbuffersVectors[col][row + 1].pressure
				- vbuffersVectors[col + 1][row + 1].pressure * 0.5
			) * 0.25;
		}
	}

	public function updatevels(mvelX:int, mvelY:int):void {
		if (mousePressed) {
			var dx:Number = x - mouseX;
			var dy:Number = y - mouseY;

			var dist:Number = Math.sqrt(dy * dy + dx * dx);
			if (dist < penSize) {
				if (dist < 4) dist = penSize;
				var mod:Number = penSize / dist;
				xvel += mvelX * mod;
				yvel += mvelY * mod;
			}
		}

		xvel *= 0.99;
		yvel *= 0.99;
	}

	public function display(i:int, u:int):void {
		var tempColor:uint = 0;

		if (color > 255) color = 255;
		if (i > 0 && i < numCols - 1 && u > 0 && u < numRows - 1) {
			tempColor = (
				  vsquaresVectors[i][u + 1].color
				+ vsquaresVectors[i + 1][u].color
				+ vsquaresVectors[i + 1][u + 1].color * 0.5
			) * 0.4;
			tempColor = int(tempColor + color * 0.5);
		}
		else {
			tempColor = int(color);
		}

		var rgb:uint = tempColor << 16 | tempColor << 8 | tempColor;
		canvas.fillRect(new Rectangle(x, y, resolution, resolution), rgb);
	}
}

うずまきエフェクト DisplacementMapFilterで

うずまき。

うずまき – wonderfl build flash online

球もつくりました。けど、これは偶然うまくいってる。
mapBitmap作る部分が間違ってると思う。createDMF関数の中がおかしい。
なので参考にしない方がいいです。すみません。
ひょっとすると渦巻きも…?

DisplacementMapFilter 球 – wonderfl build flash online

DisplacementMapFilterのメモ

追記 2009/05/11
間違ってるとこも多いです。ちょこちょこ直していきます。

かなりくどく書きました。だらだらです。helpが意味不明すぎる。

なんでも自由に変形できる万能フィルタではない。誤解してた。そういう変形は今だとpixel Bender使うのかな…?
そうするとDisplacementMapFilterの使い道ってすごく限られてくるのかと疑問に思ってきた。

おおまかな考え方

通常だと、現在地点にどの位の値を加えれば目的地に着くか? で考えるけど、DisplacementMapFilterだと逆。
目的地に引き寄せる力は何か?を考える。 その力を色に変換する。

例えば

現在地 x = 10の地点を、目的地 x = 50に移したいとする。

《通常の考え方》
普通にxに40足す。

《DisplacementMapFilterの考え方》
フィルタによって x = 50に移る点は、x = 10の地点だとしたい。 そうするためにはx = -40の力を生む色を塗る。

色は、目的地に塗る。(この例ではx = 50の地点)

DisplacementMapFilterでの色の決め方

ヘルプには

このフィルタでは次の式を使用します。
dstPixel[x, y] = srcPixel[x + ((componentX(x, y) – 128) * scaleX) / 256, y + ((componentY(x, y) – 128) *scaleY) / 256)

と書いてある。
flashPlayerはこの式を使って変形する、っていう事かな?

どういう事か?

色の強さは0~255の256段階。 このままだとマイナス方向が指定出来ないため、 真ん中の128を中間地点とする。

このhelpには中間値は127と書いてある。間違い??

真ん中からの離れ具合から強さを決める。 そこから128離れるとき、つまり256の時、 50パーセントの力になる(でも色の最大値は255なので僅かな誤差が出る)。
同様に、-128離れるとき、-50%の力になる。(100パーセントではないので注意。)

色の決め方の式

上の考え方から、

移動させる割合 = 移動させる距離 / 最大移動距離
色の強さ = (0x80 * 移動させる割合) + 0x80

このままだと最大値が0x100になってしまい、色の最大値である0xFFを超えてしまう。そのため、中間値を0x7Fとする。127と書いてあるのはこのこと?

色の強さ = (0x80 * 移動させる割合) + 0x7F

※ 0x7Fは10進数だと127、0x80は10進数だと128

x方向の移動のみ考える。
現在の座標は(0, 0)で、x方向に100px移動させたいとする。 まず目的地である(100, 0)の地点に色を塗ることにする。 この色を塗った地点に吸い寄せる力の色に青を使うとする。

目的地に引き寄せられるような色を決める

問題は何色にするか。 DisplacementMapFilterを作製する際、scaleX, scaleYという値を決める。
普通、100%の際にmaxの値を取るものだが、 DisplacementMapFilterはmaxが50%という変な設定なので、 scaleX, scaleYには取り得る最大値の2倍を設定。
ここではscaleXの値を100 * 2 = 200とする。
(0,0)から(100、0)に移動させたい。 ここは逆に考えます。 (100,0)の地点に吸い寄せられる地点を(0,0)にしたい、と

そのように設定をするためには、何色で塗ればいいのか?
x方向の距離は、目的地を基準として考えるので、0 – 100 = -100 (目的地から-100すると現在地になるという事)
移動させる距離を、最大値との比率で考える。 すると、-100 / 200 = 0.5
さっきの色の話を見直すと、-50%の力を作る色は、 中間地点の128から-50%の値である0×0。

フィルタを作るときは、大体これをfor文でmapBitmapの全ピクセルに実行する。
各ピクセルで、適用先のピクセルを求めていく。

色を決める式を、ヘルプに書いてある式から求めると

先に挙げた式でも、こちらでもやってることは一緒。
先に出たヘルプの式をxの値だけに絞って整理してみる。

フィルタが適用されるx値 = 移動先のx値 + ((色の強さ - 0x80) * dmf最大値) / 0x100

(dmf最大値はDisplacementMapFilterのscaleX, scaleYの値。変形する際の最大移動距離の2倍にする。)

↓変形

フィルタが適用されるx値 - 移動先のx値 = ((色の強さ - 0x80) * dmf最大値) / 0x100

↓変形(フィルタが適用されるx値 - 移動先のx値 を 移動させる距離 に置き換え。)

移動させる距離 = ((色の強さ - 0x80) * dmf最大値) / 0x100

↓変形

移動させる距離 * 0x100 = (色の強さ - 0x80) * dmf最大値

↓変形

( 移動させる距離 * 0x100 ) / dmf最大値 = 色の強さ - 0x80

↓変形

( 移動させる距離 * 0x100 ) / dmf最大値 + 0x80 = 色の強さ

入れ替えて、

色の強さ = ( 移動させる距離 * 0x100 ) / dmf最大値 + 0x80

このままだと最大値が0x100になってしまい、色の最大値である0xFFを超えてしまう。そのため、中間値を0x7Fとする。

色の強さ = ( 移動させる距離 * 0x100 ) / dmf最大値 + 0x7F

これらを使ったテスト。マウス座標に移す変形をする。
ステージサイズ横100 * 縦100で作ってるので拡大して表示されます。

次回はよくある球へのマッピングをやってみます。

追記 2009/05/11
色の決め方の式を追加。

その式つかったwonderflにリンク差し替え。

Clothシミュレーションもどき

2009/04/29 追記
2Dだけど、出来たっぽいです。回転の問題もクリアできました。

何回か布っぽいのを作るシリーズをやってましたが、
今までの物は、ちゃんと点どうしが連結されたものではありませんでした。

今回はちゃんと連結して布のシミュレーションぽい物ができたのでUPします。
しかし、あくまで『それらしい物』であって、z軸も考慮してませんし、怪しい部分が多々あります。

最近Clothシミュレーションよく見ますね。js実装のとか。
2009-02-11 – 最速チュパカブラ研究会
解説も丁寧で凄いなぁ。ソース読んで勉強しよう。

初wonderFlです。

ドラッグで移動、ctrlキー押しながらドラッグで固定。
固定した点をダブルクリックで解除です。

最初に格子状に並べているので布のようですが、
最初に何らかの形に並べれば、その形を維持するように動くはずです。

jointメソッドで隣り合った点どうしを連結します。
ここがどうしても冗長でわかりにくくなってしまってます。
コメントアウトで色々書いておきました。

2009/04/13 追記
ずいぶん改善できました。
布 : 改善 | wonderfl build flash online
最初は8方向に対して連結していましたが、上下左右の4方向でOKでした。
ソースも短くなり、ずいぶん分かりやすくなりました。
上の2009-02-11 – 最速チュパカブラ研究会様のソースを参考にしてます。やっぱ凄いです。

一番最初に布っぽい物を作った時も、それぞれを連結するって事は考えたんですが、やり方が思いつかなった。
今回は実直に総当たりな感じで試しにやってみたら上手くいきました。
上手いやり方を考えるのもいいけど、泥臭いやりかたで試すの大事ですね。

Player10から加わったGraphicsPathCommandを使ってラインを描画するバージョンも作ってみました。

追記
wonderflの使い方が良く分かっておらず、forkしないで新しく作ってました。そちら削除させてもらいました。favoriteに入れてくれた方がいらっしゃったのですが、ごめんなさい!

でも少し重くなりますね。今回はこの方法は適してないんでしょうね。
drawLine関数だけ違います。他の部分は全く同じ。

あとはテクスチャですが、テクスチャを貼るのは結構簡単なようです。
AdvancED ActionScript 3.0 Animationに丁寧に書かれてました。
球体のテクスチャ付き3D描画についても書かれてますよ!

それから、回転させるって以前言ったものの、まだ回転させる方法が思い浮かびません。
ためしに思いつきで作ったのですが、上手く動きませんでした。
なにをもって回転とするのかが良くわかってません。

回転の失敗作も近いうちにUPしようと思います。

AdvancED ActionScript 3.0 Animation

名著 ActionScript3.0アニメーションの続編(洋書)。

_img_cover_9781430216087.jpg

アマゾンで買っちゃったんですが、
AdvancED ActionScript 3.0 Animation | Book Details
上のリンク先で電子書籍(ebookって書いてある。pdfかな?pdfでした。)としても買えるようですね。
コピペが出来るわけです。ということは分からない単語が出てきても、すぐに辞書ひける。
まるまる1ページ翻訳とかもイケますよね。

…しまった!! 早まったかも!?

上記リンクからは、試し読みが出来るだけでなく、書籍内で使われているサンプルファイルもダウンロードできますね。ふとっぱら!!

(追記)
買ってしまいました。paypalとカードの支払いに対応してました。
1 日本円 = 0.0104302 米ドルで、$27.99 → ¥2,684でした。
形式はpdf。

ホーム > flash

Return to page top