Flash AS3 減速運動の不具合の回避方法を教えて下さい

このQ&Aのポイント
  • Flash CS3で作成したAS3のアニメーションで減速運動の不具合が発生しました。センセーショナルなタイトルは「Flash AS3 減速運動の不具合の回避方法はこれだ!」です。
  • 質問者はFlash CS3のAS3を使って、EaseingSimpleクラスを拡張して任意のボタンを押すと指定の座標に減速しながら移動するクラスを作成しました。しかし、複数のボタンが設置されている場合に移動中に別のボタンを押すと意図しない座標に止まってしまうという不具合が発生しています。
  • 質問者は移動先の座標をすぐに変更する動作を付けたいと考えています。具体的な実装としては、ボタンを押すイベント発生時に移動先の座標を変更し、インスタンスが減速しながら移動するようにしたいとしています。しかし、具体的な方法が分からず困っているようです。どのように実装すればよいでしょうか?
回答を見る
  • ベストアンサー

Flash AS3 減速運動の不具合の回避方法を教えて下さい

大重美幸様のAS3.0入門ノートを使って勉強しているものです。 今回その中の「EaseingSimpleクラス」を拡張して、 任意のボタンを押すと、予めそのボタンに引数として登録しておいたステージ上のX座標、Y座標にインスタンスが減速しながら移動するクラスを作ってみました。 そこで問題発生なのですが、 ステージにボタンを二つ以上設置(仮にAとBとします)して、 「Aのボタン」をマウスダウンしてインスタンス(IdoObjとします)の移動開始して、それが指定の座標に到達する前(移動中)に「Bのボタン」を押すと意図しない座標にインスタンスが止まってしまいます。 確実に、インスタンスが静止して、次のボタンを押せば問題は起きないのですが、移動先をすぐに変更させる動きを付けるにどうしたらよいのでしょうか? よろしくお願いいたします。 タイムラインのフレームアクション idoObj→移動するインスタンス btA→ボタンA 100,100→btAが渡すX座標,btAが渡すY座標 btB→ボタンB 200,200→btBが渡すX座標,btBが渡すY座標 ********************************************************** var btObj:idoStage=new idoStage(idoObj,btA,100,100); var btObj2:idoStage=new idoStage(idoObj,btB,200,200); ********************************************************** 今回作製したidoStageクラス(下記のEaseingSimpleクラスを拡張) ********************************************************** package{ import flash.display.MovieClip; import flash.events.MouseEvent; import EaseingSimple; public class idoStage extends EaseingSimple{ var my_mc2:MovieClip;//任意のボタン var zahyoX:Number;//x座標 var zahyoY:Number;//y座標 //コンストラクタ function idoStage(mc:MovieClip,mc2:MovieClip,stgX:Number,stgY:Number){ super(mc); my_mc2=mc2; zahyoX=stgX; zahyoY=stgY; my_mc2.addEventListener(MouseEvent.MOUSE_OUT,onOUT); my_mc2.addEventListener(MouseEvent.MOUSE_OVER,onOVER); my_mc2.addEventListener(MouseEvent.CLICK,onCLICK); } public function onOUT(event:MouseEvent):void{ my_mc.stop(); my_mc2.buttonMode=false; my_mc2.alpha=1; } public function onOVER(event:MouseEvent):void{ my_mc2.buttonMode=true; my_mc2.alpha=0.5; } //引数で受け取った座標を「EaseingSimpleクラスのeaseTo」に渡してイーズする public function onCLICK(event:MouseEvent):void{ easeTo(zahyoX,zahyoY); my_mc2.buttonMode=true; my_mc2.alpha=0.3; } } } ********************************************************** EaseingSimpleクラス (ステージをクリックするとその位置にインスタンスが減速しながら移動します。) ********************************************************** package { import flash.display.MovieClip; import flash.geom.Point; import flash.events.Event; public class EaseingSimple { var my_mc:MovieClip; var endPoint:Point; //コンストラクタ function EaseingSimple(mc:MovieClip) { my_mc = mc; } //イーズ開始 public function easeTo(end_x:Number, end_y:Number):void { endPoint = new Point(end_x, end_y); my_mc.addEventListener(Event.ENTER_FRAME, easeStep); } //繰り返しステップ private function easeStep(event:Event):void { var mcPoint:Point = new Point(my_mc.x, my_mc.y); //2点間の距離 var distance:Number = Point.distance(mcPoint, endPoint); if (distance>1) { var tmpPoint:Point = getTmpPoint(); my_mc.x = tmpPoint.x; my_mc.y = tmpPoint.y; } else { my_mc.x = endPoint.x; my_mc.y = endPoint.y; my_mc.removeEventListener(Event.ENTER_FRAME, easeStep); } } //座標計算 private function getTmpPoint():Point { var tmpX:Number = my_mc.x + (endPoint.x - my_mc.x) * 0.3; var tmpY:Number = my_mc.y + (endPoint.y - my_mc.y) * 0.3; var tmpPoint:Point = new Point(tmpX,tmpY); return tmpPoint; } //イーズ中断 public function stop():void { my_mc.removeEventListener(Event.ENTER_FRAME, easeStep); } } } ********************************************************** 製作環境 FlashCS3

  • Flash
  • 回答数1
  • ありがとう数1

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

  • ベストアンサー
  • chika_008
  • ベストアンサー率80% (20/25)
回答No.1

まず、考えられる原因としてeventListener(Event.ENTER_FRAME, function); がしっかり止められてませんね。 //イーズ中断 public function stop():void { my_mc.removeEventListener(Event.ENTER_FRAME, easeStep); } 上記関数ですが、stop()という名前はあまりこのましくありません。 play(),stop()と勘違いしてしまう恐れがあります。ですので stopEnterFrameとかremoveListenerとかなんでもよいと思うのでつけてあげてください。そして、 public function onCLICK(event:MouseEvent):void{ my_mc.removeEnterFrame(); //クリックされたら現在動いているenterFrameを消す関数を実行。 easeTo(zahyoX,zahyoY); my_mc2.buttonMode=true; my_mc2.alpha=0.3; } 上記のようにonCLICKの所にもさきほど名前をremoveEnterFrameと名前を変えて上げた関数を記述。しっかりとクリックされた時もenterFrameをとめてあげてください。 これでどうでしょうか? たしかめてくださいませ。

hidex2009
質問者

お礼

>chika_008様 早々のご回答ありがとうございます。 早速、試してみたいと思います。 追記:すみません訂正箇所がありました。 ********************************************** ・・・ ・・・ public function onOUT(event:MouseEvent):void{ my_mc.stop();//←不要な一行でした。 my_mc2.buttonMode=false; my_mc2.alpha=1; } ・・・ ・・・ **********************************************

hidex2009
質問者

補足

>chika_008様 EaseingSimpleクラス ********************************************************** 中略 //イーズ中断 public function removeEnterFrame():void { my_mc.removeEventListener(Event.ENTER_FRAME, easeStep); } ********************************************************** idoStageクラス(EaseingSimpleクラスを拡張) ********************************************************** //引数で受け取った座標を「EaseingSimpleクラスのeaseTo」に渡してイーズする public function onCLICK(event:MouseEvent):void{ my_mc.removeEnterFrame(); easeTo(zahyoX,zahyoY); my_mc2.buttonMode=true; my_mc2.alpha=0.3; } ********************************************************** と修正してみたのですが、 ********************************************************** TypeError: Error #1006: removeEnterFrame は関数ではありません。 at idoStage/onCLICK() ********************************************************** が出てしまいます。いろいろとやってみたのですが…。 度々すみません、お力添えをお願いします。

関連するQ&A

  • Actionscript3.0のクラス定義の仕方

    ActionScript3.0のクラス定義について質問なのですが、回転するインスタンスがあり(それは最初からステージに置いてあります)、それがマウスが近づくにつれてだんだん回転が速くなるのを作りたいのですがなかなかうまくいきません。 クラス定義をせずに書いた場合ですとうまくいきましたが、それを外部ファイルにカスタムクラス(と言うんでしょうか?)をした場合、やり方がいまいち理解できずにうまくいかないんです。 クラス定義せずに書いたのはこちらです↓ addEventListener(Event.ENTER_FRAME, onEnterframe); function onEnterframe(eventObj:Event):void { //インスタンスの座標 var hanePt:Point=new Point(hane_mc.x,hane_mc.y); //マウスの座標 var mousePt:Point=new Point(stage.mouseX,stage.mouseY); //インスタンスとマウスの距離 var distance:Number=Point.distance(hanePt,mousePt); //距離が200以下の時に回転する if(distance<200){ hane_mc.rotation+=2000/Math.max(50,distance); } これですとちゃんと動きました。 そしてクラス定義にしたのがこちらです↓ メインのタイムラインのところにはこちらを書いて↓ var mousePt:Point=new Point(stage.mouseX,stage.mouseY); var haneobj1:Hane = new Hane(hane_mc); haneobj1.moveHane(mousePt); 外部ファイルにはこちらを書きました↓ package{ import flash.display.MovieClip; import flash.events.Event; import flash.geom.Point; public class Hane extends MovieClip{ //インスタンスのプロパティ var hane_mc:MovieClip; var ballPt:Point; var distance:Number; public function Hane(hane:MovieClip){ hane_mc = hane; ballPt = new Point(hane_mc.x,hane_mc.y); } public function moveHane(mou:Point):void{ distance = Point.distance(ballPt,mou); addEventListener(Event.ENTER_FRAME, kaitenHandler); } public function kaitenHandler(ev:Event):void{ //距離が200以下の時に回転する if(distance<200){ hane_mc.rotation+=2000/Math.max(50,distance); } } } } とくにエラーは出ないのですが、動くときと動かないときがあります。 動いたとしても一定の動きで、マウスが近づいてもとくに回転速度は変わりません。 どこか間違っているところあればご教授してください!! よろしくお願いします!!!

    • ベストアンサー
    • Flash
  • as3 addEventListenerの動的な生成について

    addEventListenerを動的に生成したいのですが、 下記のコードは動いてくれません。(エラーはないです。) //2つのインスタンスは適当な座標においてあります for(var num=0; num < 2; num++){ var mc = "test"+num+"_mc"; mc = new MovieClip(); mc.addEventListener(MouseEvent.CLICK, move); } function move(event:Event):void{ event.currentTarget.x = 0; } 上記のような場合は、 どのようにすればよいのでしょうか。 ご教授お願いいたします。

    • ベストアンサー
    • Flash
  • 外部ASを二つ組み合わせる方法

    flash初心者です。二つのASファイルを組み合わせて作ろうとしているのですが、 外部ASをドキュメントクラスを使用して読み込み複数ある場合、調べた結果importを利用してクラスを定義出来るとの事ですが、定義が重複していますと出てしまいます。 パッケージを二個書こうとしても外部から表示可能な複数の定義は使用出来ませんと出てしまいます。二つのスクリプトを一つに纏めた方がいいのでしょうか? どなたかご教授下さい。 ASは同じディレクトリ上に配置しています。 package { import flash.display.Sprite; import flash.display.MovieClip; import flash.events.MouseEvent; import flash.events.Event; public class CardMenu extends Sprite { private var cardList:Array = ["card01", "card02", "card03", "card04", "card05"]; private var _currentCard:MovieClip; public function CardMenu() { for ( var i:int = 0; i < cardList.length; i++ ) { var mc:MovieClip = this[cardList[i]]; mc.X = mc.x0 = mc.x; mc.Y = mc.y0 = mc.y; mc.R = mc.rot = mc.rotation; mc.S = mc.sca = mc.scaleX; mc.dep = getChildIndex(mc); mc.btn.addEventListener(MouseEvent.CLICK, openHandler); mc.addEventListener(Event.ENTER_FRAME, enterFrameHandler); } } private function openHandler( e:MouseEvent ):void { if (Boolean(_currentCard)) { _currentCard.X = _currentCard.x0; _currentCard.Y = _currentCard.y0; _currentCard.R = _currentCard.rot; _currentCard.S = _currentCard.sca; setChildIndex(_currentCard, _currentCard.dep); _currentCard.btn.visible = true; } _currentCard = e.target.parent as MovieClip; _currentCard.X = stage.stageWidth / 2; _currentCard.Y = stage.stageHeight / 2; _currentCard.R = 0; _currentCard.S = 1; setChildIndex(_currentCard, numChildren - 1); _currentCard.btn.visible = false; } private function enterFrameHandler( e:Event ):void { var card:MovieClip = e.target as MovieClip; card.x += ( card.X - card.x ) * 0.2; card.y += ( card.Y - card.y ) * 0.2; card.rotation += ( card.R - card.rotation ) * 0.2; card.scaleX += ( card.S - card.scaleX ) * 0.2; card.scaleY = card.scaleX; } } } package { import flash.display.Sprite; import box; public class box extends Sprite { public function Main() { var box:box = new box(); } } }

  • Flash(ActionScript3.0)

    Flash(ActionScript3.0)でゲーム制作を行っています。 ActionScriptもFlashも最近初めて触れた初心者で、分からないことがたくさん湧いてきて困っています。 よろしければご回答お願い致します。 インスタンスをドラッグすることができる、という要素と、 インスタンスをクリックすると45度回転する、という要素を同時に入れたいのですが、 同時にプログラムを組むとドラッグだけをすることができず、 どうしてもドラッグ後に45度回転してしまいます。 (プログラムのソースはネットから拾ってきたものです)。 どうすればドラッグと回転を分けることができるのでしょうか。 プログラム自体は以下のように組みました。 ご回答いただければ嬉しいです。 よろしくお願い致します。 //インスタンスの回転プログラム mc1.addEventListener(MouseEvent.CLICK, kaiten); function kaiten(event:MouseEvent) { mc1.rotation += 45; } //インスタンスのドラッグプログラム //インスタンスの0点からのマウス座標用変数 var mc1X:int; var mc1Y:int; //マウスがインスタンスを押したらsec1開始 mc1.addEventListener(MouseEvent.MOUSE_DOWN,sec1); //sec1 マウスダウン座標確認、sec2開始 function sec1(event:MouseEvent):void { mc1X = event.localX; mc1Y = event.localY; addEventListener(MouseEvent.MOUSE_MOVE,sec2); } //sec2 インスタンス移動 function sec2(event):void { mc1.x = mouseX-mc1X; mc1.y = mouseY-mc1Y; //低FPSマウス移動スムーズ対応 event.updateAfterEvent(); } //マウスが離れたらsec3開始 stage.addEventListener(MouseEvent.MOUSE_UP,sec3); mc1.addEventListener(MouseEvent.MOUSE_OUT,sec3); //sec3 sec2停止 function sec3(event):void { removeEventListener(MouseEvent.MOUSE_MOVE,sec2); }

  • addChildの使い方

    ロールオーバーで下の画像を表示させる:を参考にしています。 http://okwave.jp/qa/q7020788.html ここはアクションスクリプト2.0でしたが、私はFLASH CS3 アクションスクリプト3.0で 作っています。 その回答をもとに100X100のロールオーバー用の画像を16個表示させるために 書きました。ステージは400x400です。 for (var i:Number = 0; i<=15; i++) { if (i != 0) { var my_mc:MC = new MC(); my_mc.x = i%4*100; my_mc.y = Math.floor(i/4)*100; addChild(my_mc); } } 16個で埋め尽くすことはできましたが、my_mcに番号をつけるなどして配列を使って やらなければならないと考えますが方法がわかりません。今は16番目(iが15)しか ロールオーバーしません。 全体のアクションスクリプトを書きます。 import fl.transitions.*; import fl.transitions.easing.*; for (var i:Number = 0; i<=15; i++) { if (i != 0) { var my_mc:MC = new MC(); my_mc.x = i%4*100; my_mc.y = Math.floor(i/4)*100; addChild(my_mc); } } my_mc.addEventListener(MouseEvent.ROLL_OVER,onrollOver); function onrollOver(eventObj:Event):void { //ロールオーバーイベントを受けたインスタンスを取得 var target_mc:MovieClip = MovieClip(eventObj.currentTarget); //そのインスタンスをフェードアウト TransitionManager.start(target_mc, {type:Fade, direction:Transition.OUT, duration:2, easing:None.easeNone}); //そのインスタンスのイベントリスナーを削除 target_mc.removeEventListener(MouseEvent.ROLL_OVER,onrollOver); }

    • ベストアンサー
    • Flash
  • マウスアウトで非表示にする

    シーン1に、mc(ムービークリップ)とcomment1(ムービークリップ)を配置 mcにマウスオーバーするとcomment1が表示される。 mcよりマウスアウトするとcommen1が非表示になる。 という感じにしたいのですが、マウスアウトしても非表示に出来ないで困っています。 //----------------------------------- MovieClip(root).comment1.visible = false; var pointX:Number=70; var pointY:Number=50; mc.addEventListener(MouseEvent.MOUSE_OVER, fl_MouseOver); function fl_MouseOver(event:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveFunc); function mouseMoveFunc(e:MouseEvent):void { MovieClip(root).comment1.visible = true; MovieClip(root).comment1.x=stage.mouseX+pointX; MovieClip(root).comment1.y=stage.mouseY+pointY; } } mc.addEventListener(MouseEvent.MOUSE_OUT, fl_MouseOver2); function fl_MouseOver2(event:MouseEvent):void { mc.removeEventListener(MouseEvent.MOUSE_OVER, fl_MouseOver); MovieClip(root).comment1.visible = false; } //-----------------------------------

    • ベストアンサー
    • Flash
  • as3でボタンにリンクをはる方法!

    質問ばかりで申し訳ないですが、お世話になります。 flashCS4&Actionscript3を使っているものです。 「ボタンにリンクをはる方法を探しています。 (どうしても 1093のシンタックスエラーになってしまい、困っています。)」 現在作成しているものは、以下のような構造です。 ************************************************************* ステージ ↓ムービークリップ【インスタンス名(menu_mc)】 ________________________________________ ・ボタン【インスタンス名(btn1_btn)】 ・ボタン【インスタンス名(btn2_btn)】 ・ボタン【インスタンス名(btn3_btn)】 ________________________________________ *************************************************** menu_mcの中で、以下のように記述しました。 btn1_btn.addEventListener(MouseEvent.CLICK,gotowebpage1); function gotowebpage1(event : MouseEvent) :void { navigateToURL(new URLRequest("​http://www.yahoo.co.jp"));​ } btn2_btn.addEventListener(MouseEvent.CLICK,gotowebpage2); function gotowebpage2(event : MouseEvent) :void { navigateToURL(new URLRequest("​http://www.yahoo.co.jp"));​ } btn3_btn.addEventListener(MouseEvent.CLICK,gotowebpage3); function gotowebpage3(event : MouseEvent) :void { navigateToURL(new URLRequest("http://www.yahoo.co.jp")); } すると、1093のシンタックスエラーになってしまいます。 うまく動作させる為には、他にどんな作業を行ったらいいのでしょうか、 よろしくお願いします!!!

    • ベストアンサー
    • Flash
  • as3 getChildByNameに変数を利用する

    ※実際にやりたいことは違うのですが、 分かりやすくするため簡易的にしています。 ステージに配置された2つのインスタンスを y=300に移動するというものを作りたいと思っています。 (実際には100以上になるので動的に生成したいです。) var num:int = 2; var _mc:Array = []; var _mcName:Array = []; for(var i=0; i < num; i++){ _mc.push("test_mc"+i); _mcName.push("test_mc"+i); } for(var n=0; n < num; n++){ _mc[n] = new MovieClip; _mc[n].addEventListener(Event.ENTER_FRAME, function() { MovieClip(getChildByName(_mcName[n])).y = 300; }); } 上記を実行すると下記のエラーが出ます。 TypeError: Error #2007: パラメータ name は null 以外でなければなりません。 at flash.display::DisplayObjectContainer/getChildByName() at MethodInfo-1() 下記のように並べて記述するとうまくいくのですが・・・・ これを100個以上も書くのはばかばかしいので。。。 _mc[0] = new MovieClip; _mc[0」.addEventListener(Event.ENTER_FRAME, function() { MovieClip(getChildByName(_mcName[0])).y = 300; }); _mc[1] = new MovieClip; _mc[1」.addEventListener(Event.ENTER_FRAME, function() { MovieClip(getChildByName(_mcName[1])).y = 300; }); ご教授お願いいたします!

    • ベストアンサー
    • Flash
  • AS3でステージのサイズ変えた時にムービークリップが減速して中央に移動

    AS3でステージのサイズ変えた時にムービークリップが減速して中央に移動するFlashの作り方で悩んでいます。 参考にしてるものはこれなんですが↓ http://hfm-kenchan.com/Lesson/sample/centermovie11/top.htm これをActionScript3で作ろうと今現在このようにコーディングをしています。 ※my_mc:ステージ中央にあるムービークリップ stage.align=StageAlign.TOP_LEFT; stage.scaleMode=StageScaleMode.NO_SCALE; stage.addEventListener(Event.RESIZE, resize_control); function resize_control(eventObject:Event):void { my_mc.x = (stage.stageWidth - my_mc.width)/2; my_mc.y = (stage.stageHeight - my_mc.height)/2; const spd:Number=1/5; my_mc.addEventListener(Event.ENTER_FRAME, center_movie); function center_movie(event:Event):void { my_mc.x += ((stage.stageWidth - my_mc.width)/2 - my_mc.x)*spd; my_mc.y += ((stage.stageHeight - my_mc.height)/2 - my_mc.y)*spd; } } 現在はリサイズするとmy_mcはステージ中央にいるのですが参考にしてるものみたいに減速して中央に移動するというものが作れません。 どうしたらいいのかどなたかアドバイスしていただけませんか? よろしくお願いします。

    • ベストアンサー
    • Flash
  • for文を使ったボタン

    for文を使ったボタン ボタンが2つあり、そのボタンをロールオーバー、ロールアウトでそれぞれ違うmcを動かしたいのですが、うまくいきません。ボタンを「maru1、maru2」として動かしたいmcを「btn1、btn2」とインスタンス名をつけて以下のスクリプトを書きました。 maru1.addEventListener(MouseEvent.ROLL_OVER,onMouse1); maru1.addEventListener(MouseEvent.ROLL_OUT,outMouse1); maru1.buttonMode = true; maru2.addEventListener(MouseEvent.ROLL_OVER,onMouse2); maru2.addEventListener(MouseEvent.ROLL_OUT,outMouse2); maru2.buttonMode = true; function onMouse1(e:MouseEvent):void{ mc_tween = new Tween(btn1, "scaleX", Elastic.easeOut, 0.7, 1, 1, true); mc_tween.start(); } function outMouse1(e:MouseEvent):void{ mc_tween = new Tween(btn1, "scaleX", Elastic.easeOut, 1, 0.7, 1, true); mc_tween.start(); } function onMouse2(e:MouseEvent):void{ mc_tween = new Tween(btn2, "scaleX", Elastic.easeOut, 0.7, 1, 1, true); mc_tween.start(); } function outMouse2(e:MouseEvent):void{ mc_tween = new Tween(btn2, "scaleX", Elastic.easeOut, 1, 0.7, 1, true); mc_tween.start(); } これでも動くのですが、ボタンが沢山あった場合にfor文を使ってできないかと考え、ttp://www.oro.co.jp/web/creator/flash/actionscript/soft-button.htmlを参考に var mc_tween:Tween; //イベント登録 for(var i:int = 1; i < 3; i++){ this["maru"+i].addEventListener(MouseEvent.ROLL_OVER, rollOverEvent); this["maru"+i].addEventListener(MouseEvent.ROLL_OUT, rollOutEvent); this["maru"+i].buttonMode = true; } function rollOverEvent(event:Event):void{ var btn:MovieClip = event.target as MovieClip; mc_tween = new Tween(btn, "scaleX", Elastic.easeOut, btn.scaleX, 1.5, 1, true); mc_tween = new Tween(btn, "scaleY", Elastic.easeOut, btn.scaleY, 1.5, 1, true); addChildAt(btn, 5); } function rollOutEvent(event:Event):void{ var btn:MovieClip = event.target as MovieClip; mc_tween = new Tween(btn, "scaleX", Elastic.easeOut, btn.scaleX, 1, 1, true); mc_tween = new Tween(btn, "scaleY", Elastic.easeOut, btn.scaleY, 1, 1, true); } と書いたのですが、上手く行きません。<var btn:MovieClip = event.target as MovieClip;>の部分でどのように「btn1、btn2」を参照したらいいのでしょうか。 作業環境はmacOSX flashCS5 actionscript3です。よろしくお願い致します。

    • ベストアンサー
    • Flash