• ベストアンサー

ライブラリにある素材をクリックしてイベントを起こしたい

http://okwave.jp/kotaeru.php3?q=1795976 で質問させて頂きました。 無事カードの初期配置は出来たのですが、今度は選択する時に どうしたらよいかわからなくなりました。 今考えてる方法としてはカードの形で100%透明のオブジェクトを ボタンで作り、それをカードとは別の上位レイヤーに配置し、それ をクリックしたかどうかでイベントを起こすというものです。 ただ、あまりスマートな方法とは思えずもっと簡単に出来るのでは と思い質問させて頂きました。 状況としては手元にある手札3枚のうちどれかをクリックして その手札を使用するというものです。 その後、使った手札の場所は空欄になり、右にあるカードが 左に詰めてくる形で右側のカードの場所に新しいカードが補充 される形を目指しています。 何かしらのヒントでも構いませんのでご教授いただければと 思います。 よろしくお願いします。

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

  • ベストアンサー
  • perse
  • ベストアンサー率74% (113/152)
回答No.6

_root["G"+gif_num].onRelease = fun_Release;では _root["G"+gif_num]というムービークリップをRelease(クリック)したら fun_Releaseという関数を実行するように割り当てています。 例えばmy_btnというボタンのボタンアクションに on(release){  fun_Release(); } と書くとボタンを押したときfun_Release関数が実行されますよね。 コレをフレームアクションに書きたい場合は my_btn.onRelease=fun_Release; と書きます。書き方は違いますが 2つともボタンを押したらfun_Releaseが実行されます。 >fun_Attach(gif_num)の座標設定の項目 fun_Attach(3)でこの関数を呼び出すと(gif_num=3) _root["G"+gif_num]._x = _root["pos_x"+gif_num];の部分を書き直すと _root.G3._x = _root.pos_x3;となります。 _root.G3というのはAttachMovieで読込んだカードで、 _root.pos_x3は冒頭に書いてある通り345ですので 「読込んだカードのX座標=345;」となるわけです。 >_root["G"+move_num].removeMovieClip();は~ 消えます。 しかし、その後で隣りのカードと同じものを 消えたカードの位置にattachMovieしているのです。 コレで動いたように見えますよね。 例) 3 6 7 というカードが配置されていて3のカードをクリックすると for文中のi=1のとき fun_Move(1)関数内---------------------   6 7 :3が消える 6 6 7 :隣りのカードと同じカードが左端に読込まれる for文中のi=2のとき fun_Move(2)関数内--------------------- 6   7 :真ん中のカードが消える 6 7 7 :右端のカードと同じカードが真ん中に読込まれる fun_Attach(3)--------------------------------------------- 6 7 3 :右端にランダムにカードが読込まれる。---(※) (※)の部分は手抜きしてカードを消していません。

その他の回答 (5)

noname#35109
noname#35109
回答No.5

おー,これはすごい。 #2です。 perseさんの#4のスクリプトがスマートで良いと思います。 こんなのがしたかったのです。 細部まで理解していませんが,難なく動きます。 そうか, functionで_root["G"+gif_num].onReleaseを定義してやると, 複数回クリックでもOKになるのですね(って違ってたりして…)。 深くまで理解していませんが勉強になりました。 -------------- perseさん追加回答ありがとうございました。 >> sassakunさん呼び捨てにしてました。ごめんなさい。 いえいえ。 これ,書かれるまで気付きませんでした。 もともと,sassakun で 君 まで入れていますので,何でも良いのですよ。 今後ともよろしくおねがいします。 -------------------------------- この#5は全然,回答になっていませんが,お許しください。

  • perse
  • ベストアンサー率74% (113/152)
回答No.4

