F-Siteのセミナーに行って、野中先生の3Dの講義を聞いてきました。
サンプルをそのままコピーしたものが下になります。
ぺらぺらなのもなんなので、もう少し立体ぽくしたいなと思ってSpriteを4枚にしてみたのが下になります。
3DのZ座標の前後関係よりも、Spriteの重なり順の方が優先されるようで、複数のSpriteを3D的に動かそうとすると、前後関係がおかしくなってしまいます。
そこで、Z座標の前後関係を自分で調整すると下のようになります。
コードは以下のような感じです。
重要な部分は野中先生のコードの受け売りです。
// タイムライン: メイン
// 第1フレームアクション
var nX:Number = mySprite.x;
var nY:Number = mySprite.y;
var nDeceleration:Number = 0.1;
mySprite.z = 0;
var spriteParts:Array=[mySprite.front,mySprite.back,mySprite.top,mySprite.bottom];
addEventListener(Event.ENTER_FRAME, xRotate);
function xRotate(eventObject:Event):void {
var nRotationY:Number = (mouseX - nX)*nDeceleration;
var nRotationX:Number = (mouseY - nY)*nDeceleration;
// 3次元座標空間でインスタンスを回転
mySprite.transform.matrix3D.appendTranslation(-nX, -nY, 0); // 親タイムラインの基準点に移動
for(var i:uint=0;i<spriteParts.length;i++){
Sprite(spriteParts[i]).transform.matrix3D.appendRotation(nRotationY,Vector3D.Y_AXIS);
Sprite(spriteParts[i]).transform.matrix3D.appendRotation(nRotationX,Vector3D.X_AXIS);
}
mySprite.transform.matrix3D.appendTranslation(nX, nY, 0); // 位置を戻す
spriteParts.sort(sortOnZ);
for(var j:uint=0;j<spriteParts.length;j++){
mySprite.setChildIndex(spriteParts[j],j);
}
function sortOnZ(a:Sprite, b:Sprite):Number {
var aZ:Number = a.z;
var bZ:Number = b.z;
if(aZ > bZ) {
return 1;
} else if(aZ < bZ) {
return -1;
} else {
//aZ == bZ
return 0;
}
}
}
ちょっとしたポイントは、キューブ状に配置したMCを回転させてしまうと、z座標が変わらないので、各パネルのMCをそれぞれ別々に回転させた後、zの値でソートして、重ね順を変える、という点。
自分でやらないでもCS4でちゃんとしてくれる方法とかあるのだろうか?