• ベストアンサー

FLASHナビボタンで、アクションスクリプトの記述の誤り

縦に並ぶアニメーションのナビボタンのスクリプトを横に並ぶ形のサンプルソースを元に書き換えしているのですが動作しません。補足でソースをコピーしますので、どこが誤りなのでしょうか。教えてください。 ボタン動き→onmouseでH=200%拡大、イメージがスワップ。その他のボタンはそれにつれてH=伸縮。 ※辞書を引きながらのつたない間違いかと思いますが…宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • DPE
  • ベストアンサー率85% (666/776)
回答No.2

ムービークリップの配置や階層構造などが不明なので、憶測まじりになりますが。  > this.init();  > this.onEnterFrame = function() {  > if (base.hitTest(_root._ymouse, _root._ymouse, false)) {     : 3行目の hitTest は、ムービークリップ同士、もしくはムービークリップとある1点の座標の衝突を判定でき、どちらの衝突を判定するかは渡すパラメータで決まります。 今回は後者の、ムービークリップとある1点の衝突を判定しているものと思われます。 この場合の書式は  hitTest( X座標 , Y座標 , true または false ); です。 しかし、X・Y座標を渡さなければならないところを、両方ともマウスカーソルのY座標( _root._ymouse )を指定していますね。 動かなくなったのは、このためだと思います。 とりあえず、この部分を  if (base.hitTest(_root._xmouse, _root._ymouse, false)) { と変えてください。 それから、初期化をしている init 関数ですが。  > //値の初期化  > function init() {  > cntX = 5;  > top = base._y-base._height/2;  > bottom = base._y+base._height/2;  > for (i=0; i<=cntY; i++) {  >line = this["lineY"+i];  > line._y = left+i*base._height/cntY;     : cntX = 5; で cntX という変数が定義されますけれど、以降のスクリプトで実際に稼動している変数の名前は cntY のようです。 cntX を cntY に変更してみてください。 元のサンプルでは横並びということで、X座標等を扱うので” X ”が付いた変数やインスタンス名が付けられていたものを、縦並びに改造するために” X ”の部分を” Y ”に変更なさったのではないのでしょうか。 これは私の推測なのですが、元のサンプルには lineX0 ~ lineX5 というインスタンス名が付いたムービークリップがありませんか? このムービークリップを、rollover ・ rollout 関数で操作していると思われます。 これらの関数で lineX +番号というムービークリップを操作していたのだとしますと、スクリプトを lineY +番号に変更しただけでは、実際にはムービークリップが存在しないのでスクリプトが空回りしてしまいます。 ”分割線”と呼ばれているムービークリップのインスタンス名を確認して、lineX +番号 となっているようなら、これを lineY +番号 に変更してください。 最後に、rollover 関数ですが。  > //カーソルの位置に応じて分割線を移動する  > function rollover() {  > for (i=1; i<=cntY; i++) {  > line = this["lineY"+i];  > if (line._y<_root._xmouse) {     : 横並びのメニューではマウスカーソルのX座標と比較しているのは分かるのですけれど、縦並びにするならY座標と比較することになると思います。 上記の最後の行を  if (line._y<_root._ymouse) { にしてみてはいかがでしょう。 ざっと見たところ、気になったのは以上の点です。 実物を見ないと詳しくは言い切れませんけれど、ご参考までに。

niconico_1969
質問者

補足

有難うございます。大変わかりやすいご説明で助かります。 タテの動きのほかのサンプルをみて、xとyの記述モレと、インスタンス名のlineX数字をlineY数字にする点に自分でも気づくことができました。(lineX数字の存在を言い当てていらしたことに感動でした) これでswfは開くようになりましたが、以下のようになってしまいました。 現在の表示のされ方: ■5つのボタンのうち3つめしかみえていなくて他の部分は下に敷いたbaseがみえている。 ■みえている3つめのボタンはyの位置が1/2分上にずれている。 ■マウスをのせても反応がない。 実際にflaファイルを見ていただけたら一番なのですが… 現在レイヤーはactionと、lines,items,baseの3つです。 linesには、lineY0~5が、itemsにはitem1~5、baseにはbaseというインスタンス名のmcが入っています。ltem1~5は入れ子のmcで、「ボタン」であるmcと「onmouseすると現れるイメージ」であるmcをピッタリ重ねたものです。 サンプルをwebでみることができるらしいので ご参考までに見ていただくことは可能でしょうか。 http://www.oshige.com/flash/mx/index.html →サンプルメニューパネルを開く→17番→2行目:ロールオーバーしたマス目が開くコンテンツメニュー これが、参考にしている横並びのスクリプトです。

その他の回答 (12)

  • DPE
  • ベストアンサー率85% (666/776)
回答No.13

タイムラインの表示が、  action  ○a○a  メニュー ○□●□ このようになっていますでしょうか? メニューを構成するレイヤーは、実際はいくつかあると思いますが、どれも同じフレーム構成にします。 それから、# 11 で nextFrame アクションを使った例を紹介しましたが。 nextFrame は”次のフレームで再生ヘッドを止める”というアクションで、フレーム3に stop(); を書く代わりに使えます。 しかし今回の変更では、フレーム3ではなくフレーム4でタイムラインを止めます。 フレーム2に nextFrame を書くとフレーム3でタイムラインが止まってしまい、フレーム4に設定してあるメニューを制御するスクリプトが何も実行されないため、メニューは反応しなくなります。 nextFrame を追加した場合は、フレーム2にある if 文の else 以下を削除し、フレーム4のスクリプトの末尾に stop(); を入れてください。 「ムービープレビュー」の時、「表示」→「プロファイラ」にチェックを入れておくと、ムービーに関する様々な情報が表示されるようになります。 「プロファイラ」パネルの左側にはムービーの容量等が表示されます。 この中の「状態」の項目に、現在再生しているフレームの情報があります。 ここがフレーム3で止まっているようなら、nextFrame が悪さをしているのだと思います。

niconico_1969
質問者

お礼

DPEさん、遅くなりましてすみません。 先日職場をかわったもので、この左ナビを含んだサイトも納品いたしました。でも結果からいうとやはり最初の1回は勝手に開いてしまいます。 タイムラインの表示はそのようになっているのですが。nextFrame を追加したのでフレーム2にある if 文の else 以下を削除し、フレーム4のスクリプトの末尾に stop(); を入れたので反応がなくはないのですが。 先方がこれでよいというので納品になりましたが、 これから自分で修正をしていきたいと思っています。 プロファイラのチェックで情報を得て自己解析ができるんですね。ぜひやってみます。 長期にわたってしまったので一度こちらは締め切りにしますが、またお聞きすることがあると思いますので、そのときはお願いします。FLASHが苦手な私には本よりずっとわかりやすい先生なので・・・。 ご教授ほんとにありがとうございました。

  • DPE
  • ベストアンサー率85% (666/776)
回答No.12

プリロードを付けてもダメでしたか... しかし、少なくとも最初の1度は大丈夫、ということでしょうか? とすると、スクリプトやムービークリップの作り方・配置などの誤りが原因ではないと思います。 では、フレームを1つ増やし、フレーム4にスクリプトを移動してみてはいかがでしょうか。 読み込みというよりは Flash Player 内部での処理の順番の問題だと思うのですが、フレームアクションでそのフレームにあるムービークリップを操作しようとすると、スクリプトが実行される時にはムービークリップがまだ存在しないことになっていて、正常に操作できない場合があります。 スクリプトでインスタンス等を制御するには、制御する対象はスクリプトが実行される時よりも先に存在していなければなりません。 普通はあまり神経質になるほどでもないのですが、ムービークリップの容量が大きい場合などに、このわずかなタイムラグにより、スクリプトに問題がなくても上手く制御できないことがあります。 プリロードは、全フレームとシンボルのデータがダウンロードされたかどうかを判断するだけです。 各フレームが再生される時、インスタンスがステージに配置されたかどうかまでは、プリロードのスクリプトでは判断できません。 (オンライン環境では、2回目以降はキャッシュから拾われてプリロードが省略されることもあります) 要は、ムービークリップの方がスクリプトよりも先に存在していればいいのです。 ムービークリップを配置したレイヤーは、フレーム3にキーフレームを作って各ムービークリップを配置し、フレーム4には「フレームを挿入」で普通のフレームを追加します。フレーム4をキーフレームにしては意味がなくなりますので、ご注意ください。 スクリプト用の「 action 」レイヤーは、フレーム2にプリロードのスクリプトを書き、メニューの制御スクリプトと stop(); アクションはフレーム4に移動してください。 普段はフレーム4が表示されますが、ほんの一瞬、フレーム3が表示されます。 分割線やムービークリップは、「プロパティ」または「情報」パネルで座標を入力して最初からなるべく正確な位置に配置しておくと、メニューを制御するスクリプトで位置の調整が行われてもズレて見えることもないと思います。 ------------------------------------------------------ ActionScript では、構文の中に全角の文字が含まれているとシンタックスエラーになります。 例えば、  if( this._y < _root._ymouse ) ↑この条件内で使っているスペースは全て全角文字ですが、これはエラーになります。 行頭に関しても同様で、行頭に全角のスペースがあると、やはりシンタックスエラーになります。 なお、シンタックスエラーではなく”余計な } がある”という内容のエラーが報告されることがあります。 これは、全角のスペースが残っているなどでスクリプトの区切りの解釈がおかしくなり、結果的に { } や ( )、" " が正しく対応していないと判断されるためです。 スクリプトやプログラムを組む時は、インデント(字下げ)を付けると見やすくなります。 これは、文章を書く時に改行を入れたり、章の最初を1文字空けると見やすくなるのと同じことです。 ActionScript の文法では、スクリプトのレイアウト用にタブと半角のスペース・改行の使用が許されています。 スクリプト中のタブ・半角のスペース・改行は、文字列の一部として使用されている場合を除いて、スクリプトがプレイヤーで実行できる形に変換(コンパイルといいます)される時には無視されます。 インデントを付けるには、通常はタブを使います。 しかし、ブラウザではタブは省略されてインデントが無効になり、スクリプトが左端に寄って見にくくなってしまいます。 半角のスペースも同じく、連続している半角のスペースはカットされるため、私は、回答でスクリプトを紹介する時は全角のスペースでインデントを付けています。 先述の通り、スクリプトの構文の中では全角文字はご法度です。 コピーして利用する場合は、各行頭の全角のスペースを全て半角のスペースかタブに置き換えてください。 「アクション」パネルにある「置換」機能を利用すると、簡単に置き換えることができます。 スクリプトのレイアウトに関しては、ActionScript の文法に則ってさえいれば、特に制約はありません。 このあたりはスクリプトを書く人の好みや主義により様々で、例えば  if( ・・・ ) {    :  } と、{ を前の行に書く人もいれば、  if( ・・・ )  {    :  } このように改行をはさむ主義の人もいます。 私は後者の書き方が見やすいと思っているので、回答ではこちらの書き方でスクリプトを紹介していますが、解説書では紙面の都合上、行数を節約するために前者の書き方をしている場合が多いようです。 「アクション」パネルにある自動フォーマット機能でも、前者の書き方になります。 また、演算子の前後に  cntY = 5; というように半角のスペースを入れる人もいれば、入れないで書く人もいます。 半角のスペースであれば、入れても入れなくてもスクリプトの動作は同じです。 ただ、見やすいかどうかや、スペースを入れる手間を省きたいといった、スクリプトを組む時の人間の都合です。 どの書き方にも一長一短があり、特定の書き方だけが正しくて推奨されるものとは一概に言い切れません。 いろいろ工夫して、ご自分の好みに合うレイアウトや納得できる書き方を研究してみてください。 ただし、構文の中での全角のスペースについてはブラウザで表示する都合で使っているだけで、本来は使ってはならない文字です。実際のスクリプトでは混入しないよう、ご注意ください。

niconico_1969
質問者

補足

ありがとうございました。スペースの空け方、初めて知ったことも多々あり助かりました。フレームを1つ増やし、フレーム4にスクリプトを移動してみたのですが、 ご指示のとおり作ったつもりが、今度はオンマウスしてもどれも開かなくなってしまいました。 フレームで言うと、 ・1フレーム目 すべて空白キーフレーム ・2フレーム目 actionレイヤーにプリロードのスクリプト (他レイヤーは何もないふつうのフレーム) ・3フレーム目 メニューを形成するレイヤーにキーフレーム (actionレイヤーは何もないふつうのフレーム) ・4フレーム目 actionレイヤーにメニュー制御のスクリプト (他レイヤーは何もないふつうのフレーム) で間違いないでしょうか。何度もすみません。

  • DPE
  • ベストアンサー率85% (666/776)
回答No.11

すみません、stop(); が抜けていました。 メニュー画面はフレーム3に移動するわけですが、普段はタイムラインを止めてこのフレームを表示します。 フレーム3に  stop(); というスクリプトを追加してください。 メニューを制御するスクリプトの最後で構いません。 # 10 で紹介したスクリプトの if 文を  //読み込み完了を待つ  if( per < 100 )  {   gotoAndPlay( _currentframe - 1 );  }  //次のフレームでタイムラインを止める  else  {   nextFrame();  } このように変えても同じです。 再生ヘッドはフレーム3に移動して止まりますが、フレームに設定したスクリプトは”再生ヘッドがフレームに移動してきた時”に実行されますので、メニューを制御するためのスクリプトは実行されます。 前述の通り、フレームに設定したスクリプト(フレームアクション)は、再生ヘッドがフレームに移動してきた、その時1度しか実行されません。 しかし、どんなに速い回線を使っていたとしても、ダウンロードが1フレームの間に終わることはまずありえません。読み込みが済んだかどうかの判定は、ダウンロードが完了するまで数回にわたって実行する必要があります。 フレームに何度も再生ヘッドをセットし直せば、フレームアクションはその都度実行されるのですが、Flash の仕様上、同じフレームに連続して再生ヘッドをセットすることはできないようになっています。 そこで、スクリプトを書いたフレームの前にダミーのフレームを用意し、読み込みが完了するまではこのフレームとの間をループさせて、読み込み完了の判定を連続的に行えるようにします。 if 文の中で使っている  gotoAndPlay( _currentframe - 1 ); の部分が、前のフレームに戻れという意味のスクリプトです。 読み込みが済んだ後はそのまま先のフレームに進みます。 ループ再生の指示がある場合( HTMLで swf ファイルを再生するタグがそのように書かれている場合や、「ムービープレビュー」で「ループ再生」にチェックが入っている場合など)は特に、放っておくと、ループして再びフレーム1に戻ってしまいます。 また、ループ再生時でなくても、gotoAndPlay アクションを使うと、なぜか勝手にループすることがあります。 確実にフレーム3で止めるには、フレーム3に stop(); を入れてください。 ちなみに、レイヤーは新たに追加しなくても、スクリプト用のレイヤーを設けているようならそのレイヤーに書いてもいいと思います。 処理の内容は違っても、スクリプトであることには変わりがないのですからね。 もっとも、プリロードとメニューの制御のスクリプトとでレイヤーを分けても分けなくても、動作には何も影響はありません。このあたりは管理しやすいように自由に決めてください。 プログレスバーや完了率を表示したい時は、メニュー用の絵とは別に専用のレイヤーを作ると管理しやすいです。 プリロード画面の作り方は、入門者向けの解説書やあちこちの解説サイトで取り上げられています。詳しくはそちらをご参考になさってください。 #ものすごーくどうでもいいことですが、私のHNは DTP ではなく DPE です ^^;

niconico_1969
質問者

補足

ありがとうございました。 actionという名前でスクリプト用のレイヤーを作っていましたので、メニューを形成するレイヤー3つを3フレーム目に移動し(1,2フレーム目は空白キーフレームに変換)、 actionレイヤーの2フレーム目に先ほどのスクリプトをいれ(1、2フレーム目とも空白キーフレームに変換)、 3フレーム目のメニューを制御するスクリプトの最後に、stop();をいれました。 これで先ほどの点滅は直りましたが…やはり自動で1番上が開いてしまうのには変わりないようです。 最初にトップページを開いたときだけは全部閉じていてよい感じなのですが…その後別のページに移動したり、再読み込みをしたりすると、100%そうなってしまうんですよね。何か間違いがあって、きちんとプリロードしていないのかもしれませんが・・・ スクリプトの記述の仕方で基本的なことを教えていただきたいのですが、各行の最初の文字の前のスペースの空け方にはキマリがあるのでしょうか。そこが違っていてエラーになってしまうことがたまにあるので…。 それと、HN間違ってしまいすみません。いつかは、さん、が抜けてしまって呼び捨てのようになってもいたみたいで…仕事だったら同じミスを何度もして、許されないですね。申し訳ありません、、

  • DPE
  • ベストアンサー率85% (666/776)
回答No.10

一応、  ・W×H= 100 × 235 px の base (中心点は中央)を1番下に敷く  ・太さ1 pt の分割線のムービークリップ lineY0 ~ 5 (中心点は中央)を、等間隔(Y座標を 47 px おきに、左端は base の左端に合わせる)に base の上に配置  ・閉じた状態の大きさW×Hが 100 × 47 px の home と open を重ねた item1 ~ 5 (中心点は左上)を lineY0 ~ 5 の間に並べる という配置にして作り、オリジナルのスクリプトの、これまで考えてきた部分を変更してざっと試してみたのですが、メニューが勝手に開くことはありませんでした。 ActionScript では、文字列からインスタンスや変数等を参照することができます。 文字列を参照に変換するには、eval 関数か配列演算子 [ ] を使います。 今回のスクリプトでは、配列演算子 [ ] を使って変換しています。 lineY0 ~ 5 をループを使ってまとめて操作するには、  this[ "lineY" + i ]._y = ・・・ このような表記で操作できます。 この作品の制作者のスタイルだと思うのですが、このようにするとターゲットパスが長くなるので、  line = this[ "lineY" + i ]; と、予め line という変数に分割線のムービークリップへの参照を格納しておいて、  line._y = ・・・ というように、コンパクトにターゲットパスを書けるようにしているだけです。 要するに、this[ "lineY" + i ] の” Y ”はターゲット名の一部ということです。 このようなスクリプトに変更したのであれば、分割線のムービークリップのインスタンス名を lineY +通し番号で付けておけば問題はありません。 これはメニューが勝手に開いてしまう理由とは特に関係はないと思います。 あとは、オフラインではちょっと考えにくいことなのかも知れませんが・・・ open シンボルには、おそらくビットマップ画像を使用しているのだと思います。 ビットマップ系画像は容量が大きいので読み込まれるまでに時間がかかり、読み込みが完了するまでは open シンボルの height プロパティが0になっているために、勝手に開くこともあるのではないでしょうか。 item のアルファを決める setalpha 関数では、開いているボタンがあろうがなかろうが、全ての item をチェックし、ムービークリップの高さからアルファを算出しています。 もし、この中にどれか1つでも height が0のものがあれば、マウス操作によらずボタンが開いてしまうこともありうるのかもしれません。 時々上手くいったりいかなかったり、3番や4番が勝手に開くという不可解な不具合は、スクリプトや根本的な考え方・作り方の間違いというよりは、むしろ、読み込みの問題ではないかと思います。 とりあえず、プリロードを付けて、全シンボルの読み込みの完了を待ってから表示してみてはいかがでしょうか。 プリロードには様々な作り方がありますが、簡単なところで、2フレームでできる作り方をご紹介します。 ムービーの先頭に空白のキーフレームを2つ作り、2フレーム目に、次のようなスクリプトを設定してください。  //完了率の算出  loaded = _root.getBytesLoaded();  total = _root.getBytesTotal();  per = Math.floor( loaded / total * 100 );  //読み込み完了を待つ  if( per < 100 )  {   gotoAndPlay( _currentframe - 1 );  } 変数 per に、完了率がパーセントで入ります。 よく見かける、バーが伸びたり Now Loading ○%といった表示を作るのに利用できますが、メニューならそこまで読み込みに時間はかからないでしょうから、待ち時間の退屈しのぎの演出は作らなくてもいいと思います。 これでもダメだったら、申し訳ありませんが、あとはちょっと心当たりがありません。。。

niconico_1969
質問者

補足

わざわざサンプルを作っていただいて恐縮です・・・。 ささっとそのようなことができるDTPさんがうらやましいです。 プリロードを付ける方法も伝授して頂いてありがとうございます。確認させていただきたいのですが、同じムービー内に新しいレイヤーを設けるのですよね? 全体を2フレーム右にずらして、新規のレイヤーに空白キーフレームを2つ作って、その2つ目にスクリプトを記述する、というふうにやってみたら、正しく表示されませんでした。(全体がペカペカと点滅する) 知識不足ですみませんが、もう少し詳しく設定の仕方を教えて頂けないでしょうか。

  • DPE
  • ベストアンサー率85% (666/776)
回答No.9

何だか、本当に怪奇現象ですね。 原因は見当もつかないので、この先回答できるかどうか自信はありませんが、、、 base が見えてしまう件については、最終手段で、base のアルファを0%にして透明にしておけば何とかなります。 しかし、サンプルではこんな小細工をせずとも、両端のボタンも普通に動いていますよね。 となると、どこかに何か問題があるのだと思います。 分割線の lineY は最初に呼び出される init 関数で所定の位置に配置し直されるようなので、編集画面で多少ズレていたとしても問題はありません。 ただし、init 関数内の  > line._y = left+i*base._height/cntY; (実際は left ではなく top だと思いますが)この計算式で base._height / cntY が割り切れず端数になっていると、細かい誤差が生じます。 1ピクセルのズレは、こうしたところから生じているのではないでしょうか。 これは計算で位置を決めている以上はどうにもなりません。base をボタンの総数で割り切れるサイズにするしかないと思います。 ボタンの高さはメニューが開いた時に調整されるので、割り切れるかどうかと動作・表示位置などには特に関係はないと思いますけれど、元のサイズとリサイズされた後のサイズが違っていると、画像が意図しない大きさに拡大/縮小されて微妙に汚くなる場合があります。 もしかしたら、for ループのカウントの取り方など、細かいところにまだ誤りがあるのかもしれません。 1度、変更する前の、サンプルに書かれていたオリジナルのスクリプトを見てみたいのですが、補足していただけませんでしょうか。

niconico_1969
質問者

お礼

DTPさんにいわれて改めてスクリプトをみてみたところ、気になった点がありました。 line = this["line"+i]; という記述がいくつかあるかと思うのですが、 作成しているスクリプトではこれが、 line = this["lineY"+i]; とlineのあとにYがはいっているのです。最初にお見せした時点ですでにこのようになっていたと思うのですがなぜそのように書き換えてしまったのか自分でもよく覚えていないのです。(すみません・・) ためしにYを外してみたのですが、ボタンが開かなくなった だけでした。このYの役割はなんなのでしょうか。やはりこの現象はこれが原因しているのでしょうか。 1度目だけ勝手に開いてしまう件は、たまに大丈夫なとき(正常に閉じていてマウスをのせるとはじめて開く)もあったりして、でも再読み込みするとダメになったりしています。また、3番目とか4番目とか、他のメニューが勝手に開いてしまうときもあったりするようです。

niconico_1969
質問者

補足

よろしくお願いします。 this.init(); this.onEnterFrame = function() { if (base.hitTest(_root._xmouse, _root._ymouse, false)) { this.rollover(); } else { this.rollout(); } this.resize(); this.setalpha(); }; //値の初期化 function init() { cntX = 7; left = base._x-base._width/2; right = base._x+base._width/2; for (i=0; i<=cntX; i++) { line = this["line"+i]; line._x = left+i*base._width/cntX; } //ロールオーバー時に開いているitemの幅 openW = 180; //ロールオーバー時に閉じているitemの幅 closeW = (base._width-openW)/(cntX-1); //ロールアウト時のitemの幅 homeW = base._width/cntX; } //分割線の位置をホームポジションに戻す function rollout() { for (i=1; i<=cntX; i++) { line = this["line"+i]; line._x += (left+i*homeW-line._x)/3; } } //カーソルの位置に応じて分割線を移動する function rollover() { for (i=1; i<=cntX; i++) { line = this["line"+i]; if (line._x<_root._xmouse) { line._x += (left+closeW*i-line._x)/3; } else { line._x += (right-closeW*(cntX-i)-line._x)/3; } } } //分割線の間隔にitemの幅を合わせる function resize() { for (i=0; i<=cntX; i++) { mc = this["item"+(i+1)]; lineL = this["line"+i]; lineR = this["line"+(i+1)]; mc._x = lineL._x; mc._width = lineR._x-lineL._x; } } //コンテンツの中身を表示する function setalpha() { for (i=0; i<=cntX; i++) { mc = this["item"+i]; //透明度を決める homeAlpha = (openW-mc._width)/(openW-homeW)*100; openAlpha = 100-homeAlpha; if (homeAlpha>10) { //mc.homeを表示する mc.home._visible = true; mc.home._alpha = Math.ceil(homeAlpha); } else { //mc.homeを消す mc.home._visible = false; } if (openAlpha>10) { //mc.openを表示する mc.open._visible = true; mc.open._alpha = Math.ceil(openAlpha); } else { //mc.openを消す mc.open._visible = false; } } }

  • DPE
  • ベストアンサー率85% (666/776)
回答No.8

そのような怪現象の原因は、さすがに現物を見ないことには何とも言えませんが、、、 最初から開くとは、通常通りアニメーション付きで開くということでしょうか。 それとも、アニメがなくいきなり open が見えている状態でしょうか? おそらく、おかしいのは最初の1回だけで、1度でもいずれかのボタンにカーソルを合わせたりロールアウトした後は正常に戻ると思うのですが。 最初から open が見えており、なおかつ、何も操作していない最初の1度だけがおかしいのであれば、item1 の open に何か問題がありそうです。 この作品のコンセプトは、  ・ base とマウスカーソルとの衝突判定を取り、メニュー内にカーソルが重なっているかどうかを検知する。  ・カーソルが重なっている場合、その位置から分割線の配置を決定。  ・分割線の位置から、各メニューボタンの位置と高さを決める。  ・メニューボタンの高さをもとに home のアルファを決め、更に open のアルファを算出。 となっています。 メニューボタンのアルファ値でさえもムービークリップの位置や高さから求めるため、どれか1つでも位置の計算や高さ・中心点のズレなどの些細な誤差があるとアルファの計算にまで響きかねない、非常に繊細な設計になっています。 スクリプトに問題がなくても、シンボルの作り方(高さおよび中心点)や並べ方の誤りが原因で不具合が起こる可能性はあります。 さしあたって、open と同じ大きさの四角形を描画してムービークリップシンボルにし、item1 の open と入れ替えてみてください。 (テスト用のムービークリップを作る時は、中心点や大きさにはご注意ください。open の代わりに使うので、open と全く同じように作ります) インスタンスを選択した状態で「プロパティ」パネルを見ると、中央あたりに「入れ替え...」というボタンがあるかと思います。クリックするとシンボルのリストが出てきますので、目的のシンボルを選択して入れ替えてください。 これで正常に動くようならば、item1 の open の作り方に問題があることになります。 スクリプト等をいじっていないとすると、後から変更した部分が怪しいです。 特に、後で作り直した open のシンボルの大きさや配置が狂っていないか、確認してみてはいかがでしょう。

niconico_1969
質問者

補足

早速のお返事ありがとうございます。 教えていただいたように、同じ大きさ、同じ中心点の四角形を描画して入替えをしてみましたが、やっぱり勝手に、アニメしながら1番うえのメニューが開いてしまいます。 その他のopenも、確かに画像の内容を変更するという作業を施してはいるのですが、そのときもムービークリップシンボルに変換するときに、入替えますか?ときかれて 入れ替える方を選んでいるので、位置のズレはなかったと思うのです。 ただ、その作業より前からこの現象がおきていたかもしれません。保存していた過去のファイルを開いてみたら、動作はきちんとしているのだけれど、上から3番目のメニューが最初から(アニメしつつ)開いてしまう症状のものがでてきました。3番目が開いてしまうのと、1番上が開いてしまうのとでは、原因は異なるのでしょうか。 それと、先ほど書き忘れましたが、この症状は見た目には2箇所の異常があります。もう1箇所は1番下のメニューなのですが、マウスが下にちょっとズレると、すべてのメニューが上に寄って(下にもう1つ6個目のメニューがあるかのような動きをして)しまいます。そのため下に敷いてある黒色のbaseがみえ、うっとおしいだけでなく大変目立ちます。なので、全体が1ピクセル程度上に上がってしまっていたりするのかなと思い、base以外の全てを選択し、1ピクセル下に下げてみたのですが、いずれの症状も変わりありませんでした。 それとも、item(open+home)同士の間に配置されているlineの位置がずれているのでしょうか。 今、lineのy軸の位置は、実は46.5とか、整数でないところもあり、また間隔も正確ではないんです。配置の際、見た目に二重線にみえないようにあわせただけでした。これはどのように決めるべきだったのでしょうか。先ほど頂いた作品のコンセプトから考えると、これをきちんと配置していないことで、スクリプトが正しく動作しない可能性があるように思いましたが、いかがでしょうか。

  • DPE
  • ベストアンサー率85% (666/776)
回答No.7

Flash ではビットマップ画像をピクセル単位で書き換えることができません。 open が1枚のビットマップ画像でできていて、その中に各項目へのリンクボタンのテキストやイラストが描き込まれている状態ですと、そのままでは無理だと思います。 色を変えた画像を多数用意しておいて切り替えるとか、そういった無理をすれば何とかならないこともないですけれど、ビットマップ系画像を多数使うとムービーが重くなってしまい、メニューとしてはちょっと現実的ではありません。 メニュー用の各ボタンを、背景から独立したパーツとして用意できるなら、各ボタンをそれぞれボタンシンボルとして作り、「オーバー」のフレームを利用すると簡単です。 とりあえずメニューの各ボタンがテキストとして説明しますが、これがイラストの場合でも基本的な考え方は同じです。 テキストを入力し、ボタンシンボルに変換してください。 ロールオーバーで色を変えるには、ボタンシンボルの編集画面を開き、「オーバー」のフレームにキーフレームを作って、文字の色を変えておきます。 これで、ロールオーバーの時に色が変わるボタンシンボルになります。 ついでに「ダウン」のフレームでも同様の作業をしておくと、クリックした時にも色が変わって分かりやすくなります。 それから「ヒット」にキーフレームを作り、テキストが収まるくらいの四角形を描画してください。線のない、塗りだけの四角形で構いません。 「ヒット」フレームはマウスが反応する部分を定義するもので、ムービーには表示されません。「ヒット」が未定義の場合は、「アップ」と同じ絵がヒット領域として採用されます。 ボタンが丸や四角のような形であればあまり問題はないのですが、テキストの場合は、「ヒット」が未定義だとテキストの線がない部分にはマウスが反応しなくなり、クリックしにくいボタンになってしまいます。 テキストが収まるくらいの四角いヒット領域を定義しておくと、線のない部分にもマウスが反応し、普通のボタンのようにクリックできるようになります。 メニューの数だけボタンシンボルを用意したら、これを、#6と同じ要領で配置します。 要するに、透明なリンクボタンが「オーバー」のフレーム付きのボタンシンボルに変わるだけです。 スクリプトも同様に、配置したメニュー用の各ボタンのインスタンスと、背景画像に重ねた透明ボタンに on アクションを設定してください。 -------------------------------------------------------- メニュー用のボタンがテキストで、単に色が変わればいいだけでしたら、項目名として表示するテキストとリンク先の URL をパラメータとして持つコンポーネントにし、テキストやリンク先のページだけを変更可能にするという方法もあります。 メニューの項目がいくつあってもシンボルは1つだけで済むので、仕様やデザインが変更になった時も楽に対応できますし、スクリプトをいじることなくムービーの編集画面で文字やリンク先を変更できて管理や編集も簡単です。 ただし、項目名をダイナミックテキストで表示するため、あまり凝ったフォントが使えないことと、ボタンごとに細かく違うデザインにはできないといった難点があります。 コンポーネントとは、編集可能なパラメータを持っているムービークリップのことです。 メニュー用のボタンは、ロールオーバーでテキストの色を変更・ロールアウトで元の色に戻す・クリックでリンク先のページを開くという動作は全て共通です。 共通する動作はムービークリップの動作として作り、違う部分だけを編集できるパラメータにして、後から簡単に変更できるようにします。 まずはムービークリップを作ります。 「挿入」→「新規シンボル」でムービークリップを作り、空白のテキストフィールドを描画します。 「プロパティ」パネルで、「ダイナミックテキスト」「単一行」「選択不可」(” Ab ”のボタンを OFF )「 HTML なし」(” <> ”ボタンを OFF )に設定してください。 大きさは適当で構いませんが、ムービークリップの中心点が左端になるよう、シンボルの+マークがテキストフィールドの左上に来る位置に配置してください。 それから、このテキストフィールドにインスタンス名を付けます。ここでは仮に、” btn_name ”とします。 次に、コンポーネントのパラメータを定義します。 コンポーネントの作り方やコンポーネント定義パネルの使い方は以前別の質問で回答しましたので、こちらをご参考になさってください。 #3の中ほどで説明しております。  ・縦のメニューバー作成方法で困っています。Part2   http://okweb.jp/kotaeru.php3?q=1612380 今回のパラメータは、項目名として表示する名前とリンク先の URL の2つです。 「コンポーネント定義」パネル(シンボルを選択して右クリック→「コンポーネント定義...」)を開き、+ボタンを2回クリックしてパラメータを追加してください。 変数はとりあえず、項目名を item_name 、リンク先を page_url とします。タイプはどちらも String (文字列)です。 これで、ムービークリップがコンポーネントシンボルになります。 このシンボルのタイムラインに、ボタンとしての動作を定義します。 シンボル内に定義しておくと、このシンボルから作られたインスタンスは全て同じ振る舞いをするようになります。 シンボルのタイムラインのフレーム1に、次のようなスクリプトを設定してください。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)  //テキストの長さに合わせて幅を伸縮させる  btn_name.autoSize = "left";  //項目名を表示  //テキストはコンポーネントパラメータ:item_name  btn_name.text = item_name;  //デフォルトのテキストの色を保存  org_color = btn_name.textColor;  /*ロールオーバー時、テキストの色を赤にする*/  this.onRollOver = function()  {   btn_name.textColor = 0xff0000;  };  /*ロールアウト時、テキストの色を元に戻す*/  this.onRollOut = function()  {   btn_name.textColor = org_color;  };  /*クリックされた時、指定のページを表示*/  this.onRelease = function()  {   //リンク先はコンポーネントパラメータ:page_url   getURL( page_url , "blank" );  }; 「ダイナミックテキスト」または「テキスト入力」にしたテキストフィールドは、TextField というクラスで細かく制御できます。 TextField には、テキストフィールド内に表示する内容を管理している text というプロパティがあります。書き換えることで、直接内容を更新できます。上記のスクリプトでは、text プロパティにコンポーネントパラメータの item_name の内容を代入して、項目名を表示しています。 テキストの文字色は、同じく TextField クラスの textColor というプロパティに入っています。 ロールオーバー/アウトの時には、このプロパティを操作して文字色を変更します。 textColor には、最初は、テキストフィールドを配置した時に設定した文字色が入っています。この色を変数 org_color に保存しておき、ロールアウト時に元の色に戻せるようにしています。 ムービークリップ内にテキストフィールドを1つだけ配置し、ムービークリップにボタンイベント( rollOver や release など)を利用するスクリプトを書くと、テキストフィールド全体がヒット領域になります。四角い透明なボタンを重ねる必要はありません。 ただ、何も指示しないとテキストフィールドが伸縮せず最初に配置したサイズの通りのボタンになるため、文字列の長さと大きさが合わないとテキストが途中で切れたり、空白の部分なのにマウスが反応するなどのおかしな現象が起きてしまいます。 テキストの長さに合わせてテキストフィールドを伸縮させるには、autoSize というプロパティを使います。 left は左端を固定し、右方向に伸縮させる設定です。メニューを左揃えにしたい時に便利です。 その他のスタイルについては、よろしければこちらをご参考になさってください。  ・ダイナミックテキストの幅を広げるには?   http://okweb.jp/kotaeru.php3?q=1510682 以上でコンポーネントは完成です。 open のシンボルに、各項目へのリンクボタンの代わりにコンポーネントシンボルのインスタンスを配置してください。 これらのインスタンスは既にボタンとしての機能を備えていますから、on アクションを設定する必要はありません。画像に重ねている透明ボタンにだけ、別途 on アクションを設定します。 コンポーネントの持っているパラメータは、「プロパティ」パネルに表示されている「パラメータ」のタブ(パネルの右上にあるタブを切り替えると表示されます)で編集できます。 項目名とリンク先を入力して、動作を確認してみてください。 ちなみに、文字色をパラメータに追加し、そのパラメータを元に文字色を変更するようにスクリプトを変更すると、ボタンごとに色を変えられる、より柔軟なコンポーネントになります。 textColor プロパティに設定するのは色の RGB 成分値ですから、パラメータのタイプは Color ( RGB 成分の 16 進数表記)がオススメです。 タイプを Color にしたパラメータでは、色のサンプル部分をクリックするとカラーピッカーが表示され、ピッカーから拾った色や作成した色の RGB 成分が 16 進数形式に直されて設定されます。 コンポーネントにする場合でも、画像の一部分をクリックできるようにするための透明なボタンの代わりに、別のリンクボタンを大きなボタン(メニュー以外の部分に対するボタン)の上に重ねておくという考え方は全く同じです。 コンポーネントも万能ではありません。何か問題があるようでしたら、容量やメンテナンス面では多少難がありますけれど、各項目用のボタンを片っ端からボタンシンボルとして作るのもアリかなとは思います。

niconico_1969
質問者

お礼

早速ありがとうございました。 画像上にあったメニューの文字を、FLASH上でテキストにして、それをボタンシンボルにする方法でつくってみたところ、すごく簡単にロールオーバーするようになりました。 今回のが今までで一番スムーズに作業ができました。 コンポーネントについては、噛み砕いて説明してくださっているのに、私には何度読んでもなるほどというところまで理解ができませんでした。どうにも太刀打ちできないレベルなんでしょうか。。もっと勉強します。 それで、いつのまにかこうなってしまっていたのですが、 フラッシュ開始と同時に一番上のメニューが開いてしまうのです。なので、ページを移動するたび一番上のメニューが開いてしまい、とてもうっとおしいです。当初はマウスを載せてから開いていたはずだったのですが。 これは、シンボルが1ピクセル上に移動してしまっているとかの問題でしょうか。不要なアクションが入っていないか調べてみたのですが、見当たらないようなのですが… たびたびすみませんがよろしくお願いいたします。

  • DPE
  • ベストアンサー率85% (666/776)
回答No.6

とりあえず無事に動くようになって何よりです。 以前、No.1197851 で回答したことがありましたね。覚えております。 あの時はバナーの話でしたから、ムービー内のどこをクリックしても反応するように、透明なボタンを1つ重ねる方法をご紹介しました。 今回も、透明なボタンを使ってはいかがでしょうか。 サンプルでは番号が書いてあるインスタンス home は、ボタンが開いている間は徐々に薄れて、やがて非表示( _visible プロパティが false )になって消えてしまいます。 home に on アクションを使ってリンクを設定したとしても、_visible プロパティが false になっているインスタンスでは release 等のボタンイベントが発生しなくなり、ボタンとしては機能しなくなります。 ビジュアル的な面から見ても、home は見えなくなるのですから、これをボタンとして使うのは無理ではないでしょうか。 例えば、リンク先が  表紙   ・ページ1   ・ページ2    : と、このようになっていて、open に配置した画像の一部にページ1と2へのリンク、そのリンク以外の部分を表紙へのリンクにしたいということであれば、home を使わず open だけで何とかできます。 親子階層になっているムービークリップや、今回の home と open のように上にムービークリップがぴったり重なっている状況で、親や上のムービークリップがボタンとしての機能を使うと、子および下に配置されているムービークリップでは、on アクションを設定しても各イベントが検出されなくなります。 しかしこれは、ムービークリップが親子階層になっていたり、覆うようにかぶさっているムービークリップがある時の話です。 例えば、大きな四角いムービークリップと小さい丸のムービークリップを用意し、この2つを重ねて両方に on アクションを設定すると、それぞれでボタンイベントは検出されます。 open も、この特徴を利用してリンクボタンを作ってはいかがでしょう。 仮に先述のような構成のコーナーがあり、open 内の画像の一部に各ページへのリンク、これ以外の部分をクリックした時には表紙を表示するものとします。 open の元になっているシンボルを開き、次のようにレイヤーを追加してください。  レイヤー1:各ページへのリンクボタンを配置  レイヤー2:表紙へのリンクボタンを配置  レイヤー3:画像を配置 レイヤーは上のものほど上に重なって表示されます。 このようにレイヤーを重ねておくことで、画像の上に表紙へのリンクボタン、そのボタンの上に更に各ページへのボタンが重なります。 表紙へのリンクボタンは、ただの四角形で構いません。 なお、open (の元になっているシンボル)のサイズは全て同じはずですから、各コーナーの表紙(第2階層)へのリンクボタンシンボルは、他の open のシンボルでも再利用できます。 各ページ(第3階層)へのリンクボタンは、リンクさせたい部分の形に合わせて作ってください。 各ボタンができたら、それぞれアルファを0%にして透明にし、on アクションでリンクを設定してできあがりです。 こんなところで、いかがでしょうか。

niconico_1969
質問者

お礼

DPE、大分時間があいてしまってすみません。 ご指示のとおり制作したらリンクが貼れました。 一度でうまくいって感動しました。どうもありがとうございました。 それで、やはりクライアント側からアクションの変更がでて、各ボタン内の文字がロールオーバーして色が変わるようにするように言われました。確かに今のままではボタンのどこにマウスを載せてもクリックできる印になっていて、実際に飛んでみないと任意のページにいけたかどうかわかりずらいようです。文字に色がついたバージョンのopen画像を作るのまではわかるのですが、それをどのレイヤーに配置して、どこにアクションが必要なのか、おわかりになりますでしょうか。情報に不足があれば補足させていただきます。長丁場で申し訳ないのですが…ご説明がとてもわかりやすいので、できればまたよろしくお願いいたします。

niconico_1969
質問者

補足

あれ…?週末に補足を書いたつもりなのですが、今みたら未記入のままです。ちゃんと送れていなかったのかな。 お返事遅れてすみません。 すぐに印刷して熟度し、よく理解できました。 今クライアントからの返事まちで、またアクションが変更になるかもしれなくて先に進めないのですが、 決まり次第着手します。そしたらまたご連絡しますので 引き続き、よろしくお願いします。

  • DPE
  • ベストアンサー率85% (666/776)
回答No.5

item のズレも中心点の問題だと思います。 ある方向に”半分だけ”ズレるのは、スクリプトの問題でなければ、大抵は中心点が違っていることが原因です。 item1 ~ 5 の中心点が、中央になっていませんか? 各ボタンは上下の分割線をもとに座標と幅を決めるため、item は base とは逆に、中心点が上端になければならないと思います。 ActionScript での _x と _y プロパティには、インスタンスの中心点の座標が入ります。 item1 ~ 5 の位置を、これの上端に接する分割線の位置から決めるのであれば、_x と _y 、特にY座標を表す _y プロパティにはインスタンスの上端の座標が入っていた方が計算しやすいです。 _x は今回は触らないので、item の中心点は上端でさえあれば左上・上中央・右上のどれでもいいと思います。 分かりやすいのは左上でしょうか。item1 ~ 5 の中心点を左上にしてみてください。 インスタンスの中心点は元になっているシンボルの中心点と同じ場所になり、インスタンスごとに変更はできません。元のシンボルを編集して、中心点を決めます。 item シンボルの編集画面を開き、入れ子になっている home と open の両方を、+マークが左上にくるように移動してください。 this.onEnterFrame = function()・・・をコメントにすると、分割線やボタンの座標などを決める関数が呼び出されなくなります。 これらの関数が呼び出されなければボタンは移動しませんから、編集画面で配置した通りの位置に表示されます。 しかし、この部分をコメントからスクリプトに戻した時は、フレームレート分の1秒ごとに関数が呼び出され、ボタンの位置を計算する処理が行われます。 この部分に問題があると、ムービーがロードされた次の瞬間には、ボタンは誤った位置に配置されてしまいます。 分割線は init 関数で base の大きさと座標から初期配置を決めているようなので、base や line0 ~ 5 に問題があるのかどうかは init 関数だけを実行してみれば分かります。 これで分割線が所定の位置に配置されるのであれば、base から分割線の位置を決める計算や処理はとりあえず問題なしとなります。 この時点で既に分割線がズレているようなら、線を配置する計算か、あるいは基準になる base に問題がありそうだと推測できます。 base と line0 ~ 5 に問題がないとすると、item 自体か、あるいは item1 ~ 5 を動かす処理が怪しいことになります。 曲がりなりにも分割線の位置と幅に合わせて item1 ~ 5 の位置と幅が変化しているなら、動かす処理にはさしあたって問題はなさそうで、となると残る可能性は中心点のズレではないか・・・と絞っていくわけです。 不具合や不可解なことが起きたら、少しずつスクリプトを動かしていって、どの部分は正常に動くのか、何をしたらどうなるのかを考えながら原因を突き止めていくといいですよ。 -------------------------------------------------------- closeH の 計算に出てくる - 1 は、これは変更してはいけません。 メニュー全体の高さは常に固定で、base の高さと一致しています。 従って、あるボタンが1つ開いた時、閉じている残りのボタンの高さの合計は、base の高さ( _height プロパティ)から開いたボタンの高さを差し引いた値になります。 ボタンが開いた状態の高さは変数 openH に入っていますので、残りのボタンの高さの合計は  base._height - openH で求められます。 変数 closeH には、もう1歩進んで、閉じているボタン1つあたりの高さを入れておきたいのです。 閉じているボタンはどれも同じサイズですから、高さの合計を閉じているボタンの数で割れば1つあたりの高さが出てきます。 ボタンは全部で5つあり、そのうちの1つが開いているのでこれを除きますと、閉じているボタンはボタンの総数( = cntY ) - 1 で4つです。 よって、base の高さから openH を引いた値をボタンの総数 cntY - 1で割ったものが、閉じたボタン1つあたりの高さとなります。 rollout 関数と rollover 関数で、_y の値を決める時に用いられている / 2 や / 3 は詳しくは分かりませんが、おそらくはアニメのコマ数を決める数だと思います。 つまり、/ 2 なら2コマ、/ 3 なら3コマで移動が完了するといった意味ではないでしょうか。 例えば、これを / 1 にするかこの部分を削除すると、なめらかなアニメではなく分割線がいきなり所定の位置に戻ったり開いたりするようになり、逆に値を増やすと、アニメにかかる時間が長くなる代わりにゆっくりなめらかに動くようになると思います。 メニューをストレスなく開閉させるためには、ある程度のスピードやアニメのキレの良さも必要です。 まあ、ダラダラと長いアニメにするとボロも出やすくなりますしね。 そのあたりの兼ね合いから、閉じる時は3コマ、開く時は2コマでアニメが完了するようにしているのだと思います。 init 関数で変数 top と bottom の値を決める時にも、/ 2 という数値が出てきます。 図を描いてみると分かりますが、base の中心点が中央にある場合、base の上端の座標は base の _y から高さの半分を引いた位置、下端は逆に、_y に高さの半分を足した位置であるといえます。 (↑この部分から、base の中心点が中央にあるものとして作られていることが推測できます) この / 2 は base の高さの半分を、との意味ですから、これは変更してはいけません。 余談ですが、あるムービークリップがどの座標空間を占めているかは MovieClip クラスが持っている getBounds というメソッドでも取得できます。 -------------------------------------------------------- ところで、#4で書きました、パブリッシュのバージョンについてですが。 this.onEnterFrame = function・・・という書き方は Flash Player 5 以前のバージョンにはないため、この部分が正常に動作しません。 つまり、分割線やボタンを開閉させるスクリプトは、this.onEnterFrame = function の部分以外は Flash Player 5 でも動くのですが、onEnterFrame = function ・・・の書き方を利用して各関数を呼び出している限りは Flash Player 5 では動きません。 Flash Player 6 では問題なく動きます。6以降のバージョンでパブリッシュしてください。 何だか脳回路がショートしていたみたいで(^^;)訳の分からない説明をしてしまい、失礼いたしました。

niconico_1969
質問者

補足

ご指摘のとおりでした。ついに美しく動くようになりました。ありがとうございました。DPEさんがいらっしゃらなかったらデザイン変更を余儀なくされているところでした。 インスタンス名open、homeの+が、編集画面上では左上になっていることを確認してあったのですが、今回初めてopen,homeであるシンボルのno1~5とimg1~5というMCをライブラリでダブルクリックして+を移動しました。 ご説明のとおり、私はインスタンスごとに中心点を動かして、動かしたつもりになっていたということなのでしょうか。昨日はご説明を印刷して家でじっくり理解したのですが、それで初めて見えてくることがたくさんありました。スクリプトの意味を理解することは、間違い部分に気づくためにとても大事だとすごく思いました。 ところで、引き続き教えていただきたいことがございます。もしお疲れでなければDPEさんにご教授頂きたいのですが…。 作成したのは左ナビなので、homeが第2階層のコンテンツ、openが第3階層のコンテンツになるのですが、それぞれリンクを貼らなければなりません。 以前にDPEさんにリンクの貼り方を教えていただきましたが(途中で気づきました…!)これは、itemのMCのなかのhomeのインスタンスに直接アクションを指定するのでよいのですよね。ただ、openの第3階層のほうでは、一つの画像内に、2箇所、3箇所のリンク先を指定しなければならないので、これは(第3階層が1ページだけのところと、2ページ、3ページあるところとあります)、htmlのホットマップのように、任意の位置に透明ボタンを配置してボタンにアクションを指定すればよいのですか?

  • DPE
  • ベストアンサー率85% (666/776)
回答No.4

まず、ボタンのサイズが変わらない点ですが。 よく考えてみますと、resize 関数内の  > mc._height = lineT._y-lineB._y; これ、逆ですね。 lineB._y - lineT._y だと思います。 lineT は上の線、lineB は下の線と思われます。 Y座標はステージの下方向にいくにつれて大きくなります。 上の線から下の線の座標を減算したのでは、ムービークリップの高さである _height プロパティに負の数が入ってしまい、変形が無効になります。 ボタンのアルファも、実は _height プロパティと関係があります。 setalpha 関数で  > homeAlpha = (openH-mc._height)/(openH-homeH)*100; この部分に、item1 ~ 5 の _height プロパティを使ってアルファを求める計算が含まれています。 ボタンの下の画像が見えないのも、_height の計算が正しくなかったためではないでしょうか。 なお、item1 ~ 5 の入れ子のムービークリップは、それぞれ home と open というインスタンス名でなければならないようです。 この間違いもないか、合わせてご確認ください。 残るは位置のズレですけれど、これは根が深そうですね。 正直言いますと、原因の目星がつかないのですが ^^; base から外れているものにカーソルを合わせても反応しないのは、これは当然です。 base とマウスカーソルとの衝突判定を取り、メニュー全体のどこかにカーソルが重なっていれば rollover 関数が、重なっていなければ rollout 関数が呼び出されます。 base から外れているボタンにカーソルを合わせた場合は、base からカーソルが外れているので rollout 関数が呼び出され、ボタンが初期状態に戻されてしまい、反応していないように見えます。 とりえず、this.onEnterFrame = function()・・・の部分をコメントにして、init 関数だけを呼び出すようにしてみてください。 この時点で、ボタンはさておき、分割線は base の上に正しく配置されますでしょうか? スクリプトを見た限りでは、base の中心点は中央にあるものとして計算されていると思われます。 base のシンボルの編集画面を開き、+マークの位置を確認してみてください。 これが中央以外にあると、base の座標をもとに算出しているもの(特に top および bottom 変数を使った計算)全てに狂いが生じます。 中心点がズレているようなら、+マークが中央にくるように base の絵を移動してください。 openH は画像のサイズ、つまりボタンが開いた状態のサイズで、間違いないと思います。 ただ、サンプルでは横長の画像が使われており、openH(元は openW でしょうか?)には画像の幅が入っていたはずです。 これを縦並びに改造するなら画像の高さを代入すべきですが、このあたりに問題はありませんでしょうか? 元のスクリプトは変数を多用して柔軟に設計されている(おかげでややこしいですが)ので、変更するのは、ボタンの数である cntY とこの openH だけだと思います。 あとの変数は、これらの数値をもとに算出されていますので。 まあ、base や item の大きさと数によっては計算に端数が生じ、拡大/縮小した時に画像が歪んで見えたりわずかにズレるといった害は出るかもしれませんけれど、全く動かなかったりおかしいほどズレるようなことはないかと思います。 書き出すバージョンは、さしあたって関係なさそうです。 on*** = function という書き方やムービークリップに on アクションが書けるようになったのは Flash Player 6 からで、Flash Player 5 以前では動作しません。 ですが、分割線の位置やボタンの配置を決める部分は、文法上は Flash Player 5 でも動く( Flash Player 4 以前では無理ですが)スクリプトになっています。 強いて言えば精度の問題で多少はズレることはあっても、全体的に上手くいっていないこととは直接関係はないと思いますよ。

niconico_1969
質問者

補足

お忙しい中ありがとうございます。助かっています。 おっしゃるとおり、lineB._y - lineT._yにしたらサイズとアルファの点が解決しました。itemの入れ子のmcのインスタンス名はopenとhomeで間違いありませんでした。 残る位置の問題なのですが、ご推測の通り、baseの×が左上にあったのでbaseを動かして中央点をそこにもっていったら、lineとbaseがきちんと揃い、itemがxは揃って、yが高さ半分上にずれている状態まで改善されました。this.onEnterFrame = function()・・・をコメントにすると、確かに全ての画像がピタリと揃います。openHの94は開いたボタンの高さで間違いありません。ステージに配置されている座標はきちんと揃っているのになぜなのでしょうか。ためしにステージ上でボタンを高さ半分、下にずらしてみても、書き出した状態には変化がありません。 たまにでてくる整数、例えば、line._y += (top+i*homeH-line._y)/2; とか closeH = (base._height-openH)/(cntY-1); の1や2を調整する必要はないのですよね? (私は、なぜここで1をひくのか、2で割るのか、がよくわかっていません…無知ですみません)

関連するQ&A

専門家に質問してみよう