#1です。左詰するようにしてみました。 前回同様(書き忘れましたが)カードの識別子は gif1,gif2,gif3です。 左詰の方法はsassakunさんがやった様に クリックしたカードの右隣りのカードを クリックした場所に読込んでいます。 一応コメントはつけましたがわかりづらかったら質問してください。 Flash MX 2004proで動作確認済みです。 _root.pos_x1 = 15; _root.pos_x2 = 180; _root.pos_x3 = 345; _root.pos_y = 50; //カードを選んで貼り付ける関数 gif_num: 読込み位置 function fun_Attach(gif_num) { //1~3のカード位置に読込まれるカード番号の取得 //例) card1 = 2 だと 一番目のカード位置に読込まれるのはgif2 _root["card"+gif_num] = Math.floor(Math.random()*3)+1; _root.attachMovie("gif"+_root["card"+gif_num], "G"+gif_num, gif_num); //座標設定 _root["G"+gif_num].num = gif_num; _root["G"+gif_num]._x = _root["pos_x"+gif_num]; _root["G"+gif_num]._y = _root.pos_y; _root["G"+gif_num].onRelease = fun_Release; } //カードの移動 move_num:移動するカード位置 function fun_Move(move_num) { //カードを消す _root["G"+move_num].removeMovieClip(); //となりのカード番号を取得 _root["card"+move_num] = _root["card"+(move_num+1)]; //その番号を貼り付ける(コレで動いたように見える) _root.attachMovie("gif"+_root["card"+move_num], "G"+move_num, move_num); //以下、座標設定 _root["G"+move_num].num = move_num; _root["G"+move_num]._x = _root["pos_x"+move_num]; _root["G"+move_num]._y = _root.pos_y; _root["G"+move_num].onRelease = _root.fun_Release; } //ボタンを押したときの処理 function fun_Release() { for (var i = this.num; i<=2; i++) { fun_Move(i);//カードの移動 } fun_Attach(3);//3番目のカードを読込み } //カード初期表示 for (var i = 1; i<=3; i++) { fun_Attach(i); } コメント中にあるカード位置とは ステージ上でカードを置く位置です(左から1,2,3)。 カード番号とはライブラリにあるgifの識別子です。

tukikageran
質問者

お礼

ありがとうございます。 イベント型のプログラムはaction scriptが初めてということもあり、流れが理解できずに困っております。 まず、座標の設定をし、カードの初期配置を行いfun_Attach(gif_num)に飛ぶ。 ここでカードがクリックするまでプログラムは待機しているのでしょうか? で、クリックされるとfun_Releaseへ飛ぶのでしょうか。 あと、fun_Attach(gif_num)の座標設定の項目なのですが、左辺と右辺の場所が逆ならよくわかるのですが、 なぜ左辺にこれがあり、右辺にこれがあるのかが よくわかりません。 また、_root["G"+move_num].removeMovieClip();は実際に画面からカードの画像が消えるわけではないのでしょうか? 少々質問が多くなってしまいましたが、ご回答いただけると助かります。 よろしくお願いします

  • perse
  • ベストアンサー率74% (113/152)
回答No.3

#1です。sassakunさん呼び捨てにしてました。ごめんなさい。 コレで出来ると思います。 クリックした後左詰めにするところはやってません。 クリックしたカードの位置に次のカードが読込まれます。 ですので左詰めの処理を入れたときにやっぱり動きませんでしたってなるかも知れないですけど。 // MovieClip this; _root.pos_x1 = 15; _root.pos_x2 = 180; _root.pos_x3 = 345; _root.pos_y = 50; //ランダムでカードを選んで貼り付ける関数 function fun_Attach(gif_num) { _root["card"+gif_num] = Math.floor(Math.random()*3)+1; _root.attachMovie("gif"+_root["card"+gif_num], "G"+gif_num, gif_num); _root["G"+gif_num].num = gif_num; _root["G"+gif_num]._x = _root["pos_x"+gif_num]; _root["G"+gif_num]._y = _root.pos_y; _root["G"+gif_num].onRelease = fun_Release; trace("カード読込み="+_root["card"+gif_num]); } //カード初期表示 for (var i = 1; i<=3; i++) { fun_Attach(i); } //ボタンを押したときの処理 function fun_Release() { fun_Attach(this.num); } // >MobieClipクラスの onRelease 早速使わせてもらいました。

tukikageran
質問者

お礼

