サイトトップ

Director Flash 書籍 業務内容 プロフィール
 

Macromedia Director非公式テクニカルノート

Flashスプライトにオブジェクトを設定したい

ID: FN0501003 Product: Director

Platform: All
Viersion: MX 2004 and above

FlashスプライトにDirectorから、文字や数値などの単純な(プリミティブ)値でなく[*1]、配列やオブジェクトを変数に設定して、SWF内で使用したい場合があります。

[*1] 変数にストリング(文字列)や数値を設定する方法については、「Flashスプライトに数値の変数を設定したい」をご参照ください。

1. setVariable()とnewObject()関数を使う
Flashスプライト内に変数を「設定」したい場合には、setVariable()関数を使う必要があります。ただし、setVariable()関数で変数の値を指定する第2引数は、ストリング(文字列)でなければなりません。そのため、まずストリング値の変数を設定したうえで、実際に使用する値を後から代入するかたちをとります(前出注[*1]参照)。

Flashオブジェクトは、newObject()関数で生成することができます。Flashスプライトをsprite(1)とし、[メッセージ]ウィンドウで試してみます。

スクリプト001■メッセージウィンドウでFlashスプライトに配列を設定

mySprite = sprite(1)
test_array = newObject("Array")
test_array.push("test0")
mySprite.setVariable("my_array", empty)
mySprite.my_array = test_array
put mySprite.my_array[0]
-- "test0"

一見、問題なくFlashスプライト内に、配列が設定できたように思えます。しかし、この変数値は、FlashのSWFから調べると、値がundefined(未定義値。Lingoのvoidに相当)と認識されてしまいます。Flash内の変数値を調べて出力するテスト用の関数を、つぎのようにFlashのフレームアクションとして設定します(Directorのノートですので、Flashの関数定義については、解説を割愛します)。

スクリプト002■ストリング値のパスを参照に変換してプロパティを出力する関数

// Flash SWF: DirectorのFlashキャストメンバーとして読込む
// タイムライン: _root
// 第1フレームアクション
function xTrace(path_str:String) {
  var obj:Object = eval(path_str);
  trace([obj, typeof obj]);   trace("=====");
  if (typeof obj == "object") {
    for (var prop:String in obj) {
      trace([prop, obj[prop], typeof obj[prop]]);     }
  }
}

上記スクリプト002を設定したSWFをFlashスプライトとして配置し直したうえで、[メッセージ]ウィンドウからスクリプト001を再度試します。続けて、スクリプト002の関数xTrace()を呼出す以下のステートメントを実行します。関数には引数として、値を調べる配列のパス"_root.my_array"をストリングで渡します。

-- [メッセージ]ウィンドウに追加して実行
mySprite.xTrace("_root.my_array")

すると、Flash側の関数xTrace()からつぎのような出力が、[メッセージ]ウィンドウに返されます。

-- [type Object],object
-- =====
-- 0,undefined,undefined

まず、Flash内でmy_arrayの存在は認識されています。しかし、配列であればエレメントがカンマ区切りで表示されるはずなのに、"[type Object]"と出力されてしまいます[*2]。また、配列エレメントの存在は認識されているようで、配列インデックス0が出力されます。ところが、値はundefinedになっています(図002)。結局、Directorで設定した配列は,Flash側では正しく認識されていないということになります。

図001■Flashの関数xTrace()から返された出力

[*2] typeof演算子で配列(Arrayインスタンス)を調べると、データタイプとしては"object"が返されます。したがって、このデータタイプ自体には、問題ありません。

2. スプライト内にオブジェクトを生成するnewObject()メソッド
newObject()には、トップレベル関数として単独で使用する場合(スクリプト001)のほか、スプライトを参照してターゲットに指定するメソッドのシンタックスがあります。Flashスプライト内にオブジェクトを生成するには、実はメソッドシンタックスを用いなければならないのです。

トップレベルのnewObject()関数は、Director内にグローバルオブジェクトを作成します。グローバルオブジェクトとFlash内のオブジェクトは,メモリ空間が別途に管理され、これらの間でデータを移すことはできません[*3]。

