Director MX 2004以降、ウインドウクラスのオブジェクトからアクセス(_player.window[1].movie...)できるようになりました。これにより、他のムービー自体のメソッドやプロパティにも、現在のムービーからアクセスできます。従来、ムービー内部のアクセスは、そのムービー自身からしか行えませんでした。そのため、tellコマンドというやや特殊な仕様がありました。しかし、ウインドウオブジェクトやムービーオブジェクトにより、より簡単にムービーを扱えるようになりました。ですが、簡単なことには落とし穴があります。
下記のスクリプトは、スプライトの矩形を変更する単純な例です。問題はなさそうですが、実は動きません。構文が間違っていないので、エラーも出ません。 (*もちろん、これが自身のムービーで実行されているのであれば、_player.window[1].movieの代わりに _movieを使うのが当たり前ですが、別のムービーから実行されることを想定しています。)
-- Script 1 myRect = _player.window[1].movie.sprite(1).rect --(1) newRect = myRect.offset(10,10) _player.window[1].movie.sprite(1).rect = newRect --(2)
ポイントは 2つあります。ひとつに、windowオブジェクトからアクセスした場合、メソッドの返値やプロパティで取得できる値が、自身のムービーからアクセスした場合と異なります。下記はwindowオブジェクトからのアクセスと、自身のムービーからプロパティを取得を比較した例です。
-- Script 2 put _player.window[1].movie.sprite(1) -- <Object sprite 1 c70364> put _movie.sprite(1) -- (sprite 1) put _player.window[1].movie.sprite(1).rect -- <Object rect 1 c70268> put _movie.sprite(1).rect -- rect(-42, 4, 362, 236) put _player.window[1].movie.sprite(1).loc -- <Object point 1 c70340> put _movie.sprite(1).loc -- point(160, 120) put _player.window[1].movie.sprite(1).name -- "mySprite" put _movie.sprite(1).name -- "mySprite" put _player.window[1].movie.sprite(1).top -- 4 put _movie.sprite(1).top -- 4
windowオブジェクトからアクセスした場合、Rectや Pointなどの Director特有のオブジェクトは実体を返しません。 返値はそのwindowオブジェクトが管理するメモリ領域に保存され、その保存された値への参照を返すようです。値が StringやIntegerなど単純なオブジェクトの場合は、その値を返します。
ふたつ目に、メソッドの引数や、オブジェクトのプロパティに入力する場合、movieオブジェクトからの参照が使えません。Script 1では、(1)で、myRectには windowオブジェクトからの参照が入っています。 次の行で、オフセットした値を newRectに代入しています。しかし、このnewrect自体も windowオブジェクトからの参照になります。(2)で代入しようとしていますが、これは働きません。まるで、Director内部でnewRectのデータ型をみて弾かれているような印象です。このサンプルの場合、rect型のデータを作成し、代入することで解決します。
-- Script 3 myRect = _player.window[1].movie.sprite(1).rect --(1) newRect = myRect.offset(10,10) newRectCopy = rect(newRect.left, newRect.top, newRect.right, newRect.bottom ) _player.window[1].movie.sprite(1).rect = newRectCopy --(2')
しかし、これはスマートでないうえに、根本的な解決ではありません。もっとも問題がない手順は、windowオブジェクトから直接アクセスするのではなく、movieオブジェクトに同様の操作が行えるメソッドを作成し、メソッドを呼び出すことで、そのムービー内部ですべての処理をおこわせることです。
-- ムービースクリプト on spriteOffset xSpNum, xH, xV myRect = _movie.sprite(xSpNum).rect newRect = myRect.offset(xH,xV) _movie.sprite(xSpNum).rect = newRect end -- 他のムービーからの呼び出し _player.window[1].movie.spriteOffset(1,10,10)
windowオブジェクトからアクセスを多用したスタイルの欠点として、デバッグの複雑さがあります。Script 1では、動かないのにエラーも出ませんでした。(もちろん、エラーがでるメソッドやプロパティもあります。) さらに私たちは、myRectが、実体なのか参照なのか知る術がないように思えます。 ilk(myRect)で返されるオブジェクトタイプはどちらの場合も #Rectです。
とはいえ、windowオブジェクトからダイレクトにアクセスできる手軽さや便利な一面も利用したい場面もあります。その場合の手順をふたつ示します。ひとつ目は、Script 3のように、新しい値を用意することです。データのタイプが分かれば新たな値は用意できます。ふたつ目は推奨されていない、古いスタイル( tell )を使うことです。
-- Script 5 tell _player.window[1] to myRect = _movie.sprite(1).rect put myRect -- rect(-12, 34, 392, 266) newRect = myRect.offset(10,10) _player.window[1].movie.sprite(1).rect = newRect --OK
お恥ずかしながら、初めて tellコマンドの動作が理解できた気がします。ウインドウオブジェクトからのアクセスした場合、その返値はそのムービーのメモリ領域に保存されるようだというのは前述しました。たとえば、myRect = _player.window[1].movie.sprite(1).rect の myRectのデータは _player.window[1].movieに記録されます。けれど、tell _player.window[1] to myRect = _movie.sprite(1).rect の myRectのデータ本体は実行中のムービーに記録されます。おそらく、こんな解釈であってると思います。残念ながら、tellコマンドは使用できるものの、マニュアルには廃止されたと明言されています。たしかに、イマドキでないスタイルですが、ウインドウオブジェクトからのアクセスが完全?でない現在、まだまだ使う機会もあるのではないでしょうか。
もともと他の言語体系に比べると、Directorスクリプトはデータ型に関しては曖昧です。ですから今回の場合も、もっとルーズに Director側が判断してくれたら何の問題もないような気もします。ただ、他のオブジェクト指向でも通用するスタイルを勉強するには良い教材になるのかもしれません。
Trackbacks/Pingbacks (Trackback URL)
Comments
-
appliance repair said April 07, 2012 17:06
Maar willen zeggen dat dit is uiterst nuttig, Bedankt voor het nemen van uw tijd om dit te schrijven.