2010.1.21
Box2D(Box2DFlashAS3)によるActionScript物理シミュレーション

●第8回:物体の制御3(力を加えることによる回転)

◆移動との類似点

まず、更新が大変滞ったことをお詫び申し上げます。
前回の更新から2ヶ月以上も経過してしまいました…。
その間に、α版とはいえ新しいマイナーバージョン(2.1a)が登場してしまいました。
このバージョンではFlash Player 9用(「Box2DFlashAS3 2.1a for Flash 9」)とFlash Player 10以降用(Box2DFlashAS3 2.1a)があります。
ほとんど触っていないのですが、両者の主な違いは配列にArrayを使うかVectorを使うかという点かなーと思います。

さて。
前回は力を加えることによる移動について触れてきました。その力には瞬間的なものと継続的なものがある、というところで使用するメソッドが異なっていました。
今回の回転でも同様の類似点があります。
つまり、コマのように瞬間的な回転力を与えるメソッドと、モーターのようなものによる継続的な回転力を与えるメソッドがあります。
前者はb2Body.SetAngularVelocity()メソッド、後者はb2Body.ApplyTorque()メソッドになります。

【M】b2Body.SetAngularVelocity(omega:Number) : void-物体の回転速度を設定する。

引数-omega:1秒あたりの回転角度(ラジアン)を表す数値。
戻り値-なし。

【M】b2Body.ApplyTorque(torque:Number) : void-物体に継続的な回転力を与える。

引数-torque:物体に与える回転力を表す数値。
戻り値-なし。

移動には、瞬間的な力を与えるメソッドとしてb2Body.SetLinearVelocity()メソッドとb2Body.ApplyImpulse()メソッドの2つがありました(違いは色々ありますが)。回転にはこのような類似のメソッドが複数あることはなく、瞬間的・継続的とも1つずつとなっています。

では、これらのメソッドをボタンクリックで実行してみます。
b2Body.SetLinearVelocity()メソッドは回転させるためと、停止させるための両方で使ってみようと思います。
以下、各ボタンのイベントリスナー部のみ掲載します。

private function _AngVel_btn_clickHandler(eventObj:Event):void {
    _bBall.WakeUp();
    _bBall.SetAngularVelocity(Math.PI * 4);
}
private function _AppTor_btn_mouseDownHandler(eventObj:Event):void {
    addEventListener(Event.ENTER_FRAME, _AppTor_enterFrameHandler);
    stage.addEventListener(MouseEvent.MOUSE_UP, _stage_mouseUpHandler);
}
private function _Stop_btn_clickHandler(eventObj:Event):void {
    _bBall.SetAngularVelocity(0);
}
//継続的な回転を終了させるイベントリスナー
private function _stage_mouseUpHandler(eventObj:Event):void {
    removeEventListener(Event.ENTER_FRAME, _AppTor_enterFrameHandler);
    stage.removeEventListener(MouseEvent.MOUSE_UP, _stage_mouseUpHandler);
}

b2Body.GetPosition()メソッドによる位置移動

↑グラフィックイメージをクリックすると、swfファイルが別ウィンドウで開きます。

→サンプルファイル【Box2D_08_01.zip

なお[Sleep]ボタンについては前回と同じ処理(b2Body.PutToSleep()メソッド)です。

◆回転の減衰率

上のサンプルでは一度回転させるとその回転は、[Stop]ボタンか[Sleep]ボタンで止めない限りずっと継続します。
これは回転の減衰率を設定していないためです。
回転の減衰率はb2BodyDef.angularDampingプロパティで設定します。前回扱った移動の減衰率を表すb2BodyDef.linearDampingプロパティと同様で、大抵の場合0(減衰なし)~1の間の小数値で指定します(1より大きい値も設定は可能)。

【P】b2BodyDef.angularDamping : Number-減衰率を表す数値。

次のサンプルは、上のサンプルにb2BodyDef.linearDampingプロパティを0.5にする設定を追加したものです。

swfを別ウィンドウで開く

→サンプルファイル【Box2D_08_02.zip

◆摩擦係数

物体には摩擦係数を設定することができます。
滑り台のような斜めの静体に箱をのせた場合、滑り落ちるかその場で留まっているかは摩擦係数が大きく影響します。
斜面に限らず平らな地面で円を回転させる場合にも摩擦係数が動作に影響を与えます。
…ということでやや無理やり摩擦を回転と関連付けて今回扱おうと思います。
摩擦係数はb2ShapeDef.frictionプロパティで指定します。通常は0(摩擦なし)~1の間の小数値で指定します(1より大きい値も設定は可能)。デフォルト値は0.2です。
当然といえば当然ですが、摩擦は複数の物体があって初めて意味があります。
2つの物体があった場合、一方のb2ShapeDef.frictionプロパティが0だと他方の値がいくつでも摩擦は発生しません。

【P】b2ShapeDef.friction : Number-摩擦係数を表す数値。

b2Body.GetPosition()メソッドによる位置移動

↑グラフィックイメージをクリックすると、swfファイルが別ウィンドウで開きます。

→サンプルファイル【Box2D_08_03.zip

次のサンプルは床のb2ShapeDef.frictionプロパティをデフォルト値の0.2、動体のb2ShapeDef.frictionプロパティを0に設定したものです。
左右に回転させるボタンがあり、これらのボタンで動体を回転させることができます。
摩擦が無いので動体は回転しても転がらず、同じ位置で滑っている状態になります。
ちなみにこのサンプルでは回転が減衰していきます。これは摩擦の影響ではなく動体のb2BodyDef.angularDampingプロパティ(回転の減衰率)を0.5に設定してあるためです。

次のサンプルは動体のb2ShapeDef.frictionプロパティ(摩擦係数)を0.5に設定したものです。
動体が回転すると床との摩擦で転がるのが分かります。

swfを別ウィンドウで開く

→サンプルファイル【Box2D_08_04.zip

このサイトへのご意見・ご感想は[takuya@haphands.com]までお願いします!