- ベストアンサー
FLASHナビボタンで、アクションスクリプトの記述の誤り
縦に並ぶアニメーションのナビボタンのスクリプトを横に並ぶ形のサンプルソースを元に書き換えしているのですが動作しません。補足でソースをコピーしますので、どこが誤りなのでしょうか。教えてください。 ボタン動き→onmouseでH=200%拡大、イメージがスワップ。その他のボタンはそれにつれてH=伸縮。 ※辞書を引きながらのつたない間違いかと思いますが…宜しくお願い致します。
- みんなの回答 (13)
- 専門家の回答
質問者が選んだベストアンサー
ムービークリップの配置や階層構造などが不明なので、憶測まじりになりますが。 > 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) { にしてみてはいかがでしょう。 ざっと見たところ、気になったのは以上の点です。 実物を見ないと詳しくは言い切れませんけれど、ご参考までに。
その他の回答 (12)
- DPE
- ベストアンサー率85% (666/776)
#2です。 init 関数の中に、 > top = base._y-base._height/2; > bottom = base._y+base._height/2; とあり、これは分割線のムービークリップ lineY0 ~ 5 の座標を計算する時に基準として使う変数だと思います。 ところが、実際の計算では ・ init 関数内 > line._y = left+i*base._height/cntY; ・ rollout 関数内 > line._y += (left+i*homeH-line._y)/3; ・ rollover 関数内 > line._y += (left+closeH*i-line._y)/2; > } else { > line._y += (right-closeH*(cntY-i)-line._Y)/2; ・・・と、top と bottom (上下端)が、いつのまにか left と right (左端・右端)に変わってしまっています。 これが怪しいですね。 多分ですが、left → top 、right → bottom だと思います。 上手くいかないようなら、逆に、left → bottom、right → top にして試してみてください。 ボタンである item1 ~ 5 の位置と高さは、enterFrame イベントで常時呼ばれている resize 関数で、lineY0 ~ 5 の位置から決定されているようです。 つまり、lineY0 ~ 5 の座標が正しく計算されていないと、これに引きずられてボタンもおかしなところに表示されてしまったり、高さが0になるなどで表示されなくなる可能性があります。 それから、resize 関数で > function resize() { > for (i=0; i<=cntY; i++) { > mc = this["item"+(i+1)]; > lineT = this["lineY"+i]; > lineB = this["lineY"+(i+1)]; > mc._y = lineL._y; : mc._y = lineL._y; は変数 lineL ではなく、lineT._y (これでおかしい場合は lineB._y )ではないでしょうか。 スクリプトがらみで怪しいのは大体こんなところで、他に考えられる原因としては、インスタンス名が違っているといった些細な誤りだと思います。
補足
救いのお返事、ありがとうございます。 ご指摘の部分、昨日自分でも気づいたもののモレがあり、ご指示いただいて助かりました。またご推測のとおり、インスタンス名が間違っていたり、モレている部分がありました。これらを修正したところ、すべての画像は表示され、マウスを載せるとボタンとラインが動きを見せるようになりました。(ご説明の仕方のおかげでスクリプトのしくみも少しづつわかってきました。) これだけでも感動なのですが、、まだヘンです。 □下に敷いてあるbase、ボタン、ライン、すべてが 縦方向にズレて見えている。→下2つのボタンと下3本のラインはbaseの上にのっているが、それより上は、baseから上にはみ出ている。 □baseに乗っていない部分のボタンとラインはonmouseに反応しない。 またonmouseしたときの動きもヘンで、 □ラインとラインの間にマウスをおくとライン同士の距離は2倍に広がるが、ボタンはそのままの状態で上下に移動している。 □マウスをおくとボタンが広がって徐々に現れるはずの、ボタンの下に重ねてある画像が見えない。 サンプルは7つのボタンなので、5つのボタンにすることで数値を変えなければならない箇所があるのでしょうか。 ロールオーバー時に開いているitemの高さ、閉じているitemの高さ、という箇所が気になっています。開いているとき=94は画像サイズです。違っていますか。 書き出しの際のflashのバージョンなども関係あるのでしょうか。現在は7.0で書き出しています。(5.0以下は更に正しく表示されません)
つまり, 「質問欄には書ききれなかったスクリプトを補足するので,とりあえず何か言ってください。」 ということですか? それでは,一応質問がさっぱりわからないので「補足要求」します。 (補足の字数制限もありますから,注意してください。) 私がわかるかどうかわかりません。どなたかもしおわかりであれば,回答おねがいします。↓
お礼
this.init(); this.onEnterFrame = function() { if (base.hitTest(_root._ymouse, _root._ymouse, false)) { this.rollover(); } else { this.rollout(); } this.resize(); this.setalpha(); }; //値の初期化 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; } //ロールオーバー時に開いているitemの高さ openH = 94; //ロールオーバー時に閉じているitemの高さ closeH = (base._height-openH)/(cntY-1); //ロールアウト時のitemの幅 homeH = base._height/cntY; } //分割線の位置をホームポジションに戻す function rollout() { for (i=1; i<=cntY; i++) { line = this["lineY"+i]; line._y += (left+i*homeH-line._y)/3; } } //カーソルの位置に応じて分割線を移動する function rollover() { for (i=1; i<=cntY; i++) { line = this["lineY"+i]; if (line._y<_root._xmouse) { line._y += (left+closeH*i-line._y)/2; } else { line._y += (right-closeH*(cntY-i)-line._Y)/2; } } } //分割線の間隔にitemの高さを合わせる function resize() { for (i=0; i<=cntY; i++) { mc = this["item"+(i+1)]; lineT = this["lineY"+i]; lineB = this["lineY"+(i+1)]; mc._y = lineL._y; mc._height = lineT._y-lineB._y; } } //コンテンツの中身を表示する function setalpha() { for (i=0; i<=cntY; i++) { mc = this["item"+i]; //透明度を決める homeAlpha = (openH-mc._height)/(openH-homeH)*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; } } }
補足
大変ありがたいです。 回答がつかないと補足ができないのを知らなかったので 削除の依頼などかけてやきもきしていました。 昨日も辞書やネットで、横用の記述を縦用にするのに必要な変更点を調べていたのですが、私の頭では限界のようで やはり動作しませんでした。(逆にswfが動かなくなってしまいました。)
- 1
- 2
補足
有難うございます。大変わかりやすいご説明で助かります。 タテの動きのほかのサンプルをみて、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行目:ロールオーバーしたマス目が開くコンテンツメニュー これが、参考にしている横並びのスクリプトです。