• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:FLASHのスライド式のメニューの作り方について)

FLASHのスライド式のメニューの作り方について

このQ&Aのポイント
  • FLASHでスライド式のメニューを作りたいと思っていますが、いくつか分からない点があります。
  • 具体的には、選択番号の初期化や各メニューの値の設定、親と子の関係などについてです。
  • どうしても理解できていない部分が多く、質問の仕方もうまくできていないかもしれませんが、ご教示いただければと思います。

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

  • ベストアンサー
  • BlurFiltan
  • ベストアンサー率91% (1611/1754)
回答No.1

とりあえず階層構造は次のようになっています。 少なくともこの構造が理解できてイメージできないとわからないと思います。  _root   ├ p_mc0(ムービークリップ)   │  └_btn(ボタン)   ├ p_mc1(ムービークリップ)   │  └_btn(ボタン)   ├ p_mc2(ムービークリップ)   │  └_btn(ボタン)   ├ p_mc3(ムービークリップ)   │  └_btn(ボタン)   └ p_mc4(ムービークリップ)      └_btn(ボタン) > 1.// 選択番号 p の初期化  >  p = 0; >  の意味。 p は変数名です。 p ではなくて hoge とか piyo とかでもかまいません。 一応 photo の頭文字 p を使ってみただけです。 この _root の変数 p の値は 0~4 で変動します。 その p の値によって,動くエンジン部分の動向を変えています。 その動くエンジン部分がこの部分です↓。  ~ i=1~4 でループする for文内 ~  // 各 p_mc1~p_mc(n-1) の動き  _root["p_mc"+i].onEnterFrame = function() {    // _root の p の値によって目標座標を変える    if (_root.p<this.p) {      this._x += (m+w-r*(n-this.p)-this._x)*s;    } else {      this._x += (m+r*this.p-this._x)*s;    }  }; つまり, ムービークリップp_mc1~p_mc4は, _root の p の値が 0~4 のうちどれであったとしても, ずっと目標座標に向けて近付き続けます。 _root の p の値によって目標座標が変わるので, 近付き続ける座標が変わるというしくみです。 // 選択番号 p の初期化  p = 0; をしておかないと,p は undefined です。 p が undefined であると上のエンジンが正常に動作しません。 また p の値を 0 ではなく他の数にしておくと, ムービークリップp_mc0 が見えている状態に整列しません。 したがって, p = 0; が必要になります。 ※ただし絶対にこれが必要なのは   FlashPlayer7(FlashMX2004)以上のSWFの場合です。   FlashPlayer6以下のSWFでは   初期化をしていない変数の値は,   自動的に ""(空白文字),もしくは 0 と判断されますから,   上の場合 p = 0 と書かなくても自動的にそうなります。 > 2.// 各 p_mc? にローカルな変数 p の値を設定 >   _root["p_mc"+i].p = i; >   の記述の意味。 これは書かれていらっしゃる通り, ムービークリップ p_mc0~p_mc4 内の変数 p を i と同じ値にしています。  _root   ├ p_mc0 ← 変数p=0   │  └_btn   ├ p_mc1 ← 変数p=1   │  └_btn   ├ p_mc2 ← 変数p=2   │  └_btn   ├ p_mc3 ← 変数p=3   │  └_btn   └ p_mc4 ← 変数p=4      └_btn ということです。 > 3.// 親の p の値を _root の p に代入 >  _root.p = this._parent.p; >  の記述の意味。 各ボタン_btn のロールオーバー時の動作ですよね。 各ボタン_btn の親 は p_mc0~p_mc4 のうちいずれかです。 仮に p_mc2 内の _btn にロールオーバーしたときは, その親の p の値 2 を _root の p に代入するということになります。  _root 変数p=2 ←───┐   ├ p_mc0 ← 変数p=0  │   │  └_btn        │   ├ p_mc1 ← 変数p=1  │   │  └_btn        │   ├ p_mc2 ← 変数p=2 ─┘   │  └_btn ←★ロールオーバー   ├ p_mc3 ← 変数p=3   │  └_btn   └ p_mc4 ← 変数p=4      └_btn これで _root の変数p の値が 2 になるので, 上に書いたエンジン部分の各p_mc0~p_mc4の動く目標座標が変わります。 ※---注意-------------------------- ボタン自体に on (rollOver) { _root.p = this._parent.p; } と書いた場合, この this はそのボタンのあるムービークリップになります。 (例) _root ←this._parent     └p_mc0 ←this        └_btn 一方, ボタン.onRollOver = function() { _root.p = this._parent.p; }; と書いた場合, この this はそのボタン自体になります。 (例) _root ←this._parent._parent     └p_mc0 ←this._parent        └_btn ←this 書き方によって this は変わります。 this が何なのかわからなくなった場合は, trace(this); を書いて「制御」→「ムービープレビュー」 で確かめてみると良いと思います。 ----------------------------------- > 一つのソースの中に絶対パスと相対パスを混ぜて書いてよいのか 「悪い」とは何処にも書いていないと思います。 また理論も合っているので良いのではないでしょうかね。 何も考えずにごちゃ混ぜにするとややこしいので確かに混ぜない方が良いです。 「for文を使って各ボタン_btn の動作定義をしている」 というところがポイントです。 for文を使う以上,右辺は this._parent.p のように相対パスでないと書けないでしょう。 どうやって絶対パスで表します??? 実際は四苦八苦すると _root.p_mc○.p のような意味になるように書けますが, それは無駄な努力です。 したがって, 普通に考えると右辺は this._parent.p のような相対パスに決定してしまいます。 変えるとしたら左辺でしょうね。 気になるようでしたら, _root.p = this._parent.p; ではなく, this._parent._parent.p = this._parent.p; に統一しても良いと思います。 しかし, this._parent._parent って何? と,わかりにくくなりませんか? 混乱を防ぐために _root.p にしています。 何も考えずに混ぜているのではなくて, 上のように考えた上で,絶対パスと相対パスを混ぜているので, かまわないと思います。 > 4.for (i=1; i<n; i++) { >  // 各 p_mc1~p_mc(n-1) の動き >  _root["p_mc"+i].onEnterFrame = function() { >  // _root の p の値によって目標座標を変える >  if (_root.p<this.p) { >  this._x += (m+w-r*(n-this.p)-this._x)*s; >  } else { >  this._x += (m+r*this.p-this._x)*s; これが上にも書いた主要エンジン部分です。 実際に数値を代入して考えてみるとわかると思います。 for文の i が仮に 1 であったとします。 そのときは次のようになります。  // 各 p_mc1の動き  _root.p_mc1.onEnterFrame = function() {    // _root の p の値によって目標座標を変える    if (_root.p<this.p) {      this._x += (m+w-r*(n-this.p)-this._x)*s;    } else {      this._x += (m+r*this.p-this._x)*s;    }  }; p_mc1 の p は 1 です。 また各変数は次のように設定してあります。 // 表示枠の 横幅 を設定(変更可) w = 600; // 表示枠の 左側余白 を設定(変更可) m = 10; // 表示枚数(p_mc? の個数)の設定(変更可) n = 5; // 狭いときに見えている範囲を設定(変更可) r = 80; // 動く速さの設定(変更可) s = 1/5; したがって次のようになります。  // 各 p_mc1の動き  _root.p_mc1.onEnterFrame = function() {    // _root の p の値によって目標座標を変える    if (_root.p<1) {      this._x += (10+600-80*(5-1)-this._x)*1/5;    } else {      this._x += (10+80*1-this._x)*1/5;    }  }; 実際はこの↑ように数値を直接記入してもかまいません。 作成の最初の段階ではまずこのような感じで作成したと思います。 しかしこのままだと, 何処の数字をどう変えれば思い通りに動かせるのか使う方がわかりにくいです。 また,触りすぎて壊してしまう可能性もあります。 何処を変えれば何が変わるのかをわかりやすくするために, w m n r s という変数を別に上に用意して,その変数の意味を書いています。 上の式をさらに計算します。  // 各 p_mc1の動き  _root.p_mc1.onEnterFrame = function() {    // _root の p の値によって目標座標を変える    if (_root.p<1) {      this._x += (290-this._x)/5;    } else {      this._x += (90-this._x)/5;    }  }; したがって, p_mc1 の x座標は, _root の p の値が 1 未満であるとき(0 のとき)   →290 に 1/5 ずつ近づく _root の p の値が 1 以上であるとき   →90 に 1/5 ずつ近づく ということになります。 MovieClip.onEnterFrame = function() { } は, ムービークリップクラスのイベントハンドラメソッドのうちの1つで, { } 内が1フレーム進む時間ごとに毎回実行されます。 「+=」 は, 加算後代入演算子です。 this._x += (290-this._x)/5; の場合は, this._x = this._x+(290-this._x)/5; と同じ意味です。 仮に this._x が最初 0 であったとします。 onEnterFrame = function() { } の { } 内1回目の実行で, this._x = 0+(290-0)/5;  → this._x =59 になります。 onEnterFrame = function() { } の { } 内2回目以降の実行で, 2回目:this._x = 104.4 3回目:this._x = 141.52 4回目:this._x = 171.216 5回目:this._x = 194.9728 6回目:this._x = 213.97824 7回目:this._x = 229.182592 8回目:this._x = 241.3460736  … 略 … と 290 に向けて前の座標から 1/5 の割合ずつ近づき続けます。 もし _root の p が 1 以上であると, this._x = 90 に向けて近づき続けます。 > _root.p = this._parent.p; の意味が分かっていないので、 > if (_root.p<this.p) の記述についても理解できていません。 なんとなく逆です。 またこの回答で書いた内容も下に書いた物ほど先に作成しています。 考えとしては _root.p の出没は念頭に置いていますが, 実際に詰めて作成して行くのは下の方が先です。 ◎ 簡単な例 ステージ上に直径2cmくらいの塗り入りの丸を描きます。 そしてムービークリップに変換して, 「my_mc」 というインスタンス名を付けます。 そして_rootのフレームに次のように書きます。 ---------------------------------- // my_mc内の変数 num の初期化 my_mc.num = 20; // my_mc をクリックしたときの動作 my_mc.onRelease = function() { this.num += 50; }; // 1フレーム進む時間ごとに毎回実行する動作 my_mc.onEnterFrame = function() { this._x += (this.num-this._x)/5; }; ---------------------------------- そしてパブリッシュ。 my_mc をクリックすると num が 50 ずつ加算されるので, 目標座標が右へ右へと動き,my_mc が右へ右へと動きます。 この辺から脹らませて行って上のような仕組みを作成します。 ですから作成上 _root.p の登場はずっと後になります。