FlashのSWF内に配列を設定するには、つぎのようにFlashスプライトに対するメソッドとしてnewObject()を呼出します(スクリプト003)。

スクリプト003■newObject()メソッドでFlashスプライト内に配列を作成(1)

mySprite = sprite(1)
test_array = mySprite.newObject("Array")
test_array.push("item0")
mySprite.setVariable("my_array", empty)
mySprite.my_array = test_array
put mySprite.my_array[0]
-- "item0"
mySprite.xTrace("_root.my_array")
-- item0,object
-- =====
-- 0,item0,string

なお、上記のスクリプト003は、もう少し簡潔に記述することも可能です(スクリプト004)。

スクリプト004■newObject()メソッドでFlashスプライト内に配列を作成(2)

mySprite = sprite(1)
mySprite.setVariable("my_array", empty)
mySprite.my_array = mySprite.newObject("Array")
mySprite.my_array.push("item0")
mySprite.xTrace("_root.my_array")
-- item0,object
-- =====
-- 0,item0,string


[*3] Flashスプライト内のオブジェクトも、スプライトごとに別途管理されます。したがって、異なるFlashスプライト相互の間でオブジェクトを移行することもできません。

なお、トップレベル関数とFlashスプライトメソッドによるnewObject()の違いについては,[DIRECT-L]「Can Director pass a Flash object into Flash sprite?」のThomas Higgins氏の投稿ご参照ください。Tom Higgins氏は、Director Developer Centerに「Using Macromedia Flash Objects From Scripting in Director MX」という記事も寄稿されています。

3. オブジェクトの配列を設定する
応用事例として、Flashスプライト内にオブジェクトの配列を作成し、それを利用してみましょう。「Flashスプライトを操作する」でご紹介したスクリプト005「Flashスプライトのビヘイビア自身による初期化処理でComboBoxインスタンスを生成」のサンプルを修正します。

ComboBoxインスタンスmy_cbへの項目とデータの設定は、ComboBox.dataProviderプロパティを用いて行います。ComboBox.dataProviderには、項目をlabel、データをdataというプロパティとしてもつオブジェクトを、配列に格納したうえで、その配列を設定します。つまり、ComboBox.dataProviderに設定するのは,Objectインスタンスをエレメントとして格納した配列(Arrayインスタンス)ということになります。

修正するのは、xCreateComboBox()ハンドラです。まず、ComboBox.dataProviderに設定する配列を初期化します。つぎに、その配列に、項目とデータをプロパティにもつオブジェクトを、必要な数だけ追加します。オブジェクトの追加は、repeatループで処理します。そして最後に、その配列をComboBox.dataProviderプロパティに代入します(スクリプト005)。

スクリプト005■ComboBox.dataProviderプロパティにObjectの配列を設定

property mySprite, lList, nDelay

on beginSprite(me)
  mySprite = sprite(me.spriteNum)
  lList = ["item0", "item1", "item2"]
  _movie.actorList.append(me)
end

on stepFrame(me)
  ComboBox = mySprite.getVariable("_global.mx.controls.ComboBox", false)
  put ComboBox
  if (objectP(ComboBox)) then
    me.xCreateComboBox(ComboBox)
    _movie.actorList.deleteOne(me)
  end if
end

on xCreateComboBox(me, ComboBox)
  _root = mySprite._root
  my_cb = _root.createClassObject(ComboBox, "my_cb", 1)
  my_cb._x = 10
  my_cb._y = 10
  items_array = mySprite.newObject("Array")
  nCount = lList.count
  repeat with i = 1 to nCount
    --  & my_cb.addItem(lList[i], i)
    oItem = mySprite.newObject("Object")
    oItem.label = lList[i]
    oItem.data = i
    items_array.push(oItem)
  end repeat
  my_cb.dataProvider = items_array
end

_____

作成者: 野中文雄
更新日: 2005年10月12日 newObjet()関数についてDeveloper Center「Using Macromedia Flash Objects From Scripting in Director MX」をリンク。
作成日: 2005年10月8日


Copyright © 2001-2006 Fumio Nonaka.  All rights reserved.