2007年8月アーカイブ

何度も WindowSWF フォルダ内のファイルを追加、削除していると
Flash8 の「他のパネル」から開いた時に、名前とパネルが一致しなくなってくる。

このときは、一旦 Flash を閉じて WindowSWFフォルダ内のファイルをすべて別の場所に
移動させて、空の状態で再度 Flash を起動。
もう一度 Flash を閉じた後、WindowSWFフォルダにファイルを戻して
再び Flash を起動すると、ちゃんとパネルが開けられるようになる。
AS2だと
trace(this);
だけで済むのに、AS3でこれをしようとすると
function getGlobalPath( target:DisplayObject ):String
{
  if( target!=target.root ){
    var _path:String = getGlobalPath( target.parent );
    return _path+"."+target.name;
  } else {
    return "root";
  }
}

var res:String = getGlobalPath( this );
trace(res); //出力 : root.instance1.instance2.instance3.instance4.instance5
var mc:Object = this.root;
trace( mc.instance1.instance2.instance3.instance4.instance5==this ); //出力 : true
いちいちこんな事しないといけないのかな?
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);
}
Motion クラスと Ease クラス
  サンプル
  サンプルソース
  ドキュメント
使用例:
import com.seyself.controls.Motion;
import com.seyself.controls.Ease;
import flash.display.Sprite;

var motion:Motion = new Motion();
var easing:Array = Ease.cubic( "out" , 30 );

for(var i=0;i<10;i++){
  creater(i);
}

function creater( i )
{
  var sprite:Sprite = new Sprite();
  sprite.graphics.beginFill( 0x666666 , 1 );
  sprite.graphics.drawRect( 0, 0, 20 , 20 );
  sprite.y = i*30+5;
  sprite.x = 10;
  motion.start( sprite , { x:550 } , easing , i*3 );
  this.addChild( sprite );
}
enterFrameイベントを管理するクラス「EnterFrame」

  サンプル
  サンプルソース
  ドキュメント
使用例:
import com.seyself.events.EnterFrame;
import com.seyself.events.EnterFrameEvent;
import flash.display.Sprite;

function emptiedHandler( event:EnterFrameEvent )
{
  trace("empty");
}
EnterFrame.addEventListener( "emptied" , emptiedHandler );

function registeredHandler( event:EnterFrameEvent )
{
  trace("registered / "+event.currentTarget);
}
EnterFrame.addEventListener( "registered" , registeredHandler );

function  removedHandler( event:EnterFrameEvent )
{
  trace("removed / "+event.currentTarget);
}
EnterFrame.addEventListener( "removed" , removedHandler );

for(var i=0;i<10;i++){
  creater(i);
}

function creater( i )
{
  var sprite:Sprite = new Sprite();
  sprite.graphics.beginFill( 0x666666 , 1 );
  sprite.graphics.drawRect( 0, 0, 20 , 20 );
  sprite.y = i*10;
  sprite.x = i*4;
  var tx = Math.random()*800;
  var ty = Math.random()*800;
  function enterFrameHandler( event:EnterFrameEvent )
  {
    sprite.x += (tx-sprite.x)/3;
    sprite.y += (ty-sprite.y)/3;
    if( event.currentTime==20 ){
      event.remove();
    }
  }
  EnterFrame.register( enterFrameHandler , sprite , i*3 );
  this.addChild( sprite );
}
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 );

なぜか今日は片言。
月曜日緊張するな~
ASDoc の実行時に
asdoc -doc-sources ●●●●
とすると、やたらと「~に型宣言がありません。」と怒られる。
(●●●●はソースの置いてるディレクトリ)

普通にコマンドプロンプト使ってやってると、うまく書き出されないときに
肝心のエラー部分が上に追いやられてしまって、何が原因になのかが
わからなくなってしまう。

-compiler.show-actionscript-warnings
    エイリアス -show-actionscript-warnings
    有効であるが部分的に正しくないコードを検出するモードで AS3 コンパイラを実行します
このオプションを使って
asdoc -doc-sources ●●●● -show-actionscript-warnings=false
としてやれば、エラー箇所のみ出力されるのでスッキリ。

その他の警告オプション
-compiler.show-binding-warnings
    エイリアス -show-binding-warnings
    データバインディングコードから生成される警告を表示するかどうかを切り替えます
-compiler.show-deprecation-warnings
    エイリアス -show-deprecation-warnings
    推奨されない API を使用した場合に警告を表示するかどうかを切り替えます
-compiler.show-unused-type-selector-warnings
    エイリアス -show-unused-type-selector-warnings
    使用されていないタイプセレクタから生成される警告を表示するかどうかを切り替える


Adobe Flex2 ヘルプ
ASDoc の使用
こんなのも。
拡張ウィンドウパネル


ClipBoardLuncher.swf
テキストをリストに登録、1クリックでクリップボードにコピーされます。

LinkagePanel.swf
AS2用のリンケージ設定パネルです。
複数同時に設定が可能です。

NamberingPanel.swf
選択したステージ上の複数のムービークリップに連番付きのインスタンス名を設定します。
* が連番に置き換えられます。(例:symbol_*_text など )
Start No に0付きの数値を入力すると、桁数を揃えます。
連番を割り当てる順番と開始番号の設定が可能です。


以下は、自分で作ってはみたものの使い道がなかったり、挙動がいまいちだったりするもの。
ご利用は自己責任でお願いします。

FunctionTree.swf
タイムライン上のFunction定義を探して階層表示します。

SecondActionPanel.swf
アクションパネルをもう1枚、ってときに。
一応編集もできますが、あまりお勧めできません。

なんか巷のFlasher方の間で流行ってるみたいなので、
手持ちのものをいくつかアップしておく。

探せばどっかにありそうなのばっかりだけども。


setInstanceName.jsfl
選択したステージ上の1つ、もしくは複数のムービークリップのインスタンス名をシンボル名と同じ名前に設定します。

getInstanceName.jsfl
選択したステージ上の1つ、もしくは複数のムービークリップのインスタンス名を出力パネルに表示します。
実行するとプロンプトが表示され、入力した文字を付加して表示します。
[$$]は複数行、[##]は1行で表示します。

setButtonLabel.jsfl
レイヤーを追加し、そのレイヤーに _up, _over, _down, _disabled のラベルを付けたフレームを作成します。

BmpPropLosles.jsfl
ライブラリ内の選択した複数のビットマップ画像をロスレスに設定します。

ConvertSymbol.jsfl
選択したステージ上のムービークリップ、ビットマップ画像を左上を基点としたムービークリップに変換します。
実行するとプロンプトに名前が入力された状態で表示されますので、そこで変更が可能です。

ItemSearch.jsfl
選択したステージ上のムービークリップをライブラリの中から探して選択します。

NextKeyFrame.jsfl
選択中のフレームの次のキーフレームを選択します。

PrevKeyFrame.jsfl
選択中のフレームの1つ前のキーフレームを選択します。

Numbering.jsfl
選択したステージ上の複数のムービークリップに連番付きのインスタンス名を設定します。
1つ目のプロンプトにベースとなる名前を入力します。
2つ目のプロンプトには連番の開始番号を入力します。
連番は x=0, y=0 に近いものから順に設定されます。

setZeroPosition.jsfl
選択したステージ上のムービークリップの位置座標を整数値に丸め込みます。

SplitFrames.jsfl
選択中の複数のレイヤーを1つのレイヤー上に、フレーム毎に分割して配置します。

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);
    }
  }
}