• ベストアンサー

当たり判定で一度だけ音をならすには

当たり判定で、下記の様に書きました。 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
  • 回答数2
  • ありがとう数3

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

  • ベストアンサー
noname#35109
noname#35109
回答No.2

イベント(アクション)の発生が, > ドラッグ&ドロップで青ボールに重ねると なのですから, そもそも onEnterFrame をトリガ(引き金(この場合は監視の役目も含む))とすることが変だと思いますよ。 もっと素直に,そのまま, 「ドラッグ& "ドロップ" で青ボールに重ねると」→「音を鳴らす」 の方が,onEnterFrame で無駄な CPU を毎フレーム使い続けるより,ずっと良いと思います。 つまり,こういうことです↓。 --------------------------------------- Hsound01 = new Sound(_root.I_blue); Hsound01.attachSound("HS_sound01"); // I_green.onPress = function() { startDrag(this); }; // I_green.onRelease = function() { // 青が これ(緑)にヒットしたら if (_root.I_blue.hitTest(this)) { _root.Hsound01.start(0, 1); } stopDrag(); }; --------------------------------------- ※if (_root.I_blue.hitTest(this))   は,   if (.this.hitTest(_root.I_blue))   の方が自然です。   一応,ご質問のスクリプトに書かれている,   if (this.hitTest(_root.I_green))   を尊重して,あえて逆にしています。 > 当たり判定で一度だけ音をならすには… この「一度だけ」の意味が, 「一回目のドラッグ&ドロップで青ボールに重ねたときに鳴らすだけで,二回目以降は鳴らさない」 という意味でしたら,#1の方の書かれている フラグを使う方法が良いと思います。 --------------------------------------- Hsound01 = new Sound(_root.I_blue); Hsound01.attachSound("HS_sound01"); // 勝手に決めた変数 flag に 0 を代入 flag = 0; // I_green.onPress = function() { startDrag(this); }; // I_green.onRelease = function() { // 青が これ(緑)にヒットして なおかつ flag が 0 のとき if (_root.I_blue.hitTest(this) && flag == 0) { _root.Hsound01.start(0, 1); flag = 1; } stopDrag(); }; --------------------------------------- onEnterFrame や onClipEvent (enterFrame) は, 毎フレーム毎フレーム同じ処理を繰りかえし実行します。 hitTest などの説明するためにはこれらを使うことも良い方法ですが, 実際にご質問にあるような内容のときには極力使わないようにしましょう。

goo2408
質問者

お礼

sassakunさん、書き込みありがとうございます。 うっかりしていました(汗)。そうですね。ご紹介のかたちの方がシンプルで明快ですね。しかも負荷も軽い。D&Dではこちらを使うべきなのですね。実はD&Dの場合と 動いているMCの場合の 二つがでてくるものをつくっていまして、使い分けが必要なのですね。 sassakunさんの書き込みから、より深く理解できた気がします。 大変勉強になりました。 書き込みいただきありがとうございました。

その他の回答 (1)

回答No.1

onEnterFrame の処理は毎フレームで呼ばれてしまいます。 このコードだと重なっている間(hitTestがtrueの間)ずっと 音の再生が呼び出されます。 簡単にやるなら、何か適当なフラグを用意して --------------------------------------------------------- // 初回フラグ。trueで初期化しておく var bFirst:Boolean = true; _root.I_blue.onEnterFrame = function() { if (this.hitTest(_root.I_green)) { // 重なっているとき if(bFirst) { // はじめて重なったとき _root.Hsound01.start(0, 1); bFirst = false; } } else { // 重なっていないとき // フラグを戻す。 // 次に重なったときにまた音が再生される bFirst = true; } }; --------------------------------------------------------- な感じでいけるかと思います。 実際にこのコード動かしてないんであまり自信ないです...(^^;

goo2408
質問者

お礼