sassakunさん、perseさんご回答ありがとうございました。 私の想像してたよりも難しい質問だったようで大変お手数おかけいたしました。 また、市販されている解説書以上に細かい説明もしていただいて大変感謝 しております。 私の手元でも動作を確認しましたが、私のレベルよりもちょっと上の内容になってしまい 解読(理解)に少々手間取っております。 その後の報告も合わせてしたいと思いますので締め切りはもう少々お待ち下さい。

noname#35109
noname#35109
回答No.2

#1の方に反論しているわけでは決してありません。 私も最初そう言う風に考えたのですが,実際にやってみるとできない… #1の方のスクリプトを具体的になおかつ,無駄を省いて書くと以下のようになります。 ムービークリップの中には btn という置きました。 ----------------------------- //識別子 gif1 を G1 というインスタンス名で呼び出し配置 _root.attachMovie("gif1","G1",1); _root.G1._x = 100; _root.G1._y = 150; // 関数my_funを実行(※) _root.G1.btn.onPress=my_fun; function my_fun(){ //G1を消す(次で同深度にMCを呼び出すので無くても消える) //removeMovieClip(_root.G1); //識別子 gif1 を G1 というインスタンス名で呼び出し配置 _root.attachMovie("gif1","G1",1); _root.G1._x = 100; _root.G1._y = 150; trace("成功") } ----------------------------- これ,1回目は成功するのですが("成功"がtraceされるのですが), 6回目(※印)が実行されません。 attachMovieで呼び出されたMCは,removeMovieClip を使っても使わなくてもいつか消さないとなりません。 一度消して,再びattachMovieで呼び出すと, 6行目 _root.G1.btn.onPress=my_fun; が実行されなくなってしまいます。 #1の方は, Buttonクラス の onPress を使われていますが, 私が最初に考えたのは, MobieClipクラスの onRelease です。 _root.G1.onPress=my_fun; もしくは, _root.G1.onRelease=my_fun; のような感じです。 これだと,ブービークリップの中にボタンを作る必要もなくなるので,良いと思ったのですが, 実際にやってみるとこちらもダメ。 _root["G"+i].onPress=my_fun; のようにして,i++; でその都度 i を加算してもダメ。 ○○.onPress(○○.onReleaseも同じ)は,一度消されたムービークリップやボタンには通用しないようです。(初発見。) 昨日はこの辺でかなり悩んで停滞して,回答できませんでした。 違っていたり他のアイデアがございましたら, #1の方や他の方のお知恵も拝借したいと思います。 よろしくお願いします。 === 本題 ================================= >> あまりスマートな方法とは思えずもっと簡単に出来るのでは >> と思い質問させて頂きました。 確かにそう思います。 しかし上のように,かくかくしかじかな状態なので,簡単には行きません。 なので,別法でボタンとムービークリップを切り離す方法を考えました。 それでそのボタンはライブラリから呼び出すのではなく,ステージに最初から配置しておくパターンにします。 サンプルは,前回のこれ↓で良いですよね。 ------------------------------------ for(var i=1;i<=3;i++){ _root["card"+i] = Math.floor(Math.random()*3)+1; _root.attachMovie("gif"+_root["card"+i],"G"+i,i); } _root.G1._x = 150; _root.G1._y =100; _root.G2._x = 250; _root.G2._y =100; _root.G3._x = 350; _root.G3._y =100; ------------------------------------ これを発展させます。 まず, ステージ上に card と同じくらいの大きさのボタンを作ってください。 あとで透明にすれば良いので,今は何か色のある塗りをボタンにする方が良いと思います。 また場所も何処でも良いです。スクリプトで配置します。 そして,このボタンにインスタンス名を付けてください。 ここでは, btn1 btn2 btn3 という3つのインスタンス名のボタンを用意したとしておきます。 スクリプトの発展形1ですが, ポジションを何度でも使うので,書くのは1回で良いように変数化しておきます。 ----------------------------- //各ポジションの設定 var pos_x1 = 150; var pos_y1 = 100; var pos_x2 = 250; var pos_y2 = 100; var pos_x3 = 350; var pos_y3 = 100; //cardに乱数を代入&MCの呼び出し for (var i = 1; i<=3; i++) { _root["card"+i] = Math.floor(Math.random()*3)+1; _root.attachMovie("gif"+_root["card"+i], "G"+i, i); } //MCの配置 _root.G1._x = pos_x1; _root.G1._y = pos_y1; _root.G2._x = pos_x2; _root.G2._y = pos_y2; _root.G3._x = pos_x3; _root.G3._y = pos_y3; ----------------------------- こうなりますね。 これは説明のために書いた変形の途中段階ですから,実際には使いません。 眺めるだけで良いです。 次に,ボタン(btn1~3) を G1~3 と同じ位置に配置し, ライブラリからムービークリップをび出し&配置をボタンでも使うので関数に定義し, それそれを for文で書くと次のようになります。 ----------------------------- //各ポジションの設定 var pos_x1 = 150; var pos_y1 = 100; var pos_x2 = 250; var pos_y2 = 100; var pos_x3 = 350; var pos_y3 = 100; //cardに乱数の代入&ボタンの配置 for (var i = 1; i<=3; i++) { _root["card"+i] = Math.floor(Math.random()*3)+1; _root["btn"+i]._x = _root["pos_x"+i]; _root["btn"+i]._y = _root["pos_y"+i]; } //関数attach_arrange(呼び出し&配置) の定義 function attach_arrange() { //MCの呼び出しと配置 for (var i = 1; i<=3; i++) { _root.attachMovie("gif"+_root["card"+i], "G"+i, i); _root["G"+i]._x = _root["pos_x"+i]; _root["G"+i]._y = _root["pos_y"+i]; } } //関数attach_arrange の実行 attach_arrange(); ----------------------------- そして,一番左に来る btn1 には以下のように書きます。 ----------------------------- on (release) { //変数card の入れ替え _root.card1 = _root.card2; _root.card2 = _root.card3; //変数card3 に乱数を代入 _root.card3 = Math.floor(Math.random()*3)+1; //関数seisei_haichi の実行 attach_arrange(); } ----------------------------- そして,左から2番目に来る btn2 には以下のように書きます。 ----------------------------- on (release) { //変数card の入れ替え _root.card2 = _root.card3; //変数card3 に乱数を代入 _root.card3 = Math.floor(Math.random()*3)+1; //関数seisei_haichi の実行 attach_arrange(); } ----------------------------- そして,一番右の btn3 には以下のように書きます。 ----------------------------- on (release) { //変数card3 に乱数を代入 _root.card3 = Math.floor(Math.random()*3)+1; //関数seisei_haichi の実行 attach_arrange(); } ----------------------------- 結局,btn1~3 は,勝手に定義した関数attach_arrange(); を実行するのですが, その前に,変数card1~3 に値を入れ直しているのです。 === PS ================================= 今回の質問を見て,最初, 『簡単。楽勝。』と思ったのですが,実際やってみるとすごく難しかったです(難しいです)。 それと, >> 使った手札の場所は空欄になり、右にあるカードが >> 左に詰めてくる形で右側のカードの場所に新しいカードが補充 >> される形を目指しています。 ここに書かかれているように, 最初はクリックしたムービークリップを消し, 残ったもののポジションを移動して, 開いた右にattachMovieするのを考えましたが, 消えたところに右からMCを移動させて補充すると,ターゲットとなるMCが動いてしまう。 それも,不規則に入れ替わるので次に消すMCをスクリプトで定められません。 なんとかすれば定められるのかもしれませんが,定め方がわかりませんでした。 なので,ボタンをクリックする度にMCが移動するのではなく, 同じインスタンス名で同じ場所に再呼び出しをする形を取りました。 簡単なようで難しいですね。 次の壁が来て質問されても,おそらく回答出来ない気がします。

  • perse
  • ベストアンサー率74% (113/152)
回答No.1

ライブラリにある素材にボタンを配置します。 attachMovieしてからボタンアクションを記述します。 前回の質問でのsassakunの回答を使わせてもらうと、 _root.attachMovie("gif"+card1,"G1",1); _root.G1.ボタンインスタンス名.onPress=my_fun; function my_fun(){ trace("押した時の処理"); }

関連するQ&A