- ベストアンサー
addEventListenerでカードの画像が変わらないエラーが発生する
- Flash初心者がActionScript 3.0でカードゲームの作成を試みています。
- addEventListenerの扱いで問題が発生しており、カードをクリックしても画像が変わりません。
- 解決方法についての情報を探しているが、既存の質問とは異なるエラーが発生しているため解決策がわからないとのことです。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
===【本題の回答の前に】============ 2つ目の for文 の一部分に間違いがありますね。 for(var i:int; i<player01Card.length ;i++) { ↓iの初期値が抜けてます↓ for (var i:int = 0; i<player01Card.length; i++) { と言うか... 本来 var i は最初の for文 の方などですべきです。 最初の for文↓ for(i=0;i<60;i++){ ↓変更↓ for (var i:int=0; i<60; i++) { 2つ目の for文↓ for(var i:int; i<player01Card.length ;i++) ↓変更↓ for (i = 0; i<player01Card.length; i++) { . ===【本題の回答】=============== > 何が問題なのか、 これについては, 2つ目の for文 の後辺りに trace(i); と書いてムービープレビューしてみると その問題の原因がわかると思います。 for文 を抜けた後 変数 i に代入された値は player01Card.length (=60) になって止まっているため どのボタンをクリックしても player01Card[60].gotoAndStop(36); が動作します。 その player01Card[60] は存在しないはずなのでエラーが出るのです。 この件に関しては 書かれていらっしゃる http://okwave.jp/qa/q4646183.html で 超スローモーション的な動作説明を入れて詳細に書いています。 > >evnet.target.gotoAndStop(36);としてしまうと > カードの合成前の絵柄やテキストがgotoAndStopされてしまう こちらに関しては, まず第一に書かれていらっしゃる日本語の意味が良くわかりません。 「カードの合成前の絵柄やテキストがgotoAndStopされてしまう」とは??? さらに, 私の方で実際に作って検証してみましたが 無事にクリックした Card 内が フレーム36 で停止しましたよ。 ひょっとして Card のムービークリップは さらにその中に 子ムービークリップ が入っていて その 子ムービークリップ 内にも複数フレームがあって その中でも絵柄が変わるとか??? とにかく何だか良くわかりませんが, これに関しては target ではなくcurrentTarget を使えば解決するかもしれません。 evnet.target.gotoAndStop(36); ↓変更↓ event.currentTarget.gotoAndStop(36); . ===【オマケの回答】============== target や currentTarget を使わずに Card クリック時に クロージャ(関数の一種) を実行させる方法もあることはあります。 ◎クロージャを使う方法例↓ //------------------------------------- var player01Card:Array = new Array(); //60枚のカードを生成 for (var i:int=0; i<60; i++) { player01Card[i] = new Card(); addChild(player01Card[i]); //(↓※私の個人的な動作検証用の行) //player01Card[i].x = i * 8; } for (i = 0; i<player01Card.length; i++) { //player01Card[i] クリック時に関数 onCardClick の戻り値を実行 player01Card[i].addEventListener(MouseEvent.CLICK,onCardClick(player01Card[i])); } //クロージャ を返す関数 onCardClick の定義 function onCardClick(obj:Card):Function{ //戻り値として クロージャ を返す return function():void{ obj.gotoAndStop(36); } } //------------------------------------- ※クロージャ は ActionScript 専用用語ではなく . 多くの言語で使われる一般的プログラム用語です。 その他, 私が「ただ考えてみた」というだけのことで 全くお薦めできない方法ですが 次のようにしても target や currentTarget を使わなくてもできることはできます。 (カードどうしが重なることがある上で,さらにカードの上下関係が変わる場合などは,このままでは使えません。) ◎カードの親クリックでマウスとヒットしたカードに命令する方法↓ //------------------------------------- var player01Card:Array = new Array(); //60枚のカードを生成 for (var i:int=0; i<60; i++) { player01Card[i] = new Card(); addChild(player01Card[i]); //(↓※私の個人的な動作検証用の行) //player01Card[i].x = i * 8; } //この階層に対してクリック時の関数を定義 this.addEventListener(MouseEvent.CLICK, function(event:Event){ //配列要素の最後から最初に向けてループ for(i = player01Card.length-1; i >= 0; i--){ //配列要素にマウスがヒットしていれば if(player01Card[i].hitTestPoint(player01Card[i].parent.mouseX,player01Card[i].parent.mouseY,true)){ //対象カード内をフレーム36に進める player01Card[i].gotoAndStop(36); //この for文 を抜ける break; } } } ); //-------------------------------------
お礼
拙い質問に丁寧なご回答、ありがとうございました。本当に助かりました。 結論から言えば、ご提示の「クロージャ」を用いたやり方で実現できました。キーワードを教えていただいたので自分でも調べてみたいと思います。 以下、蛇足ながら質問に不備があった部分等の補足です。 --- >ひょっとして Card のムービークリップは >さらにその中に 子ムービークリップ が入っていて >その 子ムービークリップ 内にも複数フレームがあって >その中でも絵柄が変わるとか??? まさにそのとおりです。カードなので背景ムービークリップや絵柄ムービークリップなどの集合として作成していました。具体的にはカードをaddChildした上でさらにカード上に背景と絵柄をaddChildするような感じです。 そのためクリックすると背景の色だけ変わってしまったり絵柄だけ変わってしまったりしていたのです。 >これに関しては target ではなくcurrentTarget を使えば解決するかもしれません。 targetのように絵柄の一部が変わってしまうことはありませんでしたが、元のエラーが発生しまいました。 >2つ目の for文 の一部分に間違いがありますね。 コードを抜粋する際にミスしたようです。一度コンパイルしてみてから展開すべきでした・・・余計なお手間をおかけしました。 >その player01Card[60] は存在しないはずなのでエラーが出るのです。 こちらについては、いろいろと配列番号を変更してみてもエラーは発生しますので、原因は他所のようです。(というかこちらも抜粋する際にコードを編集して余計なエラーを作ってしまっているようです・・・)