複数のモルフを組み合わせてひとつのモルフにする
今回は、前回の内容に対する若干の補足を兼ねて、モルフやスクリプトをまとめる方法、モルフを単独でファイルに保存したりそのファイルを読み込む方法を紹介する。
■サブモルフ化
前回は、円形モルフと矩形モルフ、そしていくつかのボタンモルフの組み合わせでバウンスを実現した。これらは協調して動くので、まとまりがあるように見えるが、どれかひとつをピックアップ&ドラッグすると簡単にバラバラになってしまう。複数のつながりの深い部品モルフをひとつにまとめる、ドロー系ソフトにおける「グループ化」のような機能はないのだろうか? Morphic ではこれをを「サブモルフ(submorph)」というモルフ間の関連づけ機能により実現している。サブモルフ化は注目したモルフの「親」となるモルフを指定して設定する。
- 矩形モルフを Supplies フラップからドラッグ&ドロップ
- コマンド+クリックで選択
- 300x300 ドット程度にリサイズ
- 円形モルフを Supplies フラップからドラッグ&ドロップ
- 20 ドット程度にリサイズ
- 矩形モルフの上に円形モルフをピックアップ&ドロップ
- この状態では矩形モルフも円形モルフも独立してクリック&ピックアップできる
- 矩形モルフが前面に来てしまったら send to back で後ろへ
- ちなみに茶ハロは前後関係を変えずに位置の移動ができる
- 円形モルフをクリックして選択
- 赤ハロをクリック
- 表示されるメニューから embed into を選択
- サブメニューに「Rectangle」という選択肢があることを確認してそれを選択
- 矩形モルフをクリック&ピックアップすると、円形モルフも同時に動く
- 円形モルフを選択するときは、shift+コマンド+クリック
サブメニューに world (もしくは、PasteUpMorph)しかなければ、円形モルフに回転操作が加えられていないか(heading が 0 になっているか)( 4811 では修正されたようです --sumim)、矩形モルフの範囲内にあるか(中心が矩形モルフの縁の中にあればよい)を確認する。どうしてもダメなら、矩形モルフと円形モルフを破棄して最初から試してみる。
以上の操作で円形モルフは矩形モルフのサブモルフとして登録される。このような関連づけが行なわれると、わかりやすい効果としては(矩形モルフと円形モルフの場合)、1)円形モルフはクリック&ピックアップできなくなる。2)矩形モルフをピックアップ&ドラッグすると円形モルフも同時に動く、のが確認できるだろう。
サブモルフ化を解除するには、複数回コマンドクリック(もしくは sfhit + コマンドクリックで直接)で円形モルフを選択したのち、黒ハロのピックアップ&ドラッグで親モルフの範囲外に移動するか、embed into メニューで PasteUpMorph (world とあればそれを)を指定すればよい。茶ハロで移動すると、サブモルフを解除せずに移動できる範囲でしか移動しない。茶ハロは黒ハロと違い、モルフ間の前後関係を変えずにターゲットのモルフを移動するのに使う。3.2gamma-4811 では、黒ハロのピックアップ&ドラッグを使ったサブモルフ化の解除は、親モルフの範囲内でも行われるようです。--三橋 - 2002-04-19, 15:51:25
■バウンスモルフ1
サブモルフ化はドロー系ツールにおけるグループ化と同様、複数のモルフをまとめて扱うために便利な機能であるほかにモルフ間の連携にも役立つ。親モルフは自分がどんなモルフを子供として従えているかを知っており、また子も親が誰かを知っている。本レッスンのテーマの「バウンス」機能に関して言えば、円形モルフは親、つまり自分の行動範囲を決める矩形モルフが誰かを必要なときに知る(holder タイル)ことができるので、円形モルフは親がだれであっても、その大きさを示す矩形内で動くスクリプトを組むことができる。
【図:特定の矩形でないと動作しない「バウンス」のためのスクリプト】
【図:親がだれでもよい「バウンス」スクリプト】
「Rectangle's」タイルを「Ellipse holder」に差し替えるには、以下の方法に従う。
- 円形モルフのビューワを開く
- miscellaneous カテゴリを開く
- holder タイルをクリックして、Ellipse's holder タイルをピックアップ
- スクリプタの Rectangle's タイルにドロップイン
前者は、スクリプタ中で Rectangle タイルで示される特定の矩形モルフ内に円形モルフがないと機能しないが、後者の場合、円形モルフは自分を embed into したモルフ(特に親を指定しなければデスクトップ)の大きさを示す矩形矩形範囲内で同じ振る舞いをする。
【図:親モルフを変えるとそのモルフに合わせて動く円形モルフ】
■繰り返し出現するスクリプトをまとめる
上下の壁にぶつかったとき、向きを 180 度から今の自分の向きを示す角度を引く方向に転回する。上と下、2つの場所に同じ記述が出現している。左右についても同じだ。このように何度も現れる手続きは、ひとつのスクリプトにまとめておくと扱いやすい。
- 円形モルフビューワの scripts カテゴリを呼び出す
- emptyScript タイルをクリックして Ellipse emptyScript タイルをピックアップ
- デスクトップにドロップすると空のスクリプタが表示される
- 「script云々」と書かれた部分をクリックして「bounceV」などと入力し return キーで決定
- Ellipse's heading ← 0 - Ellipse's heading タイルをドロップイン
- Ellipse forward by 5 タイルをドロップイン
- bounceV スクリプタを閉じる
- 元のスクリプタから重複分のタイルを除去
- ビューワから Ellipse bounceV タイルをピックアップし、除去した場所にドロップイン
- 同様に左右の壁での処理「bounceH」を作り、元のスクリプタで置き換える
このようにしてけば、例えば、バウンスするときに Ellipse make sound croadk タイルで音を出す、といった機能の変更をするとき、bounceH、bounceV に追加すればよいので手数を減らせるし、なにより元のスクリプタがすっきりして見やすくなる。
【図:繰り返し出現するスクリプトを別にまとめて見やすくなったスクリプト】
■ビューワにない状態を保存したり参照する(インスタンス変数)
各モルフにはインスタンス変数という自由に中身を入れ替えることのできる「入れ物」のようなものを個別に用意できる。
- インスタンス変数を新しく設けたいモルフのビューワを開く
- モルフ名の左にあるメニューボタンで現れるメニュー(ビューワメニュー)から、make new instance variable を選択
- within などと適当な名前をタイプし、accept する
- ビューワの instance variable パネルに付けた名前のタイルが現れる
- インスタンス変数の左手のメニューボタンをクリック
- メニューから change date type を選択
- boolean (真偽値)を選ぶ
たとえば、このタイルを使って、withinH などとした下のようなスクリプトを組んでみよう。
【図:親モルフの左右の幅に収まっているかどうかを調べるスクリプト】
こうすることで、もとのスクリプトで入れ子になった条件タイルをひとつにまとめることができる。スクリプトの流れとしてもより見やすくなる。
【図:より流れを把握しやすいバウンスのためのスクリプト】
また、スクリプタでは複雑な計算はできない。計算式は加減乗除の区別なく、単純に後ろから評価されていくので、込み入った式を扱いたいときは、適当なインスタンス変数を用意し、そこの途中結果を代入、その結果を用いて改めて大枠の計算をするという分割作業が必要とされる。まあ、そこまで複雑な式を扱わなければならなくなってきたら、タイルでのスクリプティングは諦めて、より便利で小回りの利く次のステップ(タイルではなくテキストによるスクリプト記述)に進むことをお薦めしたい。
■スクリプトの実行速度を速める
もうすこしキビキビと円形モルフが跳ね返る様子を見てみたいと思う人もいるだろう。実は、今のスクリプトは動作速度が意識的に制限されており、具体的には1秒回に8回の動作しかしないようになっている。この回数を多くしてやれば、円形モルフを目にもとまらぬ速さで動かすことも可能である(実際にはマシンのパフォーマンスの限界があるので、適当なところでそれ以上は速くなくなる)。
- 動作スピードをあげたいスクリプトの時計アイコンをプレス&ホールド
- メニューが現れるので、より大きな数字を選ぶ
■バウンスモルフ2
サブモルフ化を知ると、バウンス機能は組み込みのタイル「Ellipse bounce …」で簡単に実現できる。このタイルは親モルフの範囲内でバウンスし、バウンスするときに「…」部分で指定された音を出す。
【図:バウンスのためのスクリプタ】
■モルフの回転
青ハロは選択されたモルフを自由な角度で回転させる機能を持つ。サブモルフを持つ場合は、それらも一緒に回転する。
- コマンド+クリックで矩形モルフを選択
- 青ハロをドラッグして回転
残念ながらそのままでは、円形モルフは上図のように期待した動きをしてくれない。これは、デスクトップをクリックしたときに現れるメニュー → playfield options... → fence enabled を選んでこの機能をオフにすれば解消する。なお、このオプションをオフにすると、モルフが表示範囲を超えて forward by などで移動しようとしたとき、それを妨げる機能が働かなくなる。画面から見えなくなったモルフは、そのビューワの最上段、そのモルフのビューワメニューから grab me を選べば取り戻すことができる。
【図:fence オプションを外す】
■できあがったモルフの情報をファイルに書き出す
モルフはサブモルフやスクリプトを含めてファイルに書き出すことができる。モルフの情報を保存しておけば、別の仮想イメージから同じモルフを利用することができる。
- 保存したいモルフを選択
- 赤ハロメニューから save morph in file を選択(見つからないときは debug... にある)
- ファイル名を確認して(必要なら変更して) accept する。
ファイルは仮想イメージと同じフォルダに .morph 拡張子を付けて保存される。
my RectangleMorph.morph
■ファイル出力したモルフを読み込む
ファイルの読み込みはファイラである「ファイルリスト(FileList)」を用いる。
- 右手の Tools フラップから FileList をドラッグ&ドロップ
- 左手下段ペインで * を *.morph を書き換えて return を押す
- 左手のファイルリストペインに .morph ファイルが表示されるのでクリックして選択
- option+クリックか、スクロールバーにあるメニューボタン(上矢印の下のボタン)をクリック
- メニューから load as morph を選択
名前の入力を促すボックスでのタイプのときにすでに気が付いておられるかも知れないが、Squeak では、マウスポインタがその枠内に無いと入力ができないようになっている。特に、上の手順のように大きなウインドウのペイン(枠)になにかを入力しなければならないときは、そのペイン内にマウスポインタが入っているかどうかをよく確認する必要がある。デフォルトでは、ペイン内にマウスポインタが入っているときだけ、そのペインのスクロールバーが表示されるのでこれを目印にするとよいだろう。
前へ 次へ
#更新履歴#
2002.04.11 ロック解除。
2002.03.10 次回へリンク。
2002.03.05 図版貼り込み。
2002.03.03 図なし改訂版掲載。
2002.03.02 3.2gamma ベース。概要のみ。
感想、要望、苦情などありましたら、本文中か下のスペースにどうぞ。
「embed into メニューで world を指定」と記述がありますが、デモでは「PasteUpMorph」と表示されています。またサブモルフ化の説明の個所の記述に「サブメニューに PasteUpMorph(デスクトップのこと)」とありますので、「embed into メニューで PasteUpMorph を指定」と記述した方がいいと思います。(修正しました) なお、3.2gamma-4811 では「world」と表示されています。(トップ・プロジェクト中ではそうなるようです。--sumim)要調査 --三橋 - 2002-04-19, 16:02:16
3.2gamma-4811 で、円形モルフのスクリプトに Ellipse's holder を導入後、実験で円形モルフの親を world にしてスクリプトを実行すると、しばらくして Squeak がハングアップしてしまいます。当方の環境だけの現象かも知れませんがご報告いたします。--三橋 - 2002-04-19, 17:23:34
- 当方でもテストしてみます。お手数ですが、VM バージョン、環境(OS など) を教えていただけますか? --sumim - 2002-04-19, 17:55:43
- ウチは問題ないみたいです。念のため環境は、Squeak 3.2.5Beta8.app、 Mac OS 9.2.2 です。--sumim - 2002-04-19, 18:42:18
はじめまして。ハングアップの件ですが、私もなります。
とりあえず、worldにはしないようにしています。
Squeak 3.2.5Beta8.app, MacOS 9.2.2 と MacOSX 10.1.4のどちらでもです。 --kuro - 2002-04-19, 23:38:54
- fence enabled は off になっていますか? それでも操作を受け付けなくなるようなことはないのですが…。なにかがきっと違うんでしょう。よかったら、ハングするプロジェクトをアップしてみてもらえますか?--sumim - 2002-04-20, 00:25:19
もう一度試してみましたが、やはりハングしました。
fence enabledがoffなのを確認してから行いました。
今回は、vmのウィンドウが開いて
out of memory
727905376 OrderedCollection>copyEmpty
727905284 OrderedCollection>select:
727904824 [] in SoundPlayer class>playLoop
727904916 [] in Semaphore>critical:
727905100 BlockContext>ensure:
727904732 Semaphore>critical:
720929936 SoundPlayer class>playLoop
720929724 [] in SoundPlayer class>startPlayerProcessBufferSize:rate:stereo:sound:
720929816 [] in BlockContext>newProcess
と表示されました。
プロジェクトのアップは後ほど行います。--kuro - 2002-04-21, 07:33:53
- 仮想マシンの割当てメモリを増やしてみてください。--sumim - 2002-04-21, 22:43:42
遅くなりすみません。当方の環境です。
Squeak 3.1 VM (alpha build 6) from May 17 2001
Compiler: gcc 2.95.2 19991024 (release)
OS は Windows 98 Second Edition 4.10.2222 A です。--三橋 - 2002-04-22, 12:50:02
- 三橋さん、ありがとうございます。Virtual PC でほぼ同様の環境が手元にありますので、時間をみて試してみます。--sumim - 2002-04-22, 14:11:35
一応 ugago.pr をアップしましたが、直前に確認したところ embed into world が出なくなっています。
仮想マシンの割当てメモリは増やしました。アドバイスありがとうございます。--kuro - 2002-04-22, 20:00:05
- うまく動くようになるとよいのですが…。プロジェクトのアップ、ありがとうございます。試してみます。--sumim - 2002-04-22, 20:57:03
- 現象を確認しました。Win98SEでSqueak3.2gamma-4811です。
ugago.prをロードしたプロジェクトで、EllipseをWorld(ロードを実行したプロジェクトによってはPasteUpMorph。以後Worldに統一)にembed intoすると、無限ループに入った後にout of memoryになります(ユーザインタラプト(alt(コマンド)+ピリオド)してみると、TransformationMorph>>headingでループ)。
また、EllipseがRectangleと重なっているにも関わらずembed先としてWorldしか出ないのも変です(これは以前にheididorfさんが指摘していたのと同じ問題か)。
このとき、embed intoを使わずに黒ハロのドラッグで背景(PasteUpMorph)にドロップすれば大丈夫です。ただし、一度こうなると、今度はRectangleにembedできなくなります。
当座の回避策としては、貼り付けられる側(この場合はRectangle)の赤ハロメニューのaccept dropsをチェック(あるいはビューワのdrag & dropカテゴリのdrop enabledをtrueに変更)することで、EllipseをRectangleにドラッグ&ドロップするだけでembedできます。--abee - 2002-04-22, 21:36:52
- ああ、それはいいアイデアですね。そっちのほうが直感的だしドロップイン(サブモルフ化)が完了すると単独でピックアップできなくなるからわかりやすいし、終わったら false にするのも簡単と。ありがとうございます。そのセンで書き直してみましょう。……。そのうち(^_^;)。いつも、フォローをありがとうございます。--sumim - 2002-04-22, 21:48:57
このページを編集 (15766 bytes)
|
以下の 5 ページから参照されています。 |
This page has been visited 7531 times.