以前の記事でご紹介した「Flash CS5に潜む謎のクラスWorld」は、非ドキュメントの物理エンジンに含まれているようです。昨年11月に書かれた英文blogに、ライブラリの中身を探った解説がありました。そのblogのテスト用コードをもとに、簡単なサンプルをつくってみました。
参考にしたのは、Significant Data「Flash CS5 Built-in Physics Discovered」です。スクリプトはFlash Professional CS5でしか書出せず、CS5.5でもコンパイルエラーになります。またもちろん、正規サポートはされません。
以下のスクリプト001をFlash Professional CS5のフレームアクションとしてコピー&ペーストします。ステージには何も置きません。[ムービープレビュー]でステージをクリックすると、ランダムに置かれたインスタンスの半分が落下運動をします。
図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ではもはやアクセスも許されなくなったのでしょう。できれば、次期バージョンで公開してもらいたいものです。
物理エンジンの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

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

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