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

第38回 z座標値に応じて重ね順を変える

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

前回の第37回「インスタンスの回転と重ね順」は,ふたつの面を前後に置いて,y軸で水平に回した。今回はさらに2面増やし,矩形の画像で四方を囲んで,最後は上下左右に回してみたい図1)。前回に続き,面の重ね順をどう決めるかが課題だ。

図1 四方に置いた面を上下左右に回す

図1 四方に置いた面を上下左右に回す

z座標値を調べる仕組みづくり

4面を水平に回すだけなら,前回のスクリプト2と同じように,面が納められた容れ物のSpiteインスタンスの回転角で並べ替えることもできる。しかし,垂直にも回すとなると,ことはそう単純ではない。そこで,4つの面それぞれのz座標で重ね順を決めることにしよう。前回のスクリプト2に手を加えていくことにする。

まず,面のどの位置の座標を調べるかが問題となる。[ライブラリ]のビットマップ(BitmapDataインスタンス)は,Bitmapオブジェクトの基準点が左上角になるように配置された第37回図2再掲の位置座標参照)。しかし,左上角のz座標値を比べたのでは,それぞれの面の前後はわからない。

第37回図2 Spriteインスタンスの基準点が中心となるように面の位置を定める(再掲)

第37回図2 Spriteインスタンスの基準点が中心となるように面の位置を定める(再掲)

比べるなら,それぞれの面の中央の座標がよいだろう。容れ物のSpriteインスタンスの基準点は四方を囲む面の中心なので,各面とxまたはz軸との交点で決めるということだ図2)。ところが,BitmapDataクラスには位置座標のプロパティがない。つまり,面の左上角がBitmapオブジェクトの基準点であることは動かせない。

図2 各面の中央をxまたはz軸が貫く

図2 各面の中央をxまたはz軸が貫く図2 各面の中央をxまたはz軸が貫く

そのため,4つの面のBitmapオブジェクトは,それぞれSpriteインスタンスで包むことにする。そして,入れ子のBitmapオブジェクトの位置をずらすことによって,親Spriteインスタンスの基準点を面の中心に定める図3)。そうすれば,面のSpriteインスタンスのz座標でそれらの前後が決められる。これで面のz座標値を調べる仕組みが整った。

図3 Bitmapオブジェクトの位置はSpriteインスタンスの基準点が中心になるよう左上にずらす

図3 Bitmapオブジェクトの位置はSpriteインスタンスの基準点が中心になるよう左上にずらす

面をつくって返す関数の修正

つぎは,前回のスクリプト2に具体的な手を加えていく。第1に,面のBitmapオブジェクトをつくって返していた関数xCreateFace()だ。これを,Bitmapオブジェクトが入れ子になったSpriteインスタンスで返すよう修正する。引数の宣言はそのままだ。ただし,Spriteインスタンスの基準点が面の中央になるので,関数を呼出すときに渡す座標値がつぎのように変わる。なお,面のSpriteインスタンスを納める変数名も改めた。

// var frontBitmap:Bitmap = xCreateFace(Image0, -nUnit, -nUnit, -nUnit);
// var backBitmap:Bitmap = xCreateFace(Image1, nUnit, -nUnit, nUnit, 180);
var frontSprite:Sprite = xCreateFace(Image0, 0, 0, -nUnit);
var backSprite:Sprite = xCreateFace(Image1, 0, 0, nUnit, 180);

関数xCreateFace()には,以下のように手を加えた。戻り値のデータ型をSpriteで指定し,面のビットマップが納められたBitmapオブジェクトは,新たにつくるSpriteインスタンスで包む。Bitmapオブジェクトの位置は,面の中央にSpriteインスタンスの基準点がくるように,左上にずらす。そのうえで,引数値によりSpriteインスタンスの位置と回転角を定めた。

// function xCreateFace(myBitmapData:Class, nX:Number, nY:Number, nZ:Number, nRotationY:Number = 0):Bitmap {
function xCreateFace(myBitmapData:Class, nX:Number, nY:Number, nZ:Number, nRotationY:Number = 0):Sprite {
  var myBitmap:Bitmap = new Bitmap(new myBitmapData(0, 0));
  var faceSprite:Sprite = new Sprite();
  faceSprite.addChild(myBitmap);
  // myBitmap.x = nX;
  // myBitmap.y = nY;
  // myBitmap.z = nZ;
  // myBitmap.rotationY = nRotationY;
  myBitmap.x = -myBitmap.width / 2;
  myBitmap.y = -myBitmap.height / 2;
  faceSprite.x = nX;
  faceSprite.y = nY;
  faceSprite.z = nZ;
  faceSprite.rotationY = nRotationY;
  // return myBitmap;
  return faceSprite;
}

これで,前回のスクリプト2とムービーの見た目は変わらないものの,ふたつの面のSpriteオブジェクトがつくられ,容れ物の親Spriteインスタンス内に 配置される。この段階で[ムービープレビュー]を確かめる場合は,スクリプト中の面のSpriteオブジェクトの変数名を直す必要がある。また,面の重ね順を整える関数xSetOrder()は,前項で述べたとおり処理を大幅に書替えるので,一旦本体をコメントアウトしておこう。

// mySprite.addChild(frontBitmap);
// mySprite.addChild(backBitmap);
mySprite.addChild(frontSprite);
mySprite.addChild(backSprite);

function xSetOrder():void {
  /*
  var nTop:uint = mySprite.numChildren - 1;
  if (mySprite.rotationX > 90) {
    mySprite.setChildIndex(backBitmap, nTop);
  } else {
    mySprite.setChildIndex(frontBitmap, nTop);
  }
  */
}

著者プロフィール

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

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

URLhttp://www.FumioNonaka.com/

著書

コメント

コメントの記入