[as2]の最近のブログ記事

AS3の EventDispatcher クラスをAS2でも使えるようにと思って作ったクラスです。

EventDispatcher クラス
Event クラス

サンプル用 fla ファイル
demo.fla
demo2.fla

willTriggerメソッドが、どうやって実装するか悩んだ(willTriggerの挙動自体いまいち把握してない)のでとりあえずほったらかしてます。

あと、mx.events.EventDispatcherを継承してますが、中身はまったく別物です。
ムービークリップに適応した場合、イベント通知がルートからたどっていくようになってます。(微妙ですが)

で、AS3的に「addEventListener("enterFrame", handler )」とかやりたいところですが、
元々AS2のMovieClipにそんな機能は実装されてないので、前のエントリーで書いた EventMediator クラスを使います。

こんな感じです。
import flash.events.EventDispatcher;
import flash.events.Event;

import com.seyself.events.EnterFrameBeacon;
import com.seyself.events.EventMediator;

EventDispatcher.initialize( MovieClip.prototype );

var madiator:EventMediator = new EventMediator( new EnterFrameBeacon() );

madiator.addEventListener( "enterFrame" , null );
madiator.member = [mc];   // ステージ上に配置してあるムービークリップ

mc.addEventListener( "enterFrame" , enterFrameHandler );
function enterFrameHandler( event:Event ):Void
{
    trace(event.target);// _level0.mc
}

EnterFrameBeaconクラスは、単純にenterFrameイベントを通知し続けるクラスです。
AS3を使っててAS2に戻ると、何かと不便に感じることが多いです。
AS3とAS2に互換性が無いのが、今、一番厄介に感じます。
いずれ完全にAS3に移行したときのことを考えて、少しAS2にAS3らしさを取り入れたほうがいいのかな?なんて思ったりもしますが、それが正しいのか間違ってるのかはよくわかりません。
ただAS3からAS2にクラスを逆移植することがあるのですが、Eventクラスとか、デフォルトのクラスでよく使うものはAS2にもほしい。
誰か作ってないかなあ。と思う今日この頃。
あと、個人的にProxyクラスがAS2にもほしいけど実装の仕方がわからない。

flash.utils.Dictionary
import flash.utils.Dictionary;

var dic:Dictionary = new Dictionary();
var a = {};
var b = {};
var c = {};

dic.add( a , 1 );
dic.add( b , 2 );
dic.add( c , b );

trace("length : "+dic.length);// output 3
trace("object a : "+dic.value(a));// output 1
trace("object b : "+dic.value(dic.value(c)));// output 2
dic.del(c);
trace("length : "+dic.length);// output 2
trace("has a : "+dic.has(a));// output true
trace("has b : "+dic.has(b));// output true
trace("has c : "+dic.has(c));// output false
以前書いた「画像をロードしたMC 上に attachMovie」という記事に
助言をいただきまして、ちょっと試してみたので掲載しておきます。

読み込み先の"sub.swf"には「imageMC」というムービークリップが配置されてます。
var mc:MovieClip = this.createEmptyMovieClip("loadSWF",10);
var loader:MovieClipLoader = new MovieClipLoader();
listener = { onLoadComplete:function(){
    trace(mc.imageMC);                      // output 1
    mc.onEnterFrame=function(){
      trace("onEnterFrame : "+mc.imageMC);  // output 2
      delete this.onEnterFrame;
    }}, 
    onLoadInit:function(){
      trace("onLoadInit : "+mc.imageMC);    // output 3
    }};
loader.addListener( listener );
loader.loadClip( "sub.swf" , mc );
出力結果
undefined
onEnterFrame : _level0.loadSWF.imageMC
_level0.loadSWF
onLoadInit : _level0.loadSWF.imageMC
出力結果の1行目は "output 1" 、2行目は "output 2"、
3行目は sub.swf のルート1フレーム目に書かれた「 trace(this); 」の出力、
4行目が "output 3"になります。

