• ベストアンサー

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
  • 回答数2
  • ありがとう数2

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

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

大きな問題点が3点ありますが, そのうちの2点はとりあえず無視します。 trace(count); の出力結果が 3 になるのは 単純に次のようなスクリプトを書けば理解できると思います。 ------------------------------ for (count=0; count<3; count++) { trace(count); } trace(count); trace(count); trace(count); ------------------------------ もし for文を動作的に理解するのが難しければ, while文 にすればわかりやすいかもしれません。 上記 for文 使用のスクリプトと全く同値なものです↓。 ------------------------------ count = 0; while (count<3) { trace(count); count++; } trace(count); trace(count); trace(count); ------------------------------ for文にしても,while文 にしても, 結局 count の値は 3 になってループを抜けます。 したがって次のような出力結果になります↓。 ------- 0 1 2 3 3 3 ------- たとえば, このまま 10秒後 に trace(count); を実行したとしても結果は同じ。 count は 3 のままです。 このまま 1分後 に trace(count); を実行したとしても結果は同じ。 count は 3 のままです。 つまり, このまま MCにロールオーバーしたときに trace(count); が実行されても結果は同じ。 count は 3 のままです。 したがって,  eval("mc_4_" + count)._xscale = 150; はいつ実行しても  mc_4_3._xscale = 150; を実行することと同じになります。 というわけで, 単純にこれで良いのではないでしょうか↓。 (#1の方と同じ) ------------------------------ // ユーザ定義関数 SceneMcSelect の定義 function SceneMcSelect() { for (count=0; count<3; count++) { //マウスが乗ったら実行する関数を定義 eval("mc_4_"+count).onRollOver = function() { this._xscale = 150; this._yscale = 150; }; //マウスが離れたら実行する関数を定義 eval("mc_4_"+count).onRollOut = function() { this._xscale = 100; this._yscale = 100; }; } } // ユーザ定義関数 SceneMcSelect の実行 SceneMcSelect(); ------------------------------ 本題ではない残りの2つの問題ですが。 > //毎フレーム、シーン関数を呼ぶ > onEnterFrame = function() { > //現在シーンを呼ぶ >   eval( _global.scene )(); > } なせ onEnterFrame で 毎フレーム毎フレーム onRollOver や onRollOut を定義しなければならないのか, 不可解で意味が理解できません。 上に書いたスクリプトのように SceneMcSelect(); は1回で良いはずです。 何度も定義しなおす必要があることがあったとしても, その都度ごとに1回で良いはずで, 毎フレーム毎フレーム(コンマ数秒ごとに)再定義し続ける必要は普通ないと思います。 この理由を補足要求しているわけではありませんよ。 本題とは関係の無い部分なのでどうでも良いのですが, この変な部分は一考の余地があると思いましたので書かせていただきました。 もう1つは eval関数 です。 これを色々なときに使い続けると無事に動作しない場合などが出てきますよ。 eval は主に Flash 4 までで使用されていた古い関数で,Adobe もあまり推奨していません。 完全に非推奨(使用を避ける機能)にはなっていませんが,ほぼ非推奨です。 携帯の Flash Lite 1.x 用のSWFをパブリッシュするなど特別な理由がない限り, eval は使わずに 配列アクセス演算子 を使うのが一般的です。 Google検索 「配列アクセス演算子 eval」 http://www.google.co.jp/search?hl=ja&q=%E9%85%8D%E5%88%97%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E6%BC%94%E7%AE%97%E5%AD%90+eval

sekarasika
質問者

お礼

ご丁寧にありがとうございます! >trace(count); の出力結果が 3 になるのは >単純に次のようなスクリプトを書けば理解できると思います いやはや、まったくその通りです。失礼いたしました。 MovieClip.onRollOver = function() {}を関数の定義と正しく認識しておらず、 「ユーザ定義関数【SceneMcSelect】が呼び出された時に【MovieClip】の【onRollOver】をチェック」 →「条件を満たしていればその中身を実行」 という処理をするものと勝手に想定していたのが勘違いの元だったようです。 2つ目の問題点としてご指摘いただいたのもまさにこの点が原因でして、 【_global.scene == SceneMcSelect】の時のみ、 常時【onRollOver】【onRollOut】をチェックして処理を実行する、というのが本来やりたかったことです。 (つまり、【_global.scene != SceneMcSelect】のときは【onRollOver】【onRollOut】をチェックをして欲しくない) これを実現するには、MovieClip.onRollOver = function() {}以外の手段を使うしかないでしょうか? 3つ目のご指摘の、evalに代わる配列アクセス演算子の使用について、大変勉強になりました。 これまでevalを多用していたため、この機会に差し替えたいと思います。 重ね重ね、ご丁寧なご解答ありがとうございます!

その他の回答 (1)

回答No.1

function の中身は、 eval("mc_4_" + count)._xscale = 150; でなくて、this._xscale = 150; じゃないでしょか? ロールオーバーした時点ではcountは生きてないと思う。

sekarasika
質問者

お礼

お早い回答ありがとうございます! >eval("mc_4_" + count)._xscale = 150; >でなくて、this._xscale = 150; じゃないでしょか? これでうまくいきました! 助かりました。 >ロールオーバーした時点ではcountは生きてないと思う。 まさにその通りですね、お恥ずかしい……。 onRollOver処理を、関数としてではなく SceneMcSelectが呼び出された際にのみチェックするコマンドとして使おうとしていたのが勘違いの原因だったようです。 ご解答ありがとうございました。

関連するQ&A

  • ActionScript2.0のイベントについて

    親ムービークリップに配置した子ムービークリップのイベントが実行されなくて困っています。 親ムービークリップ自体には下記のイベントを設定しています。親ムービークリップはattachMovieで動的に配置しています。 onRollOver・・・onEnterFrameを設定 onRollOut・・・onEnterFrameを削除 子ムービークリップを配置して子ムービークリックにイベントを設定しました。onEnterFrameをは実行されますが、onReleaseが実行されず困っています。 function Parent() { this.onRollOver = function() { this.onEnterFrame = function(){・・・} } this.onRollOut = function(){ delete this.onEnterFrame; } this["child_mc"].onRelease = function() { trace('a') // 実行されない } this["child_mc"].onEnterFrame = function() { trace('b') // 実行される } } ・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・ _root.attachMovie("Parent", "parent_mc", _root.getNextHighestDepth(), new Parent()); 子ムービークリップはオーサリングで静的にParentに配置し、プロパティでchild_mcと設定しています。 onReleaseは実行できず、そこで止まっています。 なんでも良いので教えてください。

    • ベストアンサー
    • Flash
  • FlashCS5 ActionScript2.0で3つのボタンを制御し

    FlashCS5 ActionScript2.0で3つのボタンを制御しています。 それぞれインスタンス名はbt1,bt2,bt3です。 動きはマウスオーバーで120%大きくなり、ロールアウトで100%へと戻るものです。 しかし、ロールアウトの動作中に他のボタンに触ると、ロールアウトの動作が中断してしまいます。 なぜでしょうか? //////////////////////////////////////// stop(); sx = 3; var i; //----------- for( i = 1; i < 4; i++){ Nov = "bt" + i; _root[Nov].onRollOver = function(){ Name = this._name; btOverMotion(Name); } _root[Nov].onRollOut = function(){ Name = this._name; btOutMotion(Name); } } //----------- function btOutMotion(eachNo){ No = eachNo; onEnterFrame = function(){ if(_root[No]._xscale < 100){ delete this.onEnterFrame; }else{ _root[No]._xscale -= sx*2; _root[No]._yscale -= sx*2; } } } //----------- function btOverMotion(eachNo){ No = eachNo; onEnterFrame = function(){ if(_root[No]._xscale > 120){ delete this.onEnterFrame; }else{ _root[No]._xscale += sx; _root[No]._yscale += sx; } } }

    • ベストアンサー
    • Flash
  • 揺れるスクリプトについて

    こちらで教えていただいたサイトで揺れるスクリプト を勉強していたのですが、 ■をMCにして、  onClipEvent (load) {    this._xscale = this._yscale = 0;    function sMove(mScale,acc,conv) {      theScale = theScale*acc+(mScale-this._yscale)*conv;      this._xscale = this._yscale += theScale;    }  }  onClipEvent (enterFrame) {    if (this.hitTest(_root._xmouse,_root._ymouse,1)) {      sMove(130,0.8,0.2);    } else {      sMove(100,0.8,0.2);    }  } と書いたのですがプレビューすると真っ白なままなにも 表示されません。 なぜなのでしょうか?

    • ベストアンサー
    • Flash
  • 【action script】複数のMCを・・・

    環境:Flash8 actionscript2.0 10こ程度のムービークリップをそれぞれクリックした時に同じ動きをさせる文を1つにまとめることは可能でしょうか? ムービークリップそれぞれに mc1 mc2 mc3 …mc10 とインスタンス名をつけています。 さらにその下位層に mc1  └kai_mc mc2 └kai_mc ・ ・ ・ mc10 └kai_mc と置いています。 このそれぞれのムービークリップをクリックした際、その下位層のムービークリップを次のフレームに移動させたいと考えています。 それぞれ個別に書くと _root.mc1.onRelease=function(){ _root.mc1.kai_mc.nextFrame() } と書いていたのですが、ムービークリップの数を増やすかも知れずムービークリップの数分書くのは大変なので1つにまとめたいと考えています。 自分で以下のように書いてみました。 i=0 for(i=1; i>10; i++){ _root["mc"+i].onRelease.function(){ _root["mc"+i].kai_mc.nextFrame() } } うまくいかないので試行錯誤したりtraceで調べたりしたのですがどうもよくわかりません。 i=0 for(i=1; i>10; i++){ _root["mc"+i].onRelease.function(){ trace(i) } } で出力すると 11と表示されるのでpassが違うとは思うのですが・・・ iを1~10で指定しているのになぜ11となるのでしょうか? どうすればpass指定できるのでしょうか? そもそものやり方、考え方が違うかどうかも含め、教えて頂きたく質問しました。 よろしくお願いします。

    • ベストアンサー
    • Flash
  • scriptを使いまわしたい。

    見よう見まねで下記のようなスクリプトを記述しています。 複数のムービークリップに設定していますが、編集するのにかなり手間がかかります。うまく使いまわす方法はございませんでしょうか…。 また、記述の仕方にも問題等ありましたらご指南ください。。 onClipEvent (load) {  sx_move = Math.floor(Math.random() * -10) - 3;  sy_move = Math.floor(Math.random() * 6) - 3;  s_scale = Math.floor(Math.random() * 40) + 40;  _xscale = (s_scale);  _yscale = (s_scale);  n = 1; } onClipEvent (enterFrame) {  _x += (sx_move);  _y += (sy_move); } on (rollOver) {  mx.behaviors.DepthControl.bringToFront(_root);  this.onEnterFrame = function () {   n += 1;   _x -= (sx_move);   _y -= (sy_move);   if (n < 20) {    _x = (_x + 25) / 1.5;    _y = (_y + 12) / 1.5;    _xscale = (_xscale + 50) / 1.5;    _yscale = (_yscale + 50) / 1.5;   } else if (n < 40) {    stop();   } else if (n < 50) {    _x += 13;    _y += 13;    _alpha -= 20;    _xscale = (_xscale) / 1.2;    _yscale = (_yscale) / 1.2;   } else {    stop();   }  }; }

    • ベストアンサー
    • Flash
  • adobe flashアクションスクリプト内の優先順位について。

    adobe flashアクションスクリプト内の優先順位について。 こんにちは。 まだflashをあたり始めて1~2週間ほどしかたっておらず、初歩的で 意味の分からない質問かもしれませんが、教えて頂けると助かります。 アコーディオンメニューを作りたくて、下記のサイトを参考に作成しました。 http://exyz.cocolog-nifty.com/good_sleep/2007/12/au_45b8.html 質問はこのメニューに、flashからマウスが離れると、メニュー1(パネル1)の状態に戻るように するにはどうするのが一番良いのか、ということです。 とにかくまだ用語が分かっておらず、結局 panel02_mc.onRollOut = Delegate.create (this,function():Void{ tw (0,300,320,panel01_mc,panel02_mc,panel03_mc); }); panel03_mc.ononRollOut = Delegate.create (this,function():Void{ tw (0,300,320,panel01_mc,panel02_mc,panel03_mc); }); を付け加える事で思った通りの動きにはなったのですが、ここで疑問がでてきました。 メニュー2からマウスをメニュー3の位置へ動かすと、 メニュー1の状態に戻る命令と、メニュー3の位置へ動く命令が重なっていると思うのです。 実際には、きちんとメニュー3の位置へ動くのですが、アクションスクリプトには ムービークリップの重なり順や、アクションスクリプトにおいて上からの順など 命令文に対しての優先順位があるのでしょうか? なんだか、動くけどもおかしなアクションスクリプトの書き方をしているのではないかと心配で。 本当は、メニュー2かつメニュー3からマウスが離れるとメニュー1の状態に戻るという 命令文をいれたかったのですが...。

    • ベストアンサー
    • Flash
  • 縮小させる時の基点について

    ActionScriptを勉強中です。分からないことがあるので質問させていただきます。 ステージ上にマスクをかけたムービークリップ(インスタンス名:mc)があり、 そのmcを拡大ボタンと縮小ボタンを使い拡大/縮小できるようにしています。 mcが拡大されている時には、mc自体をドラッグして動かせるようにしています。 レイヤー構造は ーーーーーーーーーーーーーーーーーーーーーーーーーーーー 1、ボタン:拡大ボタンと縮小ボタンを配置 2、マスク ---マスクの対象:mcを配置 3、背景:背景というか枠を書いています ーーーーーーーーーーーーーーーーーーーーーーーーーーーー となっております。 mcにには ーーーーーーーーーーーーーーーーーーーーーーーーーーーー on (press) { left = Stage.width-this._width/2-2; top = Stage.height-this._height/2-98; right = this._width/2+2; bottom = this._height/2+2; this.startDrag(false, left, top, right, bottom); } on (release, releaseOutside) { this.stopDrag(); } ーーーーーーーーーーーーーーーーーーーーーーーーーーーー 拡大ボタンには ーーーーーーーーーーーーーーーーーーーーーーーーーーーー on (release) { if (mc._yscale < 300) { mc._xscale = mc._yscale += 100; } else { mc._xscale = mc._yscale = 300; } }ーーーーーーーーーーーーーーーーーーーーーーーーーーーー 縮小ボタンには ーーーーーーーーーーーーーーーーーーーーーーーーーーーー on (release) { if (mc._yscale > 100) { mc._xscale = mc._yscale -= 100; } else { mc._xscale = mc._yscale = 100; } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーー と書いています。 拡大した時の挙動は問題ないのですが、縮小する時の挙動に問題があります。 mcの中心を基点にしているため、端の方でで縮小すると余白が見えてしまいます。 この余白を見せないためにはどうしたら良いのでしょうか? 素人考えでhitTest()を使えば良いのかと思っているのですが、なかなかうまくいきません。 どうしたらよいのかご教示いただけると助かります。よろしくお願いいたします。 制作環境はCS4でAS2.0です。

  • loadMovieしたムービークリップのボタン化

    ムービークリップにloadMovieで1.jpgをロードし、それをボタンにしたいのですが、下のスクリプトではうまく動作しません。 menu01_mc.loadMovie("1.jpg"); menu01_mc._xscale=10; menu01_mc._yscale=10; menu01_mc.onRelease = function(){ gotoAndStop(5); } 最初のloadMovieの部分をなくし、 menu01_mc.onRelease = function(){ gotoAndStop(5); } とするとちゃんと動作します。 loadMovieしたムービークリップはボタンにできないのでしょうか? FlashCS3、actionscript2.0で作成しています。 よろしくお願いします。

    • ベストアンサー
    • Flash
  • forでonRollOverを一回で書くには?

    下の内容をfor文を使って一回で書くにはどのようにすればよいですか? _root.a0.onRollOver = function(){  trace("0"); } _root.a1.onRollOver = function(){  trace("1"); } _root.a2.onRollOver = function(){  trace("2"); } 下のように書いてみましたが、どのmcにロールオーバーしても "2" と表示されてしまいます。 for(i=0; i<3; i++){  _root["a"+i].onRollOver = function(){   trace(i);  } }

    • ベストアンサー
    • Flash
  • actionscriptのfunction関数について

    現在Flashの勉強をしている者です。 超初心者丸出しの質問なのですが調べても納得いく回答にめぐりあわなかったのでここで質問させていただきます(前回もPHPについて質問したら素晴らしい回答があったので!!) Function関数なのですが function 半角英字で任意の文字 () {  以下実行文 } でユーザー定義関数が作られるのはわかったのですが、 本を読みながら勉強をしていてわからないのが this.onRollOver = function () { roll = true; this.nextFrame(); }; という記述で、『マウスがムービークリップ上にあるかの判定処理』という説明がされているのですが恥ずかしながらよくわかりません。 ユーザー定義関数のFunctionと上記のものでは別物なのでしょうか? ちょっと曖昧な質問で申し訳ないのですが どなたが是非よろしくお願いします。。。

    • ベストアンサー
    • Flash