[AS3] Flash CS5に潜む謎のクラスWorld II − 内緒の物理エンジン [Edit]

以前の記事でご紹介した「Flash CS5に潜む謎のクラスWorld」は、非ドキュメントの物理エンジンに含まれているようです。昨年11月に書かれた英文blogに、ライブラリの中身を探った解説がありました。そのblogのテスト用コードをもとに、簡単なサンプルをつくってみました。

参考にしたのは、Significant Data「Flash CS5 Built-in Physics Discovered」です。スクリプトはFlash Professional CS5でしか書出せず、CS5.5でもコンパイルエラーになります。またもちろん、正規サポートはされません。


01 Flash Professional CS5の物理エンジンを内緒で使う

以下のスクリプト001をFlash Professional CS5のフレームアクションとしてコピー&ペーストします。ステージには何も置きません。[ムービープレビュー]でステージをクリックすると、ランダムに置かれたインスタンスの半分が落下運動をします。

図001■ランダムに置かれたインスタンスの半分が落下運動する
FF1109231_001.gif FF1109231_002.gif
FF1109231_003.gif

スクリプト001■物理エンジンを試す
const COUNT:uint = 50;
var instances:Vector.<Shape> = drawShapes(COUNT);
var physics:PhysicsManager = new PhysicsManager(stage);
var myWorld:World = physics.createWorld();
assignPhysics();
myWorld.enableCollisions(true);
myWorld.setGravity(new Point(0, 200));
stage.addEventListener(MouseEvent.CLICK, startPhysics);
function startPhysics(eventObject:MouseEvent):void {
	addEventListener(Event.ENTER_FRAME, animatePhysics);
}
function assignPhysics():void {
	var myPoint:Point = new Point(1, 1);
	for (var i:uint = 0; i < COUNT; i++) {
		var instance:DisplayObject = instances[i];
		var physicsObject:PhysObj = myWorld.addPhysObj(instance, myPoint, 0, false);
		if (i % 2) {
			physicsObject.setNonMoving(true);
		}
	}
}
function animatePhysics(eventObject:Event):void {
	myWorld.updateAllObjects();
	myWorld.step();
}
function drawShapes(count:uint):Vector.<Shape> {
	var nStageWidth:int = stage.stageWidth;
	var nStageHeight:int = stage.stageHeight;
	var nWidth:Number = 25;
	var nHeight:Number = 5;
	var instances:Vector.<Shape> = new Vector.<Shape>(count);
	for (var i:uint = 0; i < count; i++) {
		var myShape:Shape = new Shape();
		var myGraphics:Graphics = myShape.graphics;
		myGraphics.beginFill(uint(0xFFFFFF * Math.random()));
		myGraphics.drawRect(-nWidth / 2, -nHeight / 2, nWidth, nHeight);
		myGraphics.endFill();
		addChild(myShape);
		instances[i] = myShape;
		myShape.x = nStageWidth * Math.random();
		myShape.y = nStageHeight * Math.random();
		myShape.rotation = 360 * Math.random();
	}
	return instances;
}

非ドキュメントの機能ですので、ごく簡単にだけご説明します。まず、関数drawShapes()はタイムラインにShapeインスタンスをランダムにつくったうえで、Vectorオブジェクト(Shapeベース型)に納めて返します。試す手間がかからないように、スクリプトで配置しただけで、物理エンジンの中身には関わりません。前出のblogではMovieClipインスタンスを[ライブラリ]から配置しています。

物理エンジンのシミュレーションは、PhysicsManagerインスタンス(physics)からPhysicsManager.createWorld()メソッドにより件のWorldインスタンス(myWorld)をつくるところから始まります。

そして、タイムラインに置いたDisplayObject(Shape)インスタンスをWorld.addPhysObj()メソッドによりPhysObjオブジェクトとして加え、PhysObj.setNonMoving()メソッドで動かすかどうかを定めます。

さらに、メソッドWorld.enableCollisions()で衝突判定、World.setGravity()で重力を設定します。あとは、DisplayObject.enterFrameイベントで、World.updateAllObjects()World.step()メソッドを呼出すことにより自然落下のアニメーションが行われます。

前出英文blogに引用のビデオに示されたとおり、Adobe MAX 2009ではインバース・キネマティクスのフレームワークに含まれる物理エンジンを[物理]パネルとともに公開する予定でした。しかし、製品でその公開は実現せず、非ドキュメントのクラスとして残ったようです。

内部的に物理エンジンはあるはずですが、CS5.5ではもはやアクセスも許されなくなったのでしょう。できれば、次期バージョンで公開してもらいたいものです。


02 物理エンジンのライブラリPffLibをCS5.5でもがんばって使う

物理エンジンのAPIは、ライブラリPffLib.swcとしてFlash Professional CS5のアプリケーションの中に含まれています。これをコピーすれば、CS5.5でも使えるようです。もちろん、サポート外であることは変わりません。

具体的には、アプリケーションのAdobe Flash CS5/Common/Configuration/ActionScript 3.0/libsフォルダにPffLib.swcがあります(図002)。

図002■Flash Professional CS5アプリケーション内のPffLib.swc
FF1109231_004.gif

このPffLib.swcをディスクの任意の場所(下図003ではユーザーのフォルダmylibs/libsとした)にコピーします。そして、CS5.5の[パブリッシュ設定]から[ActionScript 3.0の詳細設定]ダイアログボックスを開き、[ライブラリパス]にPffLib.swcがあるフォルダを加えます(図003)。

図003■CS5.5の[ActionScript 3.0の詳細設定]ダイアログボックスで[ライブラリパス]を追加
FF1109231_005.gif

筆者の環境では、これでCS5.5でも前掲スクリプト001が動作しました。なお、あくまで自己責任でお楽しみください。

コメント

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事