僕は今まで onLoadInit が読み込みを開始したときのイベントだと勝手に勘違いしてました。
実際にはonLoadInitは読み込まれたswfの1フレーム目のスクリプトが実行された後に呼び出されるみたいです。
onEnterFrameは各フレームのスクリプトの一番最初に実行されるルールがここでも有効みたいなので、onLoadInitが呼び出される前(読み込まれたswfのスクリプトが実行されるよりも前)に実行されるみたいです。

それぞれ実行されるタイミングが違うので、意図的にこれらを使い分ければ便利かもしれないです。
Yoropan@Flaさんのブログ記事にコメントしたら失敗してしまいました。
http://yoropan.no.coocan.jp/wp/index.php/archives/85#comment-31

ここにコメントで書こうとしたソースを掲載しておきます。

Yoropan@Flaの筆者さん、すいませんでした。

var arr:Array = [0,1,2];

for(var i=0; i<arr.length; i++){
  var names="hoge"+i;
  var box_mc = this.createEmptyMovieClip(names,i)
  box_mc.i=i;
  box_mc.onRelease=function(){
    box_mc.name=arr[this.i];
    trace("--release event");
    trace("box_mc.name = "+box_mc.name);
    trace("hoge0.name = "+hoge0.name);
    trace("hoge1.name = "+hoge1.name);
    trace("hoge2.name = "+hoge2.name);
    trace("box_mc = "+box_mc);
    trace("this = "+this);
    trace("");
  }
  fillRect( box_mc );
  box_mc._x = i*110;
}
trace([i,box_mc]);

function fillRect( mc )
{
  var x = 100;
  mc.beginFill(0,100);
  mc.moveTo(0,0); mc.lineTo(x,0);
  mc.lineTo(x,x); mc.lineTo(0,x);
}

はじめてトラックバックという機能を使ってみます。緊張の一瞬です。

trick7さんがblogに「画像をロードしたMC 上に attachMovie できない」という記事を書かれてまして、これってよくいろいろと聞かれるので書いておこうと思いました。

まずテスト用に以下の図のような構成の"main.swf"と"sub.swf"というファイルを用意しました。


"sub.swf"のルートの1フレーム目には
trace(this);
とだけ書かれています。
あと、ムービークリップ「imageMC」を配置、そのなかに直接画像を配置しています。

で、"main.swf"にはリンケージ設定をした「attachMC」がライブラリに入った状態で、以下のスクリプトをルートに書いておきます。
import flash.display.BitmapData;

var loadMC:MovieClip = this.createEmptyMovieClip("loadMC",10);
var bmp1:BitmapData = new BitmapData(100,100,true,0);
var bmp2:BitmapData = new BitmapData(100,100,true,0);
var draw1:MovieClip = this.createEmptyMovieClip("draw_1",20);
var draw2:MovieClip = this.createEmptyMovieClip("draw_2",30);
loadMC._y = 120;
draw2._x = 120;

var loader:MovieClipLoader = new MovieClipLoader();
var listener = { onLoadComplete:function(){ 
    trace(loadMC.imageMC); // output : undefined
	
    loadMC.attachMovie( "attachMC", "attachMC" , 10 );
    bmp1.draw( loadMC ); // 描画されない
    draw1.attachBitmap( bmp1, 10, "auto", true );
    
	loadMC.onEnterFrame=function(){
      trace(mc.imageMC); // output : _level0.loadSWF.imageMC
      
	  bmp2.draw( loadMC ); // 描画される
      draw2.attachBitmap( bmp2, 10, "auto", true );
      delete this.onEnterFrame;
    } 
  }};
loader.addListener( listener );
loader.loadClip( "sub.swf" , loadMC );
結果は以下のようになります。

出力結果
undefined
_level0.loadMC.imageMC
_level0.loadMC
「出力結果」の3行目が"child.swf"の「trace(this);」の出力になります。

