- ベストアンサー
ボタンを押すとMCが現在位置→特定の位置を通過→指定位置に移動
ボタンを押すと ムービークリップが 現在位置→特定の位置を通過→指定位置 に一定の速度で移動するものを作りたいのですが、 ボタンを押すとflagに変数1が入り、 1フレーム目 flagに変数1が入ったら enterFrameで特定位置まできたらhitTestで2フレーム目に 2フレーム目 enterFrameで指定位置まで移動後flagの変数0に戻す と、スクリプトを書くと ボタン1度目はうまくいくのですが 2度目から特定の位置を通過しないまま、 指定位置に進んでしまいます。 特定の位置を通過させるには どうしたらよいのでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
実際にどのようなスクリプトになっているのかを見ないことには、原因はよく分かりませんが。 通過地点と最終目的地にムービークリップを配置し、ボタンを押すと、通過地点を通り、指定位置に向かう・・・といったものであれば、アニメの段階(ステップ)を変数で管理することで、フレームを移動しなくても1フレームだけで作れます。 仮に、移動する”clip”、通過地点の目印である”target_point”、最終目的地点になる”goal”(この3つはムービークリップ)、移動アニメを開始するボタン”btn”が、全てステージに配置してあるとします。 スクリプトは次のように考えます。 ボタンがクリックされた時、フラグを立てて clip に移動の開始指令を出します。フラグ(仮に move_flg とします)は、clip の中で定義しておきます。 clip では、他にアニメのステップも変数で管理します。enterFrame イベントでこの変数を監視して switch 文で分岐し、移動のステップごとに違う処理を実行できるようにします。 アニメのステップを管理する変数は、次のように値を決めます。 0:移動指令が出るまで待機。指令が出たら、移動の初期化をして次に進む。 1: target_point の位置まで移動。目標に到達したら、次の移動の初期化をして先に進む。 2: goal の位置まで移動。目標に到達したら、待機に戻る。 連番になっていますから、1つのステップが終わった時に +1 してカウンタを進めておくと、次からは先のステップに進むようになります。 clip が移動中の時にボタンがクリックされても問題はありませんが、念のため、move_flg が false の時だけボタンを有効にするといった処理を加えておくといいでしょう。 移動指令を出せない条件の時はボタンを非表示にし、移動終了後に再び表示する、といった方法でもいいと思います。 --------------------------------------------- ところで、移動の処理ですが。 移動の計算には様々な方法がありますが、今回は、三角関数を使って clip と target_point および goal との位置から角度を出し、それを元に速度を決める方法をご紹介します。 詳しい原理は省略しますが、XおよびY方向の移動量は vx = 速度 × cosθ vy = 速度 × sinθ で求めることができます。 sin や cos を求めるには角度が必要です。ここでは、2つのムービークリップの座標から atan2 メソッドを利用して角度を求めます。 数学での sin や cos は角度(°)で計算しますが、Flash の sin や cos メソッドの引数は、角度をラジアンに直して渡さなければなりません。 しかし、atan2 メソッドの戻り値は最初からラジアンで返ってきますから、角度やラジアンに変換する計算は不要です。 sin ・ cos ・ atan の話は、Flash のテクニカルノートに説明が載っています。よろしければご参照ください。 ・角度と座標の計算 - Flash 5 の三角関数を使う http://www.macromedia.com/jp/support/flash/ts/documents/fl0189.html 2点の角度から移動量を決めるので、target_point や goal が clip から見てどの方向にある場合でも、正確にその方向に移動していくようになります。 移動速度は一定ですから、移動距離が長くなるほど、到達するまでに時間(フレーム数)はかかります。 スクリプトにしますと、大体、次のようになります。 (↓各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください。このまま使うとシンタックスエラーになります) ● clip に設定するスクリプト onClipEvent(load) { //移動フラグ //移動時true、それ以外はfalse move_flg = false; //アニメステップを管理するカウンタ //0:待機 1:目標地点まで移動 2:最終目標地点への移動 anime_step = 0; //速度を定義 spd = 20; /*座標からラジアンを求める関数*/ function Radian( x , y ) { //X・Yともに0の時、0を返す //それ以外の場合はアークタンジェントを返す if( x == 0 && y == 0 ) { return( 0 ); } else { return( Math.atan2( y , x ) ); } } } onClipEvent(enterFrame) { var rad , dist_x , dist_y , vx , vy; //アニメステップカウンタに従って行動 switch( anime_step ) { //移動開始指令が出るまで待機 case 0: if( move_flg ) { //目標地点との角度を算出 dist_x = _root.target_point._x - this._x; dist_y = _root.target_point._y - this._y; rad = Radian( dist_x , dist_y ); //移動量を決める vx = spd * Math.cos( rad ); vy = spd * Math.sin( rad ); //次のステップに進む anime_step++; } break; //目標地点まで移動 case 1: this._x += vx; this._y += vy; //目標地点に達したら、次の移動の初期化 if( this.hitTest( _root.target_point._x , _root.target_point._y , true ) ) { //最終目標地点との角度を算出 dist_x = _root.goal._x - this._x; dist_y = _root.goal._y - this._y; rad = Radian( dist_x , dist_y ); //移動量を決める vx = spd * Math.cos( rad ); vy = spd * Math.sin( rad ); //次のステップに進む anime_step++; } break; //最終目標地点まで移動 case 2: this._x += vx; this._y += vy; //目標地点に達したら終了 if( this.hitTest( _root.goal._x , _root.goal._y , true ) ) { //次の移動まで待機 move_flg = false; anime_step = 0; //ボタンを表示する _root.btn._visible = true; } break; default: break; } } ●btnに設定するスクリプト on(release) { //ムービークリップが移動中でなければ、移動開始 //移動中はボタンを非表示にする if( ! clip.move_flg ) { clip.move_flg = true; btn._visible = false; } } 最初はアニメステップカウンタが0なので、case 0: の部分(移動指令が出るまで待機)が実行されます。 ボタンがクリックされると、move_flg が true に変わります。次のステップに移る前に、target_point の位置から角度を出し、それを元に移動量を決めて先に進みます。 次からはアニメステップカウンタが1になりますから、case 1: ( target_point に向かう移動処理)が実行されます。目的地に着いたかどうかは、target_point の座標と自分との衝突判定をとって判断しています。 target_point の位置に到達したら、ここへ向かう時と同じ要領で、今度は goal の位置から移動量を決めて先に進みます。 goal に到達した後は、フラグやアニメステップカウンタを最初の状態に戻し、再び移動の指令が出るまで待機します。 上記の例では、指定の位置に着いた後は移動せず待機に戻りますので、一旦 goal に着くと、target_point と goal の間を移動することになります。 別の位置からスタートさせたい場合は、goal に着いた後にその位置まで移動する処理を加えてください。 例えば、最初の位置を変数に保存しておき、goal に着いた後は初期位置に移動する処理を追加すると、初期位置→ target_point → goal →初期位置→ target_point ・・・というルートで移動していくアニメになります。 target_point の位置をいろいろと変更して、動作を確認してみてください。target_point がどの方向にあっても、clip はそこに向かって移動していきます。 この例では目標地点にムービークリップを配置し、その座標で目的地を決めていますが、ステージ上のある特定の点の座標を移動目標にすることもできます。 移動の計算は三角関数を使わなくてもできます。 独自の処理を作ってある時は、その処理に置き換えても構いません。 長くなってすみませんでした。 不明な点がありましたら、補足してください。
お礼
DPEさん とても解りやすく、丁寧に教えて頂いてありがとうございました! ステップを踏む式、とても参考になりました。 (私の式の誤りは同じ変数の使用が原因のようでした) おかげで希望通りの動きをするムービーを制作できます。 本当にありがとうございました。