- ベストアンサー
FLASHで作る商店街の地図について
- 商店街の地図をFLASHで作ることになりました。ユーザーが拡大・縮小や、ドラッグを行って地図上にある店のアイコンを選択、指定したHTMLにジャンプすることができるようにしたいです。
- 地図上に店の名前を入れると、拡大しすぎで見にくくなってしまいます。そこで、マウスオーバー時に店名を表示させるポップアップヘルプのような仕組みを作りたいです。また、地図の拡大・縮小に関わらず、店名表示部分のサイズを一定に保ちたいです。
- 環境はWin版Flash MXです。ソースコードの載せられない質問ですが、どなたか対処法を教えていただけると嬉しいです。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
要するに、ポップアップと地図・アイコンが、違う座標系になっていればいいのだと思います。 こんな方針で考えてみてはいかがでしょう。 地図の図面の上に店のアイコンのムービークリップを配置したムービークリップ、Map を作ります。アイコンには、それぞれインスタンス名を付けます。 それとは別に、ポップアップ用のムービークリップを作ります。フキダシでもポップアップチップのようなものでも構いませんが、テキストを表示するのでテキストフィールドが必要です。テキストは空にして、テキストフィールドに変数を設定します。(ここでは、仮に s_name とします)これのインスタンスを、非表示にしてステージのどこかに置いておきます。 アイコンの上にマウスカーソルが乗ったら、ポップアップのテキストフィールドの変数 s_name に店名を設定して、アイコンの傍に表示します。ポップアップは _root にありますから、Map のムービークリップが拡大・縮小されていても影響は受けません。 アイコンからマウスカーソルが外れたら、ポップアップは非表示にします。ついでに、s_name の中身をヌルストリング("")にしておくのが無難です。 ポップアップを設置する関数と消去する関数は、別々に作ります。アイコンにマウスカーソルが乗った/外れた時の処理は、Flash MX から使えるようになった、MovieClip オブジェクトの onRollOver、onRollOut イベントハンドラを使って、イベントが発生する度に関数を呼ぶようにスクリプトを組みます。 店名は関数を呼ぶ時に引数で渡してもいいのですが、同じシンボルから複数のアイコンを作る場合などは、コンポーネントを利用すると便利かも知れませんね。 コンポーネントの詳細は省略しますが、一言で言うなれば、パラメータのあるムービークリップのようなものです。ムービークリップとして作ったものにパラメータを定義すると、コンポーネントに変わります。 例えば、喫茶店のシンボル「 cafe 」に、コンポーネント定義で「 shop_name 」という変数を定義するとします。「 cafe 」のインスタンスは全て「 shop_name 」というパラメータを持ち、各インスタンスの「 shop_name 」に、それぞれ違う値や文字列を設定できるようになります。ActionScript では、インスタンス名.shop_name の形で参照します。 それから、今回の処理で問題になるのはポップアップの表示位置です。ポップアップの表示位置はアイコンの座標から決めますが、ポップアップは _root、アイコンは Map と、それぞれ違う座標系にあるので、単にアイコンの座標+○○とすると、位置がズレてしまいます。そこで、アイコンの座標をステージの座標(グローバル座標)に直す必要が出てきます。この変換には、MovieClip オブジェクトの localToGlobal メソッドを使います。 とりあえず、ステージに地図のシンボル「Map」のインスタンス「 map 」と、ポップアップの「 popup_chip 」というインスタンスがあるとします。「 map 」の中には「 shop1 」「 shop2 」というインスタンスがあり、この2つは、コンポーネント「 icon 」のインスタンスです。「 icon 」にはパラメータ「 shop_name 」(タイプは String )が定義されていて、各インスタンスにそれぞれの店名が入っているものとします。 ポップアップを設置・消去する関数を、メインのタイムラインのフレームアクションで設定します。大体、こんな感じになるかと思います。 (↓このスクリプトをコピーして使う時は、各行の行頭に入っている全角のスペースを、全て半角のスペースかタブに置き換えてください。このまま使うとシンタックスエラーになります) //ポップアップの設置 //引数はアイコンのインスタンスの名前 function Set_PopUp (icon_name) { var clip_name; temp = new Object(); clip_name = "_root.map." + icon_name; //アイコンの座標をステージの座標に変換 temp.x = eval(clip_name)._x; temp.y = eval(clip_name)._y; _root.map.localToGlobal(temp); //ポップアップを、アイコンの上方に表示 popup_chip._x = temp.x popup_chip._y = temp.y-60; //ポップアップに店名を設定 popup_chip.s_name = eval(clip_name).shop_name; //ポップアップを可視にする popup_chip._visible = true; } //ポップアップを消す function Delete_PopUp() { //ポップアップに表示する文字をクリア popup_chip.s_name = ""; //ポップアップを見えなくする popup_chip._visible = false; } 続けて、「 shop1 」「 shop2 」のムービークリップで、onRollOver イベントが発生した時には Set_PopUp 関数を、onRollOut イベントが発生した時には Delete_PopUp 関数を呼ぶように定義します。(「 shop2 」の方は省略しますが、map.shop2.・・・として、同様に定義して下さい) //「 shop1 」にカーソルが乗ったらポップアップを表示 map.shop1.onRollOver = function () { Set_PopUp (this._name); } //アイコンからカーソルが外れたらポップアップを非表示に map.shop1.onRollOut = function () { Delete_PopUp(); } コンポーネントのパラメータは複数定義できます。HPのアドレスを変数「url」として定義しておけば、クリックした時に、パラメータで持つURLのページを表示させることも可能です。 //「shop1」がクリックされたらHPを表示 map.shop1.onRelease = function () { getURL(this.url , _blank); } なお、map を拡大・縮小する時に、map.onPress や map.onRelease を使うと、map 全体がクリックのヒット領域として認識されてしまい、map にあるアイコン上でのロールオーバー・ロールアウトが検出されなくなることがあるようなので、ご注意下さい。 長くなってすみませんでした。
お礼
とても丁寧に教えて頂きましてありがとうございます。 非常にわかりやすかったので初心者の僕としましても嬉しい限りです。 特にlocalToGlobalを用いての座標の取得は思いもつかなかったので、これを機に勉強をしたいと思います。 教えて頂いたASもわかりやすく、感謝しています。 短いお礼で申し訳ありません。ご回答ありがとうございました!