horsewaterさん、書き込みありがとうございます。 ご紹介のかたちでできる様になりました。 変数を使用してみて、試してはいたのですが、上手くできずにいたのですが、ご紹介の方法で「なるほど」という感じでできました。 大変たすかりました。 書き込みありがとうございました。

関連するQ&A

  • ActionScriptで対象外の音まで止まる・・・。

    フレームに以下のような記述をしたのですが動作が変です。初期段階で「oto1」が鳴っており、インスタンス「b1」をクリックで止まります。これは想定どおりの動作なのですが、「b2」をクリックしても止まるのです。これは理解できません。 何が誤りなのか教えていただけませんでしょうか? よろしくお願いいたします。 (インスタンス名は正しくつけています) oto1 = new Sound(); oto2 = new Sound(); _root.oto1.attachSound("s1"); _root.oto2.attachSound("s2"); _root.oto1.start(0, 99); this.b1.onRelease = function(){ _root.oto1.stop(); }; this.b2.onRelease = function(){ _root.oto2.stop(); };

    • ベストアンサー
    • Flash
  • シューティングゲームの自機の当り判定

    以前の質問で、アクションスクリプトの記述がなかったので、詳しく説明します。http://oshiete1.goo.ne.jp/qa3535566.html 自機は、キーボードで操作します。 if(Key.isDown(87)){ gotoAndPlay(3) } if(Key.isDown(83)){ gotoAndPlay(5) } 3は上向きグラフィック、5は下向きグラフィックです。 246フレームには、 gotoandplay(1) と記述しています。 当たり判定は、別レイヤーにあります。 ステージ上の自機にmyshipというインスタンス名を付けています。 敵弾に当たると自機はbangjikiになります。 if(this.hitTest(_root.myship.hitarea)){ _root.myship.gotoAndPlay("bangjiki") _parent.removeMovieClip() }

  • 右回り、左回りの判定

    ムービークリップをドラッグし、右回転させている間はAの処理、左回転させている間はBの処理という判定の仕方がわからなくて困っています。 イメージとしてはターンテーブルのようなものです。 現在はムービークリップをドラッグし、右・左回転させるところまでは出来ています。 何かヒント・考え方で結構ですので、ご教授頂けないでしょうか。 下記に現在記述しているスクリプトを記載します。 root階層にインスタンス名"handle"というムービークリップを配置し、Iフレーム目に下記のスクリプトを記述。 handle.onPress = function():Void { if (this.hitTest(_root._xmouse, _root._ymouse, true)) { this.flag = true; } }; handle.onMouseMove = function():Void { if (this.flag == true) { xp = _root._xmouse-this._x; yp = _root._ymouse-this._y; rad = Math.atan2(yp, xp); degree = rad*(180/Math.PI); this._rotation = degree; } }; handle.onMouseUp = function():Void { this.flag = false; }; 宜しくお願いします。

    • ベストアンサー
    • Flash
  • 2つの音のボリューム制御

    質問させてください。 Flashで2つの音を鳴らしたいと考えています。 一つはタイムラインにおいて、画面と同期させて います。二つ目は常に鳴るようにサウンドオブジェクト で鳴らしています。 問題は、setVolumeで音のボリュームを制御したいの ですが、下記のように2つのサウンドオブジェクトを 作成しても、最後に設定したsetVolumeに2つの音が ボリューム指定されてしまって、別々にボリューム 制御ができません。 (下記のように、タイムラインの音は30、スクリプト 制御の音は80で設定したい。) ●タイムラインの1フレーム目のフレームアクション _root.snd = new Sound(); _root.bgmsnd = new Sound(); //タイムライン用のボリューム指定 _root.snd.attachSound("menu1"); _root.snd.setVolume(30); //スクリプト制御用のボリューム指定 _root.bgmsnd.attachSound("bgm"); _root.bgmsnd.setVolume(80); _root.bgmsnd.start(0,99999); 解決方法、おわかりの方おられますでしょうか? Flash MX 2004 Windows XP

    • ベストアンサー
    • Flash
  • 音のアクションスクリプトについて

    ActionScriptを使った音のスクリプトについて勉強しています。ステージ上に二つの音楽プレーヤーを設置し音楽を流す、という事からはじめてみたのですが、上手く行かずに困っています。 設置した音量+/-ボタンを押すと両方の音量が変わってしまったり、片側を再生している状態で、もう一方を再生すると、もう一方は停止してしまったり(目的的には困らないのですが、本来両方とも再生され音がでているのが本来の姿のようなので)、といった状態です。 何かを間違えた理解と書き方をしていると思うのですが、間違いの指摘や音のアクションスクリプトの書き方についてご教授いただければと思い、質問させていただきました。 複数音楽プレイヤーを設置 という事がしたい場合のアドバイスやご教授をいただきたく思います。 よろしくお願いします。 ステージ  MC01(インスタンス名、I_MC01)   L__MC再生ボタン(インスタンス名、I_saisei)   L__MC音量+ボタン   L__MC再生-ボタン  MC02(インスタンス名、I_MC02)   L__MC再生ボタン(インスタンス名、I_saisei)   L__MC音量+ボタン   L__MC再生-ボタン と二つのシンボルがステージ上に配置し、各MCに再生ボタンと音量+/-ボタンを配置しています。 MC01 onClipEvent (load) {    Hsound_MC01 = new Sound(I_MC01);    Hsound_MC01.attachSound("RS_MC01"); } MC再生ボタン onClipEvent (load) {    Hvol= 50; } on (release) {    _root.I_MC01.Hsound_MC01.stop();    _root.I_MC01.Hsound_MC01.start(); } onClipEvent (enterFrame) {    _root.I_MC01.Hsound_MC01.setVolume(this.Hvol); } MC音量+ボタンon (release) {    if (_root.I_MC01.I_saisei.Hvol<100) {       _root.I_MC01.I_saisei.Hvol += 10; } } と書きました。MC02も同じで、01と02が違うだけです。

    • ベストアンサー
    • Flash
  • 音声の出だしの音量だけがsetVolumeで制御が利かない。

    SoundオブジェクトのattachSoundを利用して、フレームに音声を割り当て、再生しているのですが、 最初の出だし部分の音だけが、setVolumeで設定した音量を無視して、ライブラリに取り込んだままの音声で再生されてしまいます。 その後は、setVolumeで設定した音量にすぐにもどります。 自分的には、インスタンス化したSoundがsetVolumeで制御されるよりも先に再生されてしまう為、出だし部分だけ音量制御が利かないのでは? と思うのですが、良い解決方法がみつからず、悩んでおります。 コードは下記のようにしてます。 bgSound = new Sound(this); bgSound.attachSound("sound1"); bgSound.start(0, 1); slider.slideBar._y = -30; slider.slideBar.onEnterFrame = function() {     bgSound.setVolume(0-this._y); } slider.slideBar.onEnterFrame = function() { bgSound.setVolume(0-this._y); _global.vol = this._y }; slider.slideBar.onPress = function() { startDrag(this, false, this._x, -60, this._x, -0); }; slider.slideBar.onRelease = slider.slideBar.onReleaseOutside=function () { stopDrag(); }; 宜しくお願いします。

    • ベストアンサー
    • Flash
  • flashの音再生について

    main.swfにactionscript2.0で音のon/offしているのですが、 offになって欲しくない音までoffになってしまいます。 スクリプトで呼び出している音ならばまだわかるのですが、 flvで外部から読み込み再生しているファイルなので、 訳が分からず困っています。 ちなみに音再生スクリプトはフレーム上に以下 //BGM制御用のダミーのムービークリップを作る this.createEmptyMovieClip( "bgm_clip" , 0 ); //BGMの設定 sndbgm = new Sound( bgm_clip ); sndbgm.attachSound( "BGM01" ); sndbgm.setVolume( 100 ); sndbgm.onSoundComplete = function() { //無限ループ再生 sndbgm.start(); }; //BGMを再生 sndbgm.start(); //BGMのボリュームとフェードの速さを管理する変数 bgm_vol = 100; fade_spd = 5; //SE設定 allse = new Sound(); allse.setVolume( 100 ); S1 = new Sound(this); S1.attachSound("SE01"); S2 = new Sound(this); S2.attachSound("SE02"); S3 = new Sound(this); S3.attachSound("SE03"); on/offにはMCで以下の様にしています。 on (release) { if (this._parent.sndbgm.getVolume()>0) { this._parent.sndbgm.setVolume(0); this._parent.allse.setVolume(0); this._parent.v_on_off.gotoAndStop("soundOFF"); } else if (this._parent.sndbgm.getVolume()<=0) { this._parent.sndbgm.setVolume(100); this._parent.allse.setVolume(100); this._parent.v_on_off.gotoAndStop("soundON"); } } SE再生にはフレーム上に S1.start(); と入れています。 使用バージョンはCS4になります。 どなたか判る方、教えて下さい。

    • ベストアンサー
    • Flash
  • Java ブロック崩し 当たり判定

    こんにちは、Java初心者の者です。 今週の末に、文化祭があるので、その際の出し物で「ブロック崩し」を出すことにしたのですが、 ブロックの当たり判定がおかしいのです。 おかしいというか、正確にはブロックとの当たり判定自体はあるのですが、ブロックと当たったらブロックが消えるようにしているはずが、消えないのです。 一応、消えてはくれるのですがボールとブロックが離れたらまた元の色に戻ってしまいます。 フラグ管理を使っての処理で、ボールとブロックが触れたらフラグを「偽」。そしたらそれに該当するブロックを描画しないようにする仕組みなのですが、どうも上手くいきません。 以下コードです。 ~~~~中略~~~~ //ブロックの座標の設定 int k=0; for(int j=0;j<block_r;j++) { for(int i=0;i<block_g;i++) { block_x[k] = i*block_w; block_y[k] = j*block_h; block[k] = 1; flag[k] = true; k++; } } //ブロックに当たった時の処理 for(int i=0;i<30;i++) { if(flag[i] == true) { if(y + ball_y >= block_y[i] && y <= block_y[i]+block_h && x + ball_x >= block_x[i] && x <= block_x[i] + block_w) { vy = -vy; flag[i] = false; } } } //ブロックの描画 for(int i=0;i<30;i++) { if(flag[i] == true ) { //ブロックの描画 offg.setColor(Color.yellow); offg.fillRect(block_x[i],block_y[i],block_w,block_h); //ブロックの枠線 offg.setColor(Color.black); offg.drawRect(block_x[i],block_y[i],block_w,block_h); } } ~~~~中略~~~~~ paintメソッドの部分だけ載せてます。 どこかおかしいところがあれば、アドバイスを頂ければ幸いです。 宜しくお願い致します。

    • ベストアンサー
    • Java
  • FlashでXMLを読み込んだ際の関数について

    XMLでデータを読み込んで表示させているボタンがあり、 そちらを制御するための関数を作りたいのですがうまくいきません。 btn0.onRelease = function() { _root.sound_mc.songStarter(songfile[0], songname[0]); }; btn1.onRelease = function() { _root.sound_mc.songStarter(songfile[1], songname[1]); }; btn2.onRelease = function() { _root.sound_mc.songStarter(songfile[2], songname[2]); }; とある中身を簡単に書きたくて、 for(var i=0; i<=2; i++) { var btn = this["btn" + i ]; btn.onRelease = function() { _root.sound_mc.songStarter(songfile[i], songname[i]); }; } と記述してみましたが、動きません。 正しい書き方をどなたかご教授ください。 よろしくお願いいたします。

    • ベストアンサー
    • Flash
  • 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

専門家に質問してみよう