ActionScript 3.0で始めるオブジェクト指向スクリプティング

第33回 遠近法の投影

この記事を読むのに必要な時間:およそ 5 分

PerspectiveProjectionクラスで遠近法を操作する

PerspectiveProjectionクラスを使って,メインタイムラインの遠近法を変えてみる。DisplayObjectインスタンスがもつPerspectiveProjectionオブジェクトには,ふたつのプロパティを経てアクセスする。

まず,DisplayObject.transformプロパティは,DisplayObjectインスタンスに対する2次元ないし3次元の座標やカラーの変換を管理するTransformオブジェクトへの参照となる。そしてつぎに,Transform.perspectiveProjectionプロパティにより,DisplayObjectインスタンスに適用される遠近法の設定となるPerspectiveProjectionオブジェクトの参照が得られる図6)⁠なお,後の回で解説する3次元空間の座標変換を扱うMatrix3Dオブジェクトも,Transformクラスのプロパティから参照する。

図6 プロパティDisplayObject.transformからTransform.perspectiveProjectionの参照を得る

図6 プロパティDisplayObject.transformからTransform.perspectiveProjectionの参照を得る

それでは,前掲スクリプト1の消失点を動かしてみよう。用いるプロパティは,PerspectiveProjection.projectionCenterだ。xy座標をPointオブジェクトで設定する。前掲フレームアクション(スクリプト1)につぎのステートメントを加えると,消失点がマウスポインタの座標に合わせて動く図7)⁠

var myPerspective:PerspectiveProjection = transform.perspectiveProjection;
addEventListener(Event.ENTER_FRAME, xMoveViewPoint);
function xMoveViewPoint(eventObject:Event):void {
  myPerspective.projectionCenter = new Point(mouseX, mouseY);
}

図7 消失点がマウスポインタの座標に合わせて動く

図7 消失点がマウスポインタの座標に合わせて動く

さらに,視野角も変えてみたい。PerspectiveProjection.fieldOfViewプロパティに,0より大きく180より小さい度数値で定める。前掲フレームアクション(スクリプト1)にさらにつぎのスクリプトを加えると,ステージをクリックしたとき,現行の視野角に50度を加え図8右図)⁠再度クリックするともとの視野角に戻る図8左図)⁠前述のとおり,視野角は大きいほど遠近の差が際立つ。

var standardView:Number = myPerspective.fieldOfView;
var bStandard:Boolean = true;
stage.addEventListener(MouseEvent.CLICK, xChangeFieldOfView);
function xChangeFieldOfView(eventObject:MouseEvent):void {
  if (bStandard = ! bStandard) {
    myPerspective.fieldOfView = standardView;
  } else {
    myPerspective.fieldOfView = standardView + 50;
  }
}

図8 ステージをクリックすると視野角が拡大する

図8 ステージをクリックすると視野角が拡大する

なお,前掲リスナー関数xChangeFieldOfView()のif条件は,式の両辺を比較しているのではなく,代入文であることに注意してほしい。演算子!は論理否定で,ブール(論理)値を反転する。したがって,変数のtrueとfalseを反転して代入したうえで,その反転後の値を条件として評価している。

さて,以上に述べた消失点と視野角の操作を前掲スクリプト1に加えたのが,つぎのスクリプト2だ。

スクリプト2 Shapeインスタンスが配置された3次元空間の消失点と視野角を変える

// タイムライン: メイン
// フレームアクション
var myPerspective:PerspectiveProjection = transform.perspectiveProjection;
var standardView:Number = myPerspective.fieldOfView;
var bStandard:Boolean = true;
addEventListener(Event.ENTER_FRAME, xMoveViewPoint);
stage.addEventListener(MouseEvent.CLICK, xChangeFieldOfView);
xGreateShapes(100);
function xMoveViewPoint(eventObject:Event):void {
  myPerspective.projectionCenter = new Point(mouseX, mouseY);
}
function xChangeFieldOfView(eventObject:MouseEvent):void {
  if (bStandard = ! bStandard) {
    myPerspective.fieldOfView = standardView;
  } else {
    myPerspective.fieldOfView = standardView + 50;
  }
}
function xGreateShapes(nCount:uint):void {
  for (var i:uint = 0; i < nCount; i++) {
    var nColor:uint = xGetRandom(0xFFFFFF, 0, true);
    var nRadius:Number = xGetRandom(10);
    var myShape:Shape = xCreateCircle(nRadius, nColor);
    addChild(myShape);
    myShape.x = xGetRandom(stage.stageWidth);
    myShape.y = xGetRandom(stage.stageHeight);
    myShape.z = xGetRandom(stage.stageWidth);
  }
}
function xCreateCircle(nRadius:Number, nColor:uint = 0):Shape {
  var myShape:Shape = new Shape();
  var myGraphics:Graphics = myShape.graphics;
  myGraphics.beginFill(nColor);
  myGraphics.drawCircle(0, 0, nRadius);
  myGraphics.endFill();
  return myShape;
}
function xGetRandom(nMax:Number = 1, nMin:Number = 0, bInt:Boolean = false):Number {
  if (nMax < nMin) {
    var nTemp:Number = nMax;
    nMax = nMin;
    nMin = nTemp;
  }
  var nRandom:Number = Math.random();
  if (bInt) {
    return Math.floor(nRandom * (nMax - nMin + 1) + nMin);
  } else {
    return nRandom * (nMax - nMin) + nMin;
  }
}

ところで,動作結果を注意深く見ると,ある不自然なことに気づくかもしれない。それは,インスタンスのz座標値の大小と画面上の表示の重ね順が,必ずしも一致していないということだ。つまり,z座標は奥のはずのインスタンスが,手前のインスタンスの前に表示されたりする。なぜなら,Flash Playerでは,インスタンスのz座標値とはまったく別に表示の重ね順が決まるからだ。

したがって,表示の重ね順をいかにz座標値と一致させるかは,3次元空間を扱ううえでのひとつの大きな課題となる。この問題については,3次元空間の操作についてもっと詳しく説明したあとで改めて採上げたい。つぎは,3次元空間座標の回転について解説する。

今回解説した次のサンプルファイルがダウンロードできます。

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書