2008年4月4日金曜日

as2のTweenでY軸回転

まず thisのx, y, zがきまれば

function render() {
  var scale:Number = FOCAL_LENGTH
    / (Programs.FOCAL_LENGTH + this.z);
  this._xscale = this._yscale = scale * 100;
  this._x = VANISHING_POINT_X + (this.x * scale);
  this._y = VANISHING_POINT_Y + (this.y * scale);
  this.swapDepths(-this.z);
}

で疑似3Dに配置できる。

で Y軸回転した場合 yは変化しないので xとzさえもとめればよい。

xz座標の30度の位置に動かしたければ

var angleY:Number = 30 * Math.PI / 180;
this.x = RADIUS * Math.cos(angleY);
this.z = RADIUS * Math.sin(angleY);

でもとまる。

現在位置から30度移動したい場合は

var angleY:Number = 30 * Math.PI / 180;
var cosY:Number = Math.cos(angleY);
var sinY:Number = Math.sin(angleY);
var x1:Number = this.x * cosY - this.z * sinY;
var z1:Number = this.z * cosY + this.x * sinY;
this.x = x1;
this.z = z1;

となる。

これに Tweenを組み合わせる。

Tweenは なにかしらのプロパティを指定時間の間変化させてくれるので その変化させるプロパティを決めなければならない。 この場合は angleY。 で プロパティが変化するたびに onMotionChangedが呼ばれるので そのなかでrenderすればよい。

var angleY:Number = 30 * Math.PI / 180;
var tween:Tween = new Tween(this, 'angleY', Regular.easeInOut,
                            0, angleY, 0.5, true);
tween.onMotionChanged = Delegate.create(this,
                                        this.onMotionChanged);

onMotionChangedのなかは

function onMotionChanged(tween:Tween, pos:Number) {
  this.x = RADIUS * Math.cos(this.angleY);
  this.z = RADIUS * Math.sin(this.angleY);
  this.render();
}

となる。 これで0度から30度まで0.5秒かけて回転してくれる。

しかし たくさんのオブジェクトを移動したい場合 移動量が同じでも それぞれのオブジェクトにとって 初期角度と移動後の角度が異なるため この方法でTweenする場合 それぞれのオブジェクトにTweenを仕掛ける必要がある。

var angleY:Number = 30 * Math.PI / 180;
var cosY:Number = Math.cos(angleY);
var sinY:Number = Math.sin(angleY);
var x1:Number = this.x * cosY - this.z * sinY;
var z1:Number = this.z * cosY + this.x * sinY;
this.x = x1;
this.z = z1;

は 移動量を指定するタイプなので こちらがつかえれば Tweenはひとつで済む。

そこで this.objectsに 移動したいobjectが入っているとして

var angleY:Number = 30 * Math.PI / 180;
var tween:Tween = new Tween(this, 'dummy', Regular.easeInOut,
                            0, angleY, 0.5, true);
tween.onMotionChanged = Delegate.create(this,
                                        this.onMotionChanged);

としておいて onMotionChangedでは TweenのprevPosをつかって

function onMotionChanged(tween:Tween, pos:Number) {
  var delta:Number = pos - tween.prevPos;
  var cosY:Number = Math.cos(delta);
  var sinY:Number = Math.sin(delta);
  for (var i:Number=0; i<this.objects.length; i++) {
    var object = this.objects[i];
    var x1:Number = object.x * cosY - object.z * sinY;
    var z1:Number = object.z * cosY + object.x * sinY;
    object.x = x1;
    object.z = z1;
    object.render();
  }
}

とdelta(移動量)を求めて すべてのobjectsを同じ移動量だけ回転させることができる。

また、cosYとsinYはループにはいる前に決定できるので 効率がよい。

コメント(0):