まず、AS2では読み込み元(この場合は"loadMC")が"sub.swf"のルートになります。(画像の場合も同様かと思います)
読み込みが完了した後、15行目の「loadMC.attachMovie(~」でattachしようとしているのですが、この時"loadMC"は"sub.swf"のルートになっているので、"sub.swf"のルートに attachMovie しようとしていることになります。
AS2では外部読み込みしたSWFに対してattachで配置することができません。(逆も同じです。)
なのでこの場合も配置することができないのです。


あと、合わせてよく聞かれるのが BitmapData の draw とかその辺です。というかイベントのタイミングの話になるのですが。
なので一緒にテストしてみました。
最初の図と見比べていただくと"draw1"の箇所が表示されていないのが分かります。
スクリプトでいうところの16、17行目の箇所です。
これは、"onLoadComplete"イベントが発生した時点では、読み込みは完了しているが画面上に書き出されていないことをあらわしています。
まだ書き出されていないので、13行目の参照も、結果は「undefined」になってしまいます。

そこで一連の処理が終わって、描画処理も終わった後で"draw"を実行するために"onEnterFrame"を使っています。
"onEnterFrame"は現在のフレームの処理がすべて終わった後、次のフレームに移った瞬間に実行されるので、おそらく読み込みが完了してから最短で"draw"する方法じゃないかと思います。
それが20行目から24行目になります。1回実行したらこの処理はもういらないので"delete"で削除してます。


さらについでなのでAS3でも試してみました。
sub.swf
trace(this.name);
main.swf
import flash.display.*;
import flash.net.URLLoader;
import flash.net.URLRequest;

var loadMC:Loader = new Loader();
var bmp1:BitmapData = new BitmapData(100,100,true,0);
var bmp2:BitmapData = new BitmapData(100,100,true,0);
var draw1:Bitmap = new Bitmap( bmp1, "auto", true );
var draw2:Bitmap = new Bitmap( bmp2, "auto", true );
this.addChild(loadMC);
this.addChild(draw1);
this.addChild(draw2);
loadMC.y = 120;
draw2.x = 120;

var request:URLRequest = new URLRequest('sub.swf');
var info = loadMC.contentLoaderInfo;
info.addEventListener( "complete" , listener );
function listener( e ){ 
  trace(loadMC.getChildByName("imageMC")); // null
  trace(loadMC.getChildAt(0).getChildByName("imageMC").name); // imageMC
  
  //mc.addChild( new attachMC() );//Error: Error #2069: Loader クラスは、このメソッドを実装しません。
  loadMC.getChildAt(0).addChild( new attachMC() );
  bmp1.draw( loadMC );
  
  loadMC.addEventListener( "enterFrame" , function(e){
    trace(loadMC.getChildByName("imageMC")); // null
    trace(loadMC.getChildAt(0).getChildByName("imageMC").name); // imageMC
    
    bmp2.draw( loadMC );
    loadMC.removeEventListener( "enterFrame" , arguments.callee );
  } );
}; 
loadMC.load( request );

出力結果
instance4
null
imageMC
null
imageMC
AS3だと外部ファイルにも"new"で配置できるんですね。
AS2と違っているのは"loadMC"が"sub.swf"のルートになるんじゃなくて、"loadMC"の中に"sub.swf"が入るようになったんですね。
あと、この結果からイベントのタイミングが描画されたあとに発生してるのもわかります。

なんか異様に長くなってしもた。
追記:
サンプルのflaファイルをアップしときました
attach_sample.zip
きっと使えば何かと便利なんだろうけど
今まで使ってた自分クラスがなかなか手放せないだけなのかもしれない。

Motionクラス, Easeクラス
import com.seyself.controls.Motion;
import com.seyself.controls.Ease;

var tween = Ease.cubic('out', 12);
var motion = new Motion();

motion.start( mc , { x:100 , y:100 , _rotation:45 } , tween , 0 , 
               { complete:function(e){ trace(e.target) }} );
ちなみに僕はイージングは配列で管理してます。
上記の変数 "tween" は 0 から 1 の配列が入ってます。
実際1つのコンテンツにイージングを何パターンも使うことはあまりなくて
だいたい4種類前後しか使わないので、そのために実行時に何度も
同じ計算をすることもないんじゃないかなあ、と。
そのかわりメモリ食ってるかもしれません。
あんまりその辺、気にしないことにしてます。面倒なので。

Moveクラス

Transクラス

Coloringクラス

Discolorクラス

結局のところ、まとまったドキュメントやら、ソースを見るのが面倒なだけかもしれませんが。

Flash 8 から実装された Matrixクラス や Pointクラスなどが入っている flash.geom パッケージですが、 Wiiとか未だに FLASH Player のバージョンは 7 だとかで、このパッケージは使えないらしい。
これってバージョンアップはしないんでしょうか。

ところで、以前どっかのブログ記事でそんなことを書いている人がいたので試しにバージョン7 でも使えるように 手作り geom パッケージを作ってみました。

一応、概ねカバーできてると思うんだけども一部対応してない箇所があります。
以下対応してない箇所。

Point.add( v:Point ):Point
バージョン7 だと add は演算子扱いされちゃって実装できなかった。
なので、このクラスで addメソッドを使うには以下の方法を取ってください。
point["add"]( pt );//配列アクセスを使う
point.addition( pt );//代替メソッドを用意しています。

Transform.concatenatedMatrix:Matrix
途中で飽きて実装するのが面倒になってしまいました。
誰か気前のいい人が実装してくれたらいいなあと。

Transform.concatenatedColorTransform:ColorTransform
同じく、途中で飽きて実装するのが面倒になってしまいました。
誰か気前のいい人が実装してくれたらいいなあと。

ソースのダウンロードはこちら
20080109_fp7_geom_package.zip

パッケージ名が flash7.geom になってます。(バージョン8と混ざると困ったことになるので)
使いにくかったらパッケージ名は各々で変更してくださいませ。

あと、当然なんですがバージョン7 では MovieClip に transform というプロパティはデフォルトでは付いていないので、 最初に対象となるムービークリップに対して new しないといけません。
import flash7.geom.Transform;
var trans:Transform = new Transform( targetMC );
上記の対応してない箇所以外はバージョン8 のクラスと同じです。
コメントはほとんど書いてないので、使い方の分からないところは、製品のヘルプか、LiveDocsを参照してください。

ご使用、改変はご自由に。
あんましデバッグとかしてないので、バグがあったらすいません。
このクラスの利用はあくまで自己責任にてお願いします。

Matrix の値から拡大縮小、回転、位置の値を取る計算式。
import flash.geom.Matrix;
var mat:Matrix = new Matrix();
mat.createBox( 12 , 36 , Math.PI/4 , 10, 50 );
trace( mat );
trace( getParam( mat ) );

function getParam( m:Matrix ):Object
{
  var totalScale:Number = m.a * m.d - m.b * m.c;
  var sx:Number = Math.sqrt(m.a * m.a + m.c * m.c);
  var sy:Number = totalScale / sx;
  var angle:Number = Math.acos( m.a / sx );
  var obj = { scaleX:sx , scaleY:sy, rotation:angle, x:m.tx, y:m.ty };
  obj.toString = function()
  {
    return "(scaleX="+this.scaleX+" , scaleY="+this.scaleY+
			 ", rotation="+this.rotation+", x="+this.x+", y="+this.y+")";
  }
  return obj;
}
意味があるかはまったく不明。
使いどころが分からないけど、なんとなくやってみた。
import mx.events.EventDispatcher;

var execute = function( func:Function ):Void
{
  arguments.callee.dispatchEvent( { type:"call" } );
  func();
  arguments.callee.dispatchEvent( { type:"fin" } );
}

EventDispatcher.initialize( execute );

var eventListener = {};
eventListener.call = function():Void
{
  trace("Event : call");
}
eventListener.fin = function():Void
{
  trace("Event : fin");
}
execute.addEventListener( "call", eventListener );
execute.addEventListener( "fin" , eventListener );

execute( execution );


function execution():Void
{
  trace("execution");
}
ってことをするために作ったクラス
SyncMethod クラス
import com.seyself.utils.SyncMethod;
var obj = {};
var tgt = {};
obj.execution = function( a )
{
  trace("execution : "+a);
}
tgt.sync1 = function( a )
{
  trace("sync1     : "+a);
}
function sync2( a )
{
  trace("sync2     : "+a);
}
obj.execution( "exec 1" );
trace("----");
SyncMethod.synchronize( obj , "execution", tgt.sync1  );
SyncMethod.synchronize( obj , "execution", sync2  );
obj.execution( "exec 2" );
trace("----");
SyncMethod.remove( obj , "execution", tgt.sync1  );
obj.execution( "exec 3" );
trace("----");
EventDispatcher に似ていますが、すでに定義された関数の内部を変更せず、呼び出し元の記述の変更もしないで、追加呼び出しを定義することが出来ます。
onEnterFrameとかonReleaseでも使えます。
_array.push()とかでも使えます。

ただし、引数の値は呼び出した関数に渡された引数が設定されます。
また関連して実行された関数はスコープが、登録したメソッドを持つオブジェクトに変更されますので使う際は要注意。

今回はAS2用に書いたけど、AS3でも一部書き換えれば同様のことができました。
ただAS3での必要性は今のところ感じないけども。
最大値と最小値が決まっていて、その間の値を取るときに
Mathクラスのminとmaxを今まで使っていた。
var res:Number = Math.min( 1 , Math.max( 0 , i ) );
こんなふうに。
でも、Mathクラスのmaxとminで比較するより、条件分岐を使った方が倍くらい早かった。
var res:Number = ( i > 1 ) ? 1 : ( i < 0 ) ? 0 : i ;
Function呼ばないから当たり前なんだろうけど、
minとmax使った方が書くのが楽チンだから
ついついやってしまうのでメモメモ。

AS2だと BezierSegment クラスは用意されていないけど、CS3の以下のディレクトリ
Adobe Flash CS3\ja\Configuration\ActionScript 3.0\Classes\fl\motion
の中に入ってる BezierSegment.as をコピーして少し書き換えればAS2でも使えます。

・packageの記述を削除
・int を Number に書き換え
・for each を for in に書き換え
・function の引数のデフォルト値を削除

swfファイルがココに置いているので、これをダウンロードして WindowSWF フォルダに入れれば Flash 内で
「ウィンドウ」→「他のパネル」から開けます。
なんとなく思ったこと。

ActionScript のクラスを作るときって、もちろん Flash のオーサリングを前提にして作る。
今まで何度も他の人が作った fla ファイルを修正依頼なんかで見てきたりしたんだけど、
Flash のオーサリング方法は結構人それぞれで、スクリプトの書き方も、それによって
大幅に違ってたりする。

ステージ上に何も配置しないで、すべて attachMovie とかでレイアウトすらスクリプトで指定する人もいれば、
コンテンツを細切れにして、どんどん外部SWF化してたり、
flaファイル内ですべてレイアウトして、それに対してスクリプトで操作を加える作り方だったり。
すべてを 1 フレームに収めてしまう人もいれば、コンテンツ毎にフレームを区切って作成する人もいるし、
「シーン」機能を使ってコンテンツ毎にシーンを作成する人もいる。

作り方が人それぞれだから、そこに書かれたスクリプトの使い方も人それぞれ。

僕はというと、
「flaファイル内ですべてレイアウトして、それに対してスクリプトで操作を加える作り方」で、
「コンテンツ毎にフレームを区切って作成する人」なわけ。

デザイン画像をガイドレイヤーに配置して、その上からパーツを配置していく。
そこにスクリプトを埋め込んで操作を加えていく。
だから、座標やスケールなどの指定は、絶対値よりも相対値を用いることが多い。

X座標 -10 からフェードインしてきて、 +10 に向かってフェードアウト

みたいな。

こういうレイアウト指向(?)なものに適したクラスを作っていくと
もっと作業が楽になるんじゃないかと思った。

めもめも。
AS2 にて
デバッグ用に作ったもの。
渡されたスコープから辿って3階層以内に見つからなければ null を返します。
class FunctionUtil
{
  public static function getCallerScope( func:Function , scope:Object ):Object
  {
    if( scope==undefined ) scope = _root;
    var maxLevel = 4;
    var level = (arguments[2]==undefined)? 0 : arguments[2];
    if( func ){
      for(var val in scope){
        if( typeof( scope[val] )=="function" ){
          if( scope[val]==func ){
            return { scope:scope , functionName:val };
          }
        } else {
          if(level<maxLevel){
            if( typeof( scope[val] )=="movieclip" || typeof( scope[val] )=="object" ){
              var res = getCallerScope( func , scope[val] , level+1 );
              if( res ) return res;
            }
          }
        }
      }
    }
    return null;
  }
}
例:
function calleeFunc()
{
  var res = FunctionUtil.getCallerScope( arguments.caller , this._parent );
  trace(res.scope);
  trace(res.functionName);
}
27日の月曜日に心斎橋にて開催されるTERACOに参加することになったので。
予習ということで EventDispatcher クラスを使って、ステージサイズを取得するためのクラスを作成してみようと。
サンプル
サンプルソースのダウンロード ( 20070825_stageresize.zip )

今回作ったクラスは「StageResizeManager」というクラス。
詳細は省くけども、使えるメソッドはこの5つ。すべて static 。
setup( width:Number, height:Number, maxSize:Object, minSize:Object ):Void
                                                 setup は1回実行すると削除される
addEventListener( type:String , object:Object ):Void     リスナーを登録
removeEventListener( type:String , object:Object ):Void     登録したリスナーの削除
eventRequest():Void    サイズ変更の有無に関わらず強制的に1回resizeイベントを送信
getSizeInfo():Object    ステージのサイズ情報を取得
で、肝心のイベントは
resized
の1つだけ。
ルートのタイムラインに下記のスクリプトを書いています。
setup の maxSize と minSize はオプション。

var defaultWidth:Number = 550;
var defaultHeight:Number = 350;
var maxSize:Object = { width:800 , height:600 };
var minSize:Object = { width:400 , height:300 };
StageResizeManager.setup( defaultWidth , defaultHeight , maxSize , minSize );

function resizeHandler( event:Object )
{
  var str = "stage resize ---------------------------------\n" ;
  for(var val in event){
    str += "  "+ val +" => "+ event[val]+"\n";
  }
  trac.text = str;
  trace( str );
}
StageResizeManager.addEventListener( "resized" , resizeHandler );

this.onEnterFrame = function()
{
  StageResizeManager.eventRequest();
  delete this.onEnterFrame;
}
ちなみに onEnterFrame を使ってるのは、下層の四角4つの、それぞれのスクリプトの処理が終わった後に実行したいから。
四隅の四角はそれぞれ中のタイムラインに下記のようなスクリプトが書かれてます。
var loc = this;
function resizeHandler( event:Object )
{
    loc._x = event.left;
    loc._y = event.top;
    loc.x.text = loc._x;
    loc.y.text = loc._y;
}
StageResizeManager.addEventListener( "resized" , resizeHandler );

なぜか今日は片言。
月曜日緊張するな~
for(var i=0; i<Math.PI; i+=0.1)
{
  var a = Math.pow( Math.sin( i ) , 2 ) + Math.pow( Math.cos( i ) , 2 );
  trace( a );
}
これ今まで知らなかったのは痛いなあ。
まだまだ知らないことだらけだ。
何がしたかったかというと。
import flash.geom.Point;

var result = createOrderMatrix( 9 , 9 );
for(var i=0;i<result.length;i++){
  trace( result[i] );
}

function createOrderMatrix( xlength:Number , ylength:Number ):Array
{
  var p:Point = new Point( 0 , 0 );
  var totalLength = xlength*ylength;
  var matrix = new Array( ylength );
  for(var i=0;i<ylength;i++){
    matrix[i] = new Array( xlength );
  }
  var xh = Math.floor(xlength/2);
  var yh = Math.floor(ylength/2);
  var xflag = true;
  var yflag = false;
  var xm:Number, ym:Number, nx:Number, ny:Number;
  xm = ym = nx = ny = 1;
  
  matrix[yh][xh] = 0;
  for(var i=1;i<totalLength;i++)
  {
    if( xflag ){
      p.x += xm/Math.abs(xm);
      if( nx == p.x ){
        xm = -(Math.abs(xm)/xm)*(Math.abs(xm)+1);
        nx += xm;
        yflag = true; xflag = false;
      }
    }
    else if( yflag ){
      p.y += ym/Math.abs(ym);
      if( ny == p.y ){
        ym = -(Math.abs(ym)/ym)*(Math.abs(ym)+1);
        ny += ym;
        yflag = false; xflag = true;
      }
    }
    if( p.x+xh >= 0 && p.x+xh < xlength &&
             p.y+yh >= 0 && p.y+yh < ylength ){
      matrix[p.y+yh][p.x+xh] = i;
    } else {
      i--;
    }
  }
  return matrix;
}
出力結果
72,73,74,75,76,77,78,79,80
71,42,43,44,45,46,47,48,49
70,41,20,21,22,23,24,25,50
69,40,19,6,7,8,9,26,51
68,39,18,5,0,1,10,27,52
67,38,17,4,3,2,11,28,53
66,37,16,15,14,13,12,29,54
65,36,35,34,33,32,31,30,55
64,63,62,61,60,59,58,57,56
渦巻き配列

もっとスマートにならんかな・・・
1マスずつ描画する
import flash.geom.Point;
var p:Point = new Point( 0 , 0 );
this.lineStyle( 1 , 0 , 50 );
var xflag = true;
var yflag = false;
var xm = 1;
var ym = 1;
var nx = 1;
var ny = 1;
for(var i=0;i<50;i++)
{
  if( xflag ){
    p.x += xm/Math.abs(xm);
    if( nx == p.x ){
      xm = -(Math.abs(xm)/xm)*(Math.abs(xm)+1);
      nx += xm;
      yflag = true;
      xflag = false;
    }
  }
  else if( yflag ){
    p.y += ym;
    if( ny == p.y ){
      ym = -(Math.abs(ym)/ym)*(Math.abs(ym)+1);
      ny += ym;
      yflag = false;
      xflag = true;
    }
  }
  
  this.lineTo( p.x*10 , p.y*10 );
  trace(  p.x +" / "+ p.y  );
}
/**
 r : Number ― r = ( currentTime - startTime ) / durationTime;

*/
function costomEase( r:Number ):Number
{
  //return Math.sin( Math.PI*0.7*r )+(1-Math.sin(Math.PI*0.3));
  //return 1-Math.cos( Math.PI/2*r );
  //return Math.tan( Math.PI*r )+r;
  //return r*r*r;
  //return 1-Math.pow( 1-r , 5 );
  //return r*r*3-r*2;
  //return Math.abs( r*r*3-r*2 );
  return Math.sin( Math.PI*r )*Math.cos( Math.PI*r )+r;
}
頂点毎に描画する
import flash.geom.Point;
var p:Point = new Point( 0 , 0 );
this.lineStyle( 1 , 0 , 50 );
var xflag = true;
var yflag = false;
var xm = 1;
var ym = 1;
for(var i=0;i<50;i++)
{
  if( xflag ){
    p.x += xm;
    xm = -(Math.abs(xm)/xm)*(Math.abs(xm)+1);
  }
  if( yflag ){
    p.y += ym;
    ym = -(Math.abs(ym)/ym)*(Math.abs(ym)+1);
  }
  xflag = !xflag;
  yflag = !yflag;
  
  this.lineTo( p.x*10 , p.y*10 );
  trace(  p.x +" / "+ p.y  );
}
AS2でAbstract
class AbstractClass
{
  function AbstractClass()
  {
    if(arguments.caller.prototype instanceof AbstractClass){
      trace("create instance");
    } else {
      throw new Error("ArgumentError: Error #2012: AbstractClass class cannot be instantiated.");
    }
  }
}
class SubClass extends AbstractClass
{
  function SubClass()
  {
    super();
  }
}


AS3でAbstract
package
{
  public class AbstractClass
  {
    function AbstractClass( access:*=null ):void
    {
      if( access!=this ){
        throw new ArgumentError("Error #2012: AbstractClass class cannot be instantiated.");
      }
    }
  }
}
package
{
  public class SubClass extends AbstractClass
  {
    function SubClass( access:*=null ):void
    {
      super(this);
    }
  }
}