ko_005
質問者

お礼

ありがとうございます。 どう言葉にしてよいか分からないくらい感謝の気持ちでいっぱいです。 自分が参考にさせて頂いていた解説の回答者様ご本人からお答えを頂けるとは思っていなかったので、また素人の自分にも理解出来るくらいに丁寧に、噛み砕いて説明してくださって、どうお礼を申し上げてよいか分かりません。 p_mc? ----- 変数p=? まずここが理解出来ていないと、この先のスクリプトを読み進めることが出来ないんですよね。どうして変数を設定するかというと、各ムービークリップのpの値、そして_rootのpの値との関係性で、各ムービークリップの目標座標が決まるからなんですよね。 // 選択番号 p の初期化  p = 0; 動かないムービークリップp_mc0を所定の位置に配置するために、この記述は絶対必要なんですね。 _root.p = this._parent.p この部分についても本当に分かりやすく解説して下さって、またthisの指し示すものについてもこれまで混乱していたので、BlurFiltan様の教えて下さったことを心に留めながら勉強していこうと思っております。 相対パス・絶対パスについても、むやみやたらに混ぜて使うのではなく、必要なときに、必要に応じて使用するということですね。 エンジン部分のスクリプトについても、実際に数値を当てはめて解説してくださったので、非常にわかりやすかったです。 >> _root.p = this._parent.p; の意味が分かっていないので、 >> if (_root.p<this.p) の記述についても理解できていません。 >なんとなく逆です。 この部分についても、例題を出して下さったので理解することが出来ました。例題のスクリプトの仕組みを膨らませたものが今回のスライド式のスクリプトになるのだから、_root.p の登場はずっと後になりますね。 本当に、ご丁寧な解説、ありがとうございました。 これからActionScriptの勉強、頑張っていきます。 本当に感謝いたします。ありがとうございました!

関連するQ&A