- 締切済み
MCが放物線を描いて移動
いつも参考にさせていただいています。 環境はWindowsXPで、Flash2004を使っています。 ステージ右上S地点から左下F地点までループで移動するのですが、まっすく拡大していくだけで、放物線を描くような動きにすることができません。いろいろ調べてX方向=等速運動・Y方向=加速運動にすることまではわかったのですが、加速度をつけるとループさせた時にどんどんスピードアップしてしまいます。S地点にもどったときに、加速度をリセットするやり方はあるのでしょうか?もしくは加速度をつかわないやりかたがあるのでしょうか。 No-1のMCに書いてあるスクリプト、文字数の関係で一部抜粋です。 -------------------------------------- function yScroll() { if (_parent.fScroll) { if (this._y>_parent.yFp) { this._alpha = 0; this._x = _parent.xSp; this._y = _parent.ySp; } else if (this._y<_parent.ySp) { this._y = _parent.yFp; this._x = _parent.xFp; } else { this._y = this._y+(_parent.tyusin._ymouse/20); this._x = (-(_parent.xScale*(this._y/_parent.yScale))+_parent.xSp); } } } -------------------------------------- Spが出発点で Epが到達点で、まだ加速度はつけていません。 何卒ご教授よろしくお願いいたします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
#1です。 あれから,しばらく考えていたのですが, マウスの座標によってスピードを変えなければならないのでしょうか? もし変えない場合は,#1のスクリプトを変形させて, 下のようなものでもいいかもしれません。 ---------------------------------- //このMCが表示されたとき onClipEvent (load) { //このMCの大きさを保存 x0 = this._xscale; y0 = this._yscale; //MCの初期x座標を設定 this._x = 400; //変数_root.changerを設置 _root.changer = 1; } //1フレーム進む時間ごとに1回下を計算 onClipEvent (enterFrame) { //スピードの設定 spd = 200*_root.changer; //xの座標を10ずつプラスする this._x -= spd*10/100; //放物線の式 this._y = 0.0048*Math.pow(this._x-250, 2)+100; //このMCのスケールを拡大 this._xscale += spd*15/100; this._yscale += spd*15/100; //ステージの端まで行ったら, if (this._x<=0) { //xとyを最初の位置に戻す this._x = 400; this._y = 0.0048*Math.pow(this._x-250, 2)+100; //大きさも最初に戻す this._xscale = x0; this._yscale = y0; } } on (rollOver) { _root.changer = 0; } on (rollOut, dragOut) { _root.changer = 1; } ------------------------------- 放物線の式は#1のままで,動く向きや他のプロパティも変化させています。 もし,マウスのy座標によって,全体のスピードを変化させる場合はさらに変形させて, ------------------------------- //このMCが表示されたとき onClipEvent (load) { //このMCの大きさを保存 x0 = this._xscale; y0 = this._yscale; //MCの初期x座標を設定 this._x = 400; //変数_root.changerを設置 _root.changer = 1; } //1フレーム進む時間ごとに1回下を計算 onClipEvent (enterFrame) { //スピードはマウスのy座標に依存 spd = _root._ymouse*_root.changer; //xの座標を10ずつプラスする this._x -= spd*10/100; //放物線の式 this._y = 0.0048*Math.pow(this._x-250, 2)+100; //このMCのスケールを拡大 this._xscale += spd*15/100; this._yscale += spd*15/100; //ステージの端まで行ったら, if (this._x<=0) { //xとyを最初の位置に戻す this._x = 400; this._y = 0.0048*Math.pow(this._x-250, 2)+100; //大きさも最初に戻す this._xscale = x0; this._yscale = y0; } } on (rollOver) { _root.changer = 0; } on (rollOut, dragOut) { _root.changer = 1; } ------------------------------- でもいいかもしれません。 x軸方向の動きを変化させて,軌跡はそのままで全体の速さを変えるしかないと思います。 x軸の速さは一定で,y軸向きの速さだけを変化させようとすれば, 軌跡が変形してしまい,おそらくとんでもない所に行ってしまうと思います。 上記スクリプトで, _root.changer = 0; のようにわざとchangerという変数だけには _root. を付けています。 おそらく,このMC1つだけではなくて,同様の物を追従させるように動かすのではないかと考えたからです。 このMCを複数,時間を分けて表示させてもすべてが _root の changer を参照するので,ロールオーバーでシンクロして止まると思います。 ただ, 上で書いた方の,マウスの座標によってスピードを変えないスクリプトの場合は, フレーム1で1つめのMCを表示,フレーム7で2つめMCを表示,フレーム14で3つめMCを表示&stop(); みたいにすれば,微調整で等間隔に複数が出没すると思いますが, 下のように,マウスのy座標で全体のスピードを変える場合は, フレームや,時間的なコントロールではなくて,1つめのムービークリップが,座標○○ に来たとき2つめを表示… みたいにしなければ,ムービークリップの間隔が変になると思います。 いろいろされていて, 別の方法などで完成されているかもしれませんが, どこか参考にできるところがあれば参考にしてみてください。 ============================ あと,それと, 「マウスの座標によって速度を変える」 という部分を除けば, ガイドレイヤーを使ったモーショントゥイーンと,そのイージングで簡単に動きもスピード調節もできます。 複雑なことをするときは結局ActionScriptを使わず,したい通りを普通のアニメーションでするほうが楽でファイルも軽くなる場合も多々ありますよ。 「繰り返し」も,ムービークリップの中に動くムービーを作ってしまえば,stop(); を書かない限りループしています。 タイムラインとムービークリップとモーショントゥイーンで,たいていのことは可能だと思います。 わかっていらっしゃるとは思いますが, もし,ガイドレイヤーやイージングの使い方がわからない場合は参考にしてみてください。 「FLASH5最初の一歩 さらに動かす」 http://fpower.org/f5kantanp4.htm 「ガイドレイヤーを使おう!」 http://www.1art.jp/flash/le/lesson5/lesson5.htm 「簡単なイージングの使い方 」 http://www.mediacreator.jp/tutorials/print_tutorial.asp?id=4 普通はこれらでやってみて,ifによる分岐や,マウスの座標によって変わる場合や, ボタンの押され方によってどう変化するかわからないときなどにスクリプトは使う物だと思います。 というか本来Flashって,プログラムも何も必要なく簡単に物を動かすためのソフトです。JavaScriptなど難しい物を使わず,したいとおりに動かせるのが最大のメリットです。 だから,基本的には動き自体にはスクリプトは当然使っても当然良いですが,本来は使わない物だと思います。
まず, 高校1年生か2年生の頃の理科1とか,物理1Aとか物理1Bとか, そういう基礎物理を思い出してください。 鉛直方向上向きに投げられたボールは, 9.8m/s^2 の重力加速度によって,下向きに加速します。 つまり,最初は減速します。 それ以上高くは上がらない位置まで来れば,逆に加速します。 9.8は地球上における理想状態の物体を観測した場合の定数で,Flashでは無視してください。 大切なのは,「時間の2乗に比例して速度が下向きに増す」ということです。 もし,この投げられるボールの運動で, 初速が横向きにあった場合,なおかつ真空状態で他の摩擦は考えられない場合, 質問者さまが,おっしゃるように,横向きには等速運動をします。 そのとき, 結果的に,ボールの軌跡をたどると,「放物線」になります。 まとめると, 「物体の横向きの速度が一定で上に投げられた場合,ボールは放物線を描く。」 ということになります。ここが重要です。 放物線は,物体がそういう条件のもとで動いた「結果物」です。 でも,よく考えると逆も通らなければ矛盾します。 つまり, 「ボールは放物線を描くのは,ボールの横向きの速度が一定で上に投げられた場合である。」 当然これも言えなければなりません。 言いたいことがわかりますか? 「物体の軌跡が放物線を描くようにすれば,物体の横向きの速度が一定の時,縦向きの速度は勝手に減速や加速をしてしまう。」 ということです。 そうでなければ,どこかが破綻し,変な動きになります。 物体の軌跡を放物線にして,横向きの速度を一定にすると,縦向きの速度はおのずと変わります。 もし,この縦向きの速度をコントロールしようとすると,全てが破綻してしまいます。 だから, 物体の軌跡を放物線状にして,x軸方向の移動を一定にしてやれば良いだけのことです。 それ以上の手出しは,矛盾を呼ぶだけになってしまいます。 =============================== では,具体的な例です。 ステージの横幅を500px,縦幅を400pxにしたとします。 物体の最初の座標を (0,500) つまりステージの左下として, 物体の最後の座標を (500,400) つまりステージの右下としします。 そして,頂点の座標を (250,100) だとします。 y座標の100は適当ですが,xは必ず,動かしたい距離の半分になります。 そうでないと放物線は描きません。 http://www.kwansei.ac.jp/hs/z90010/sugaku1/2jikan1/2jikan1.htm などを参考にしてもらうか,中学数学を思い出してもらうとわかりますが, 放物線の頂点を求める式は y=a(x-p)^2+q となります。 この式に,上の通る点(0,500)と頂点(250,100) を代入して, 加減法などで計算すると, y=a(x-p)^2+q y=0.0048(x-250)^2+100 となります。 これが,xとyの関係式になり,つまり放物線の軌跡となるのです。 これをFlashに当てはめます。 =============================== まず,横500×縦400のステージ上に,1cmくらいの適当なMC(ムービークリップ)を用意してください。 そのMCに以下のように書けば, 最初の座標 (0,500) 頂点の座標 (250,100) 最後の座標 (500,400) を通って動くMCになります。 ---コピペ可------------------------ //このMCが表示されたとき onClipEvent (load) { //MCの初期x座標 this._x = 0; } //1フレーム進む時間ごとに1回下を計算 onClipEvent (enterFrame) { //xの座標を10ずつプラスする this._x += 10; //ここが,上で長々と説明した部分 this._y = 0.0048*Math.pow(this._x-250, 2)+100; //ステージの端まで行ったら,xを0に戻す if (this._x>=500) { this._x = 0; } } ---------------------------------- 説明が長い割にスクリプトはえらく単純で短いですね。 以上のように考えれば, 結構単純なスクリプトで行けると思います。 Math.pow(this._x-250, 2) は this._x-250 の 2乗 です。 なお,私が得意なのは 物理>Flash>数学 の順です。 物理は専門家の部類に入る可能性もありますが, Flashは単なる経験者で,数学はぜんぜんわからない者です。 Flashや数学で,これ以上の質問をされてもわからないかもしれません。 と言っても,物理もスクリプトも基礎的なことしか書いていませんね。 特に数学は苦手なので,これ以上はわかりません。
お礼
解りにくい質問内容でにも関わらず、丁寧なご回答ありがとうございました。 正直物理は授業で勉強したことがないので、ご説明の意味は初めて知ったことが多いのですが、とても勉強になりました。Math.Powという関数があるのですね!これからなんとか意味を理解したいと思います。 ソースは無事動きました!参考にさせていただきます。ありがとうございました。