第18回から前回の第21回にかけて、
MovieClipシンボルにクラスを定義すると、
MovieClipシンボルに設定するスクリプトとしては、
MovieClipシンボルに設定するクラス
3D風に回転させるMovieClipシンボルに定義するカスタムクラスは、
// ActionScript 3.0クラス定義ファイル: クラス名.as
package [パッケージ名]{
  import flash.display.MovieClip;
  // 他のimport宣言
  public class クラス名 extends MovieClip {
    // クラス定義の本体
  }
}
第1に、
第2に、
MovieClipシンボルにカスタムクラスを設定すると、
第3は、
すると、
では、
// ActionScript 3.0クラス定義ファイル: EllipticMotion.as
package {
  import flash.display.MovieClip;
  public class EllipticMotion extends MovieClip {
    public function EllipticMotion() {
      trace(x, y, this);
    }
  }
}
このままではまだクラスEllipticMotionとMovieClipシンボルの間には何の関わりもない。このふたつを関連づけるには、
クラスの設定されたMovieClipシンボルのインスタンスは、
var my_mc:EllipticMotion = new EllipticMotion();
[ムービープレビュー]を行うと、
これはインスタンスを作成しただけではまだそれはメモリ上の存在で、
そのためには、
親インスタンス.addChild(子インスタンス)
では、
var my_mc:EllipticMotion = new EllipticMotion();
addChild(my_mc);
my_mc.x = stage.stageWidth / 2;
my_mc.y = stage.stageHeight / 2;
フレームアクションをクラスに移行する
これで必要な知識は学んだので、
第1に、
// ActionScript 3.0クラス定義ファイル: EllipticMotion.as
// 回転するMovieClipシンボルの[クラス]に設定
package {
  import flash.display.MovieClip;
  import flash.events.Event;
  import flash.filters.BlurFilter;
  public class EllipticMotion extends MovieClip {
    private var nDegree:Number = 0;
    private var nRadian:Number = 0;
    private var nSpeed:Number = 5;
    private var nDegreeToRadian:Number = Math.PI / 180;
    private var nCenterX:Number = stage.stageWidth / 2;
    private var nCenterY:Number = stage.stageHeight / 2;
    private var nRadiusX:Number = 100;
    private var nRadiusY:Number = 50;
    private var nCos:Number = Math.cos(nRadian);
    private var nSin:Number = Math.sin(nRadian);
    public function EllipticMotion() {
      addEventListener(Event.ENTER_FRAME, xMoveX);
      addEventListener(Event.ENTER_FRAME, xMoveY);
      addEventListener(Event.ENTER_FRAME, xScale);
      addEventListener(Event.ENTER_FRAME, xBlur);
      addEventListener(Event.ENTER_FRAME, xUpdate);
    }
    private function xMoveX(eventObject:Event):void {
      x = nCenterX + nCos * nRadiusX;
    }
    private function xMoveY(eventObject:Event):void {
      y = nCenterY + nSin * nRadiusY;
    }
    private function xScale(eventObject:Event):void {
      scaleX = scaleY = xGetIndexZ(0.8,1);
      scaleX *= xGetIndexZ();
    }
    private function xBlur(eventObject:Event):void {
      var nBlur:Number=xGetIndexZ(4,0);
      var myBlur:BlurFilter=new BlurFilter(nBlur,nBlur/2);
      filters=[myBlur];
    }
    private function xUpdate(eventObject:Event):void {
      nDegree+=nSpeed;
      nDegree = (nDegree%360+360)%360;
      nRadian=nDegree*nDegreeToRadian;
      nCos=Math.cos(nRadian);
      nSin=Math.sin(nRadian);
    }
    private function xGetIndexZ(nMin:Number=-1, nMax:Number=1):Number {
      var nIndexZ:Number = (nMax-nMin)*(nSin+1)/2+nMin;
      return nIndexZ;
    }
  }
}
上記スクリプト1のクラスEllipticMotionを設定したMovieClipインスタンスは、
それではつぎに、
var my_mc:EllipticMotion = new EllipticMotion();
addChild(my_mc);
ところが、
TypeError: Error #1009: nullのオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。 
結論からいうと、
表示オブジェクト(野中注: DisplayObjectインスタンス)が表示リストに追加されていない場合、stageプロパティはnullに設定されます。
前掲のフレームアクションで、
対処の方法は、
中心や半径の値は、
new Point(x座標, y座標)
以上の修正をクラスEllipticMotionに加えたのが、
// ActionScript 3.0クラス定義ファイル: EllipticMotion.as
// 回転するMovieClipシンボルの[クラス]に設定
package {
  import flash.display.MovieClip;
  import flash.events.Event;
  import flash.filters.BlurFilter;
  import flash.geom.Point;
  public class EllipticMotion extends MovieClip {
    private var degree:Number = 0;
    private var radian:Number = 0;
    private var speed:Number = 5;
    private var degreeToRadian:Number = Math.PI / 180;
    private var centerX:Number;   // 初期値なし
    private var centerY:Number;   // 初期値なし
    private var radiusX:Number;   // 初期値なし
    private var radiusY:Number;   // 初期値なし
    private var cos:Number = Math.cos(radian);
    private var sin:Number = Math.sin(radian);
    public function EllipticMotion(nDegree:Number, myCenter:Point, myRadius:Point) {
      degree = nDegree;
      centerX = myCenter.x;
      centerY = myCenter.y;
      radiusX = myRadius.x;
      radiusY = myRadius.y;
      addEventListener(Event.ENTER_FRAME, moveX);
      addEventListener(Event.ENTER_FRAME, moveY);
      addEventListener(Event.ENTER_FRAME, scale);
      addEventListener(Event.ENTER_FRAME, blur);
      addEventListener(Event.ENTER_FRAME, update);
    }
    private function moveX(eventObject:Event):void {
      x = centerX + cos * radiusX;
    }
    private function moveY(eventObject:Event):void {
      y = centerY + sin * radiusY;
    }
    private function scale(eventObject:Event):void {
      scaleX = scaleY = getIndexZ(0.8,1);
      scaleX *= getIndexZ();
    }
    private function blur(eventObject:Event):void {
      var nBlur:Number=getIndexZ(4,0);
      var myBlur:BlurFilter=new BlurFilter(nBlur,nBlur/2);
      filters=[myBlur];
    }
    private function update(eventObject:Event):void {
      degree += speed;
      degree = (degree%360+360)%360;
      radian=degree*degreeToRadian;
      cos=Math.cos(radian);
      sin=Math.sin(radian);
    }
    private function getIndexZ(nMin:Number=-1, nMax:Number=1):Number {
      var nIndexZ:Number = (nMax-nMin)*(sin+1)/2+nMin;
      return nIndexZ;
    }
  }
}
これで、
var myCenter:Point = new Point(stage.stageWidth / 2,stage.stageHeight / 2);
var myRadius:Point = new Point(100,50);
var _mc:EllipticMotion;
_mc = new EllipticMotion(0,myCenter,myRadius);
addChild(_mc);
_mc = new EllipticMotion(90,myCenter,myRadius);
addChild(_mc);
_mc = new EllipticMotion(180,myCenter,myRadius);
addChild(_mc);
_mc = new EllipticMotion(270,myCenter,myRadius);
addChild(_mc);
前述のとおり、
今回解説した次のサンプルファイルがダウンロードできます。
