• ベストアンサー

Flashでmc.onPress = function() を使ったスクリプトでわからない所が・・・

FLASHのActionScriptで質問です。 今の赤・青・緑の3種類のムービークリップ(以下、MC)をそれぞれ6つ、 合わせて18つステージ上に配置し、それぞれに… 赤)markRed01_mc, markRed02_mc … markRed06_mc 青)markBlue01_mc, markBlue02_mc … markBlue06_mc 緑)markGreen01_mc, markGreen02_mc … markGreen06_mc という、インスタンス名をつけています。 --画面の模式図------------------ ┌───────────┐ │                 │ │● ● ● ● ● ●   │←赤の段 │                 │ │● ● ● ● ● ●   │←青の段 │                 │ │● ● ● ● ● ●   │←緑の段 │                 │ └───────────┘ -------------------------------- これらのMC全てに対して「マウスを押した時」に消えるようにするため、 以下のscriptをタイムライン上に記述しました。 for (var i = 1; i<=6; i++) { this["markRed0"+i+"_mc"].hit.onPress = function() { eval((targetPath(this).substring(0, 20))).play(); }; this["markBlue0"+i+"_mc"].hit.onPress = function() { eval((targetPath(this).substring(0, 21))).play(); }; this["markGreen0"+i+"_mc"].hit.onPress = function() { eval((targetPath(this).substring(0, 22))).play(); }; } [解説] ・MC内の当たり判定用のMC(インスタンス名:hit)に対し、  マウスを押した時にMCが再生(消えていくアニメーション)するようにしています。 ・MC内では最初にthis.stop();させ、  押して再生された後に、  MC内の最終フレームに来た時に再びthis.stop();するようしています。 このとき、上記のscriptを実行させると“問題なく動きます”。 しかし、MCに対するplay();命令で、 「eval((targetPath(this).substring(0, 20))...」という あまり「スマートでないやり方」になってしまっています。 そこで、これと同じように動作し、且つスマートに記述する方法があれば 教えていただきたく今回質問させていただきました。 なお、開発環境は以下の通りです。 --------------------------------------------------------------- システム:Microsoft Windows XP Professional Version2002 SP3  FLASH:macromedia FLASH Professional Ver8.0     ※ただし、Flash Player 7で動作すること。 --------------------------------------------------------------- 他に不足している点があれば、回答させていただきます。 以上、よろしくお願いいたします。

  • Flash
  • 回答数3
  • ありがとう数4

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

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

this.markRed01_mc.hit.onPress = function() { … }; というスクリプトを書いた場合, その { … } 内で使われる this は markRed01_mc.hit になります。  スクリプトを書いた階層     └markRed01_mc         └hit ←これが this hit の親のタイムラインを play() させたいわけですから, eval((targetPath(this).substring(0, 20))).play();    ↓変更↓ this._parent.play(); でうまく行くと思いますよ(検証はしていませんが)。 なお,この場合, _parent.play(); と書くのと, this._parent.play(); とでは意味が違います。 _parent.play(); では,スクリプトを書いた階層の親階層が play() されます(そんな階層があれば)。 this._parent.play(); では,hit の親階層が play() されます。

eye-eye
質問者

お礼

ご丁寧な回答ありがとうございます。 ご指摘の通り、this._parent.play();でなく、_parent.play();でプログラムを組んでいた経緯で、フクザツなプログラムになってしまっていたようです。 おかげさまでうまくいきました、ありがとうございます。

その他の回答 (2)

  • cspl
  • ベストアンサー率83% (55/66)
回答No.3

#1です。 再生させるのはhitではなくその上の階層のMCなのですね。すみません、勘違いしていました。 でしたら、#2の方の記述通り、thisの部分をすべてthis._parentに置き換えてください。

eye-eye
質問者

お礼

ご回答ありがとうございました。

  • cspl
  • ベストアンサー率83% (55/66)
回答No.1

どこまで「スマート」さを求めるかにもよりますが、パス指定をシンプルにしたい、ということでしたらeval部分をthisに置き換えればいいのではないでしょうか? ______________________________________________________ for (var i = 1; i<=6; i++) { this["markRed0"+i+"_mc"].hit.onPress = function() { this.play(); }; this["markBlue0"+i+"_mc"].hit.onPress = function() { this.play(); }; this["markGreen0"+i+"_mc"].hit.onPress = function() { this.play(); }; } ______________________________________________________ 全く同じ命令文(hitをplayさせる)を繰り返し記述しているため、この記述も完全にスマートは言えませんが、クラスを使用しない記述であれば気にならないかな、というレベルです。 一番シンプルに済むのはすべてのhitのMovieClipを共通にして、hitのフレームに直接書くことです。上記の命令だけであれば3行だけで済むはずです。 □MC[hit]に記述 ______________________________________________________ this.onPress = function() { this.play(); }; ______________________________________________________

関連するQ&A

  • FlashのMCに複数の動作をつけるためには

    ムービークリップに スクリプト(以下(1)(2))をつけたいのですが、 そのスクリプトを別々(フレームやムービークリップ)に設定しているためか、 思うような動きを出すことができません。 同じフレームにスクリプトを書くことができれば 解決できると思うのですがそれができなくて・・・。 私の考えるイメージは以下の通りです・・・。 (1)フレーム上に赤の四角□(R_mc1、R_mc2)と白の四角□(W_mc1、W_mc2)のムービークリップ(MC)があります。 (2)赤のMCはドラッグすることができ、ドラッグしたMCは他のMCに重なると常に上に表示される。 (3)ドラッグした赤のMCが白のMCにヒットすれば(重なれば)、赤から黄へと色が変わる。  (そのために、赤のMC内のタイムラインには、フレーム1に赤、フレーム2に白、フレーム3に黄色の四角□を置いて、ヒットすればMC内のフレーム3にいくようにする。) (4)赤の四角□をドラッグせずにクリックだけをした場合は、MC内のフレーム2に行き、赤から白に色が変わる。 (5)リセットボタンをクリックすると、赤や黄のMCが元の位置に戻る。(最初のMCに戻る) 環境は、Flash Professional CS5.5 Action Script 2.0   Flash Player10 です。 以下はフレームに書いたスクリプト(1)です。 //--------------------------- //深度カウント用変数を用意 var dep_cnt:Number = 1; //変数 i に 1~2を入れながらループ for (var i:Number = 1; i<=2; i++) { //★「R_mc○」内の再生を停止 this["R_mc"+i].stop(); //★「R_mc○」内の変数 target_mc に「W_mc○」の参照を代入 this["R_mc"+i].target_mc = this["W_mc"+i]; //「R_mc○」押下時に関数 dragMC を実行 this["R_mc"+i].onPress = dragMC; //「R_mc○」を放した時に関数 dropMC を実行 this["R_mc"+i].onRelease = dropMC; //「R_mc○」をMC外で放した時にも関数 dropMC を実行 this["R_mc"+i].onReleaseOutside = dropMC; } //関数 dragMC の定義 function dragMC():Void { //深度カウント用変数をカウントアップ dep_cnt++; //押下されたMCをその深度に移動 this.swapDepths(dep_cnt); //押下されたMCのドラッグを開始 this.startDrag(); //★マウスが動く度に関数 watchHitW_mc を実行 this.onMouseMove = watchHitW_mc; } //関数 dropMC の定義 function dropMC():Void { //放されたMCのドラッグを終了 this.stopDrag(); //★マウスが動く度に関数 watchHitW_mc を実行するのを解除 delete this.onMouseMove; } //★関数 watchHitW_mc の定義 function watchHitW_mc():Void { //★ドラッグ中のMCがそのMC内の変数 target_mc に // 代入したMCとヒットしていれば if (this.hitTest(this.target_mc)) { //★ドラッグ中のMC内をフレーム3で停止 this.gotoAndStop(3); } else { //★それ以外はドラッグ中のMC内をフレーム1で停止 this.gotoAndStop(1); } } //--------------------------- 以下はR_mc1とR_mc2自体に書いたスクリプト(2)です。  R_mcをクリックしたときに白色になるようにR_mc 内のフレーム2(白い四角□)に行くようにしてあります。 (本当は、上記に示したフレームに書くスクリプト(1)に加えて書かなければいけないのだと思うのですが、その書き方がわからないので、R_mc自体に書いています。) //--------------------------- on (release) { this.gotoAndPlay(2); } //--------------------------- 以上のようなスクリプト(1)(2)にすると、赤のMC(R_mc1、R_mc2)をドラッグすると、スクリプト(1)ではなく、スクリプト(2)が優先されて、赤から黄にしたいのに、白に変わってしまうのです。 上記の私の考えるイメージ(1)~(5)が実行できるようなフレームに書くスクリプトを教えてください。 どうぞよろしくお願いいたします。 補足 リセットボタンには以下のスクリプトを書いてあります。    リセットボタンは同じフレーム内にスクリプトを書かずに、リセットボタン自体に書いてもかまいません。 //------------------ on (release) { //変数 i に 1~2を入れながらループ for (i=1; i<=2; i++) { //「R_mc○」を削除 this["R_mc"+i].removeMovieClip(); } gotoAndStop(1); gotoAndStop(2); } //------------------

    • ベストアンサー
    • Flash
  • Flashで、ドラッグしたMCを上に表示&色の変化

    先日、Flashで、ドラッグしたムービークリップ(MC)を常に表示する方法を教えてもらい、 うまく表示することができましたが、今回は、このMCに色を変化させるスクリプトをつけ加えたいので 教えてください(色の変化は、別の質問者の回答を参考にしましたが、うまくいかないので・・・。) 私が作成したいイメージは以下の通り((1)~(3))です。 (1)赤の□のMCが2つ(インスタンス名:「R_mc1」「R_mc2」)と白の□のMCが2つ(インスタンス名:「W_mc1」 「W_mc2」)。 赤のMCはそれぞれMC内の2フレーム目に黄色の□を置いている。 (2)赤の□をドラッグして白の□にふれると、赤の□が黄色の□に変化する。  (R_mc1はW_mc1とふれたときにだけ黄色に変化。R_mc2はW_mc2とふれたときにだけ黄色に変化。) (3)赤の□は、どのMCに重なっても常に上に表示されるようにする。 以下にスクリプトを書いてあります。以下のスクリプトは赤や白のMCが置いてあるフレームに書いてみましたがうまくいきません。教えてgooでいただいた2種類のスクリプトを単純にくっつけただけなので、うまくいかないのは当然だと思いますが・・・。 すみませんが、わかりやすく教えてください。どうぞよろしくお願いいたします。 補足 Flashバージョン CS5.5   アクションスクリプト2.0  FlashPlayer6 です。 //------------------------------------ //深度カウント用変数を用意 var dep_cnt:Number = 1; //変数 i に 1~2 を入れながらループ for (var i:Number = 1; i<=2; i++) { //「R_mc○」押下時に関数 dragMC を実行 this["R_mc"+i].onPress = dragMC; //「R_mc○」を放した時に関数 dropMC を実行 this["R_mc"+i].onRelease = dropMC; //「R_mc○」をMC外で放した時にも関数 dropMC を実行 this["R_mc"+i].onReleaseOutside = dropMC; } //関数 dragMC の定義 function dragMC():Void { //深度カウント用変数をカウントアップ dep_cnt++; //押下されたMCをその深度に移動 this.swapDepths(dep_cnt); //押下されたMCのドラッグを開始 this.startDrag(); } //関数 dropMC の定義 function dropMC():Void { //放されたMCのドラッグを終了 this.stopDrag(); } //------------------------------------ //--------------------------- //「R_mc1」上でマウスダウン時に実行するメソッドを定義 R_mc1.onPress = function():Void { //「R_mc1」のドラッグを開始 R_mc1.startDrag(); //マウスが動く度に関数 watchHitW_mc1R_mc1を実行 this.onMouseMove = watchHitW_mc1R_mc1; }; //「R_mc1」上でマウスアップ時に実行するメソッドを定義 R_mc1.onRelease = R_mc1.onReleaseOutside = function():Void { //このMC(R_mc1)のドラッグを終了 this.stopDrag(); //マウスが動く度に関数 watchHitW_mc1R_mc1 を実行するのを解除 delete this.onMouseMove; } //関数 watchHitW_mc1R_mc1の定義 function watchHitW_mc1R_mc1():Void { //もし「R_mc1」が「W_mc1」にヒットしていれば if (R_mc1.hitTest(W_mc1)) { //「R_mc1」内の再生を フレーム2 で停止 R_mc1.gotoAndStop(2); } else { //ヒットしていなければ「R_mc1」内の再生を フレーム1 で停止 R_mc1.gotoAndStop(1); } } //--------------------------- //「R_mc2」上でマウスダウン時に実行するメソッドを定義 R_mc2.onPress = function():Void { //「R_mc2」のドラッグを開始 R_mc2.startDrag(); //マウスが動く度に関数 watchHitW_mc2R_mc2を実行 this.onMouseMove = watchHitW_mc2R_mc2; }; //「R_mc2」上でマウスアップ時に実行するメソッドを定義 R_mc2.onRelease = R_mc2.onReleaseOutside = function():Void { //このMC(R_mc2)のドラッグを終了 this.stopDrag(); //マウスが動く度に関数 watchHitW_mc2R_mc2 を実行するのを解除 delete this.onMouseMove; } //関数 watchHitW_mc2R_mc2の定義 function watchHitW_mc2R_mc2():Void { //もし「R_mc2」が「W_mc2」にヒットしていれば if (R_mc2.hitTest(W_mc2)) { //「R_mc2」内の再生を フレーム2 で停止 R_mc2.gotoAndStop(2); } else { //ヒットしていなければ「R_mc2」内の再生を フレーム1 で停止 R_mc2.gotoAndStop(1); } }

    • ベストアンサー
    • Flash
  • FlashでドラッグしたMCをリセットして戻すには

     今回もまたFlashのことで教えてください。 先日教えていただいた「ドラッグしたMCを常に上に表示&色の変化」がきちんと動作できて とても助かりましたが、また、新たな課題が出たので教えて下さい。(これまでできていたリセットボタンがうまく動作しなくなっちゃったのです。) 具体的に言うと、つまずいている課題は以下の通りです。  ドラッグして移動したMCを元の位置(フレーム上の最初にあった位置)に戻すために「リセットボタン」を配置しましたが、このボタンでリセットしてもなぜかドラッグして移動したMCもそのまま残った状態で表示されるのです。つまり、完全リセットされないのです。  ドラッグしたMCが元の位置に戻り、ドラッグする以前のフレームが表示されるようにしたいのでどうか教えてください。 私が書いたスクリプトとタイムラインを示しますので、どうぞよろしくお願いいたします。 バージョン Flash CS5.5    アクションスクリプト2.0     Flash Player 6 です。   フレーム1とフレーム2があり、フレーム1はフレーム2に進むためのボタンを配置。 フレーム2には赤の□2つ。白の□2つを配置。 フレーム2に書いたスクリプト(1)は以下の通り (ドラッグしたMCが常に上に表示&色の変化をさせるスクリプト) (赤の□のインスタンス名「R_mc1」「R_mc2」   白の□のインスタンス名「W_mc1」「W_mc2」 ) //--------------------------- //深度カウント用変数を用意 var dep_cnt:Number = 1; //変数 i に 1~2 を入れながらループ for (var i:Number = 1; i<=2; i++) { //★「R_mc○」内の再生を停止 this["R_mc"+i].stop(); //★「R_mc○」内の変数 target_mc に「W_mc○」の参照を代入 this["R_mc"+i].target_mc = this["W_mc"+i]; //「R_mc○」押下時に関数 dragMC を実行 this["R_mc"+i].onPress = dragMC; //「R_mc○」を放した時に関数 dropMC を実行 this["R_mc"+i].onRelease = dropMC; //「R_mc○」をMC外で放した時にも関数 dropMC を実行 this["R_mc"+i].onReleaseOutside = dropMC; } //関数 dragMC の定義 function dragMC():Void { //深度カウント用変数をカウントアップ dep_cnt++; //押下されたMCをその深度に移動 this.swapDepths(dep_cnt); //押下されたMCのドラッグを開始 this.startDrag(); //★マウスが動く度に関数 watchHitW_mc を実行 this.onMouseMove = watchHitW_mc; } //関数 dropMC の定義 function dropMC():Void { //放されたMCのドラッグを終了 this.stopDrag(); //★マウスが動く度に関数 watchHitW_mc を実行するのを解除 delete this.onMouseMove; } //★関数 watchHitW_mc の定義 function watchHitW_mc():Void { //★ドラッグ中のMCがそのMC内の変数 target_mc に // 代入したMCとヒットしていれば if (this.hitTest(this.target_mc)) { //★ドラッグ中のMC内をフレーム2で停止 this.gotoAndStop(2); } else { //★それ以外はドラッグ中のMC内をフレーム1で停止 this.gotoAndStop(1); } } //--------------------------- ドラッグしたMCを元の位置に戻すための「リセットボタン」に書いたスクリプト(2)は以下の通り。 (以前に以下のようなスクリプトで元の配置にリセットされたので同じく書いてみましたが、今回はドラッグしたMCが消えず、そのまま表示されてしまいました。 //--------------------------- on (release) { gotoAndPlay(1); } on (release) { gotoAndStop(2); } //---------------------------  

    • ベストアンサー
    • Flash
  • Flash ActionScript(アクションスクリプト)の挙動

    Flash ActionScript(アクションスクリプト)の挙動が 思うようにならず困っています。 ●使用ツール  Macromedia Flash MX ●やりたいこと  ムービークリップ【mc_4_0】【mc_4_1】【mc_4_2】が配置されている。  各ムービークリップにマウスが乗っているかを毎フレーム判定し、  乗っていればx/yscaleを1.5倍に、乗っていなければ1倍に戻す。 ●現在の処理  ○メインタイムラインの処理 ---------------------------- //最初のシーンを設定 _global.scene = SceneMcSelect //毎フレーム、シーン関数を呼ぶ onEnterFrame = function() { //現在シーンを呼ぶ eval( _global.scene )(); } ----------------------------  ○SceneMcSelect関数の定義 ---------------------------- function SceneMcSelect(){ for( count = 0 ; count < 3 ; count++ ){ //マウスが乗ったか? eval("mc_4_" + count).onRollOver = function(){ trace(count); eval("mc_4_" + count)._xscale = 150; eval("mc_4_" + count)._yscale = 150; } //マウスが離れたか? eval("mc_4_" + count).onRollOut = function(){ trace(count); eval("mc_4_" + count)._xscale = 100; eval("mc_4_" + count)._yscale = 100; } } } ---------------------------- ●現在の挙動  onRollOverやonRollOutの判定は正しく行われているようですが、  x/yscaleの変更処理が行われません。  traceでcountの値を確認すると、なぜか【3】になっています。 難しい処理をしているわけではないと思うのですが、 思うとおりの挙動にならず困っています。 何か間違いや見落とし等ございましたら、ご指摘お願いいたします。

    • ベストアンサー
    • Flash
  • 外部ファイルを読み込んだMCをドラッグ&ドロップしたいんですが?

    flash(swf)で外部ファイルを読み込んだムービークリップ(MC)をドラッグ&ドロップで移動できるようにしたいんですが、どのようにすればできるでしょうか? 通常のライブラリなどに登録して表示させているMC(インスタンス名:photoL)は以下のようなASで処理できるんですが、外部ファイルを読み込んだMC(インスタンス名:photoF)では同じ書き方をしても表示はするんですが、ドラッグ&ドロップで移動できません。 --------------------------------------------------- photoF.loadMovie("test.jpg"); photoL.onPress = function(){ this.startDrag(false,v_leftLock,v_topLock,v_rightLock,v_bottomLock); }; photoL.onRelease = function(){ this.stopDrag(); }; photoL.onReleaseOutside = function(){ this.stopDrag(); }; photoF.onPress = function(){ this.startDrag(false,v_leftLock,v_topLock,v_rightLock,v_bottomLock); }; photoF.onRelease = function(){ this.stopDrag(); }; photoF.onReleaseOutside = function(){ this.stopDrag(); };

    • ベストアンサー
    • Flash
  • スクリプトをまとめて書くには

    Actionscript 2.0で作成しています。 例えばムービークリップaaa1~aaa10までと、bbb1~bbb10があったとして、 aaa1をクリックするとaaa1とbbb1が動く、というようなスクリプトを書きたい場合、 for( i = 1 ; i <= 10 ; i++ ){ eval("aaa"+i).onRelease = function(){ this.gotoAndPlay(2); _root.eval("bbb"+i).gotoAndPlay(2); } } としてもbbbの方が動きません。 iの値がeval("bbb"+i)の時点で11になってしまってます。 なので現状forを使わずに書いているのですが、 このような方法を簡単な記述で実現するにはどうすればいいのでしょう? それと、同じ動作を別のムービークリップにさせたい場合、 まとめて書くことはできますでしょうか? (例えばこれをまとめて書くとか) aaa.onRelease = function(){ _root.stop(); } bbb.onRelease = function(){ _root.stop(); }

    • ベストアンサー
    • Flash
  • actionscript2のクラスの中の書き方について

    Flash ActionScript2のクラスの中の書き方について悩んでいます。 クラスの中にMcを定義するものですがthis.mct.onPressのところで class testAの中の_move()が実行できません。いろいろ試してみました がうまく実行できませんでした。なにかいいやり方はないでしょうか? よろしくお願いします。 class testA{  var mct:MovieClip;  function testA(mct:MovieClip){   this.mct = mct;   this.mct.onPress = function(){    _parent._move();   }  }  function _move(){    this.mct.onEnterFrame = function(){   }  } }

    • ベストアンサー
    • Flash
  • eval関数を利用して複数の処理を1つのfunctionで行う

    こんにちは。 困ったので質問させてください。 今、MX2004のFLASHを使ってあるゲームを作成しています。 「XXX」とリンゲージ名をつけたムービークリップを          for(i=0;i<=100;i++){     obj = _root.attachMovie("XXX", "mc"+i, i);//MCの作成     obj._x = table_x[i];//X軸の値の格納テーブル     obj._y = table_y[i];//Y軸の値の格納テーブル     } で100個のムービックリップを画面上に『mc+連番(以下「mc●●」)』と名前をつけてで作成しました。 この画面上に作成したムービークリップmc●●をクリックするとTraceで「OK」と表示したいのですが・・・     mc1.onMouseUp = function(){       Trace("OK");     }     mc2.onMouseUp = function(){       Trace("OK");     }     mc3.onMouseUp = function(){       Trace("OK");     }     ・     ・×97回     ・ この様にmc●●と同じ数だけ100回同じような文を記述する方法しかないのでしょうか? 個人的には 『eval("_root.mc"+i)』を利用して同じような構文は削除したいのですが良い方法が思いつきません。 何か良い方法がありましたらご教授ください。 お願いします。

  • AS3 mc0~5をまとめて処理する

    AS3初心者です。 forにてmc0~5をまとめて処理したいのですが、 下記スクリプトで、function内mc0の書き換え方が分かりません。 よろしくお願いします。 ///////////////////////////////////////// import fl.transitions.easing.Regular; import fl.transitions.TweenEvent; var twObj:Tween; for(var i:int=0;i<=5;i++){ this["mc"+i].addEventListener(MouseEvent.ROLL_OVER, hiraku); this["mc"+i].addEventListener(MouseEvent.ROLL_OUT, modoru); } function hiraku(eventObj:MouseEvent):void { //mc0を["mc"+i]としまとめて処理したい twObj=new Tween(mc0,"rotation",Regular.easeInOut,0,30,1,true); } function modoru(eventObj:MouseEvent):void { //mc0を["mc"+i]としまとめて処理したい twObj=new Tween(mc0,"rotation",Regular.easeInOut,30,0,1,true); } //////////////////////////////////////////

    • ベストアンサー
    • Flash
  • 当たり判定で一度だけ音をならすには

    当たり判定で、下記の様に書きました。 I_blueは青ボールインスタンス名、I_green 緑ボール インスタンス名です。 緑ボールをドラッグ&ドロップで青ボールに重ねると音がでるというものを作ろうとしています。 // Hsound01 = new Sound(_root.I_blue); Hsound01.attachSound("HS_sound01"); // _root.I_blue.onEnterFrame = function() { if (this.hitTest(_root.I_green)) { _root.Hsound01.start(0, 1); } }; // I_green.onPress = function(){ startDrag(this,false); } I_green.onRelease = function(){ stopDrag(); } ですが、これだと音が繰り返し再生されてしまいます。 当たり判定で一度だけ音をならすには、どのようにすべきでしょうか。 お知恵をお貸しいただけたらと思います。 よろしくお願いします。

    • ベストアンサー
    • Flash

専門家に質問してみよう