トピック

球体同士の衝突処理について

一応動くところまで出来たんですけど、 何故かどんどん加速していく気がします… 公開キー乗せるので、 何が原因か教えて頂けませんか?
5そうだね
プレイ済み
返信[1]
親投稿
公開キーです。 結構複雑になってしまったんですけど、 もっと簡単な書き方って出来るんですかね?
1そうだね
プレイ済み
返信[2]
親投稿
あきと SideBurnsM
当たり判定がSPHITSPで行われているので矩形による判定になってしまい、ベクトル変更後にぶつかった方の位置を補正しないと次のフレームでも衝突しそうですね。 あとはha,hbから算出するHSのあたりがどういう理論なのかよく分からない…。内積による力の分配が行われてないのでスピードアップしてしまうんだろうなとは思うのですが。
2そうだね
プレイ済み
返信[3]
親投稿
Hanzo rzsense
添付の一番上のものをダウンロードして試してみてください。 解らない点は、ご遠慮なく訊いてください。
0そうだね
プレイ済み
返信[4]
親投稿
コメントありがとうございます。 H1,H2からHSを求める所は、 コサインに移動量と衝突した角度の 差を入れて「衝突した速度」としています。 それを一方から引いて、もう一方に足せば… って思ったんですけど、 どうやら何か間違ってるみたいですね。 hanzoさん» サンプルありがとうございます。 DLしてみますね。
0そうだね
プレイ済み
返信[5]
親投稿
DLしました。 SPFUNKって便利ですね。初めて見ました。 えーっと、これはどういう原理ですか? (率直すぎる質問) 28~32行目と49~64行目あたりの 解説お願いしますm(_ _)m
0そうだね
プレイ済み
返信[6]
親投稿
あ、49からは壁の処理ですね。 よく考えれば自分で作った所だった(ぇ
0そうだね
プレイ済み
返信[7]
親投稿
Hanzo rzsense
解説しよう。(これ、懐かしいと思ってくれる人いるかな) まず、49~64行目は、お気づきのとおり、外枠との衝突判定です。外枠からはみ出したときに座標を修正しています。速度の反転は、速度成分が外向きのときだけ行っています。 このプログラムのキモは、28~41行目です。 まず、28~32行目では、自分の中心座標を原点として、自分の中心座標と衝突相手の中心座標を結ぶ直線がX軸と重なるように、自分および衝突相手の速度成分を回転しています。変数名にNがついているのが自分、Cがついているのが衝突相手です。回転の計算では、回転角のサインとコサインが必要で、それを求めているのが28行目です。
1そうだね
プレイ済み
返信[8]
親投稿
Hanzo rzsense
33~37行目は、自分と相手が近づいているのか、遠ざかっているのかの判定と、近づいているときの反発処理です。自分と相手が近づいているか遠ざかっているかは、両者の回転後の速度のX成分を比較して判断します。反発処理は基本、両者の速度のX成分を交換するだけです。両者が遠ざかっているなら、何もせず放っておきます。 38~41行目は、速度成分を逆方向に回転、つまり元に戻す処理です。 回転変換についての詳細は「回転 座標変換」でインターネット検索してみましょう。
1そうだね
プレイ済み
返信[9]
親投稿
なるほど、ぶつかった角度を0°にして X移動量を交換すれば良いんですね。 ほんっとにありがとうございます^^
1そうだね
プレイ済み
返信[10]
親投稿
Hanzo rzsense
この回転変換、円と直線の衝突判定とか、三角形同士の衝突判定のときとかにも応用できるテクニックなので、覚えておいて損はないです。 サンプルプログラムはそのうち消しちゃいますけど、もう大丈夫ですよね?
0そうだね
プレイ済み
返信[11]
親投稿
はい。大丈夫です。 回転処理とか入れるとまた複雑になるのかな。
0そうだね
プレイ済み
返信[12]
親投稿
重力処理を入れたら、 なんかめり込んでしまいました… 何が原因ですか? 質問ばかりすいません。
0そうだね
プレイ済み
返信[13]
親投稿
Hanzo rzsense
スプライトの数のわりに、反発係数Eが小さ過ぎるのだと思います。何かに衝突するたびに、E掛けで速度が失われるので、スプライトの数が多いほど、衝突する機会が増え、すぐに減速するのでは? 重力がかかっているなら、スクリーンショットのようにスプライトが下に溜まるのは道理です。スプライトをもうちょっと減らして、Eを1に極めて近い1未満の値(0.99とか)にして試してみましょう。 なお、衝突判定の半径は、実際のスプライトサイズより小さめにしているので、スプライトがたくさんある場合は、最終的にめり込み気味の状態で安定することになります。それがどうしてもイヤな場合は、RDの値を大きくしてみてください(上限16)
1そうだね
プレイ済み
返信[14]
親投稿
Hanzo rzsense
ただ、多分、上記のことをやっても、最終的には、めり込んだ状態になってしまうと思います。このめり込みを完全に避けるためには、スプライトが重なったときのスプライトの位置補正を適切に行う必要がありますが、恐縮ながら、その方法については現時点では no idea です…
0そうだね
プレイ済み
返信[15]
親投稿
Hanzo rzsense
たびたびすみません。 元々のリストの38行目あたり(回転変換を元に戻す部分)に、以下を追加してみてください。 X[C]=2*RD*CO+X[N]:Y[C]=2*RD*SI*Y[N] スプライト同士がめり込もうとすると、無理やり引き離します。
0そうだね
プレイ済み
返信[16]
親投稿
スプライトを小さくして、 オリジナルの物に変えてみました。 なんか下で影分身して瞬間移動しますΣ(°д°) 沸騰した水みたいですね。 ちなみに、最終的には アクションパズルを作ろうと思っています。
0そうだね
プレイ済み
返信[17]
親投稿
お、なんか沸騰しなくなりました^^ 接点から半径分離す処理です。
0そうだね
プレイ済み
返信[18]
親投稿
Hanzo rzsense
おおっ、面白そうですね。球体ストボンツムツム系ゲーム? 前回のスプライト位置補正式は間違っておりました。恐縮です。 誤:X[C]=2*RD*CO+X[N]:Y[C]=2*RD*SI*Y[N] 正:X[C]=2*RD*CO+X[N]:Y[C]=2*RD*SI+Y[N] もっともこれは自分の位置を固定して、相手の位置を半径×2だけ引き離す処理でしたが、そのスクリーンショットのように、自分と相手の中点を中心として、両者を半径分引き離す方が、バランスがいいですね。 それにしても、それだけうじゃうじゃスプライトを表示すると、少なくとも旧3DSでは確実に処理落ちします。新3DSでも、旧ほどではないにしても処理落ちすると思いますので、ご注意ください。
1そうだね
プレイ済み
返信[19]
親投稿
Hanzo rzsense
ん…よく考えてみると、接点から半径分引き離す処理の42~43行目で、X[N]とY[N]を更新しているので、中点の計算結果が、42~43行目と44~45行目では、微妙にずれることになりますね。 次のようにするといいでしょう。 XM=(X[N]+X[C])/2:YM=(Y[N]+Y[C])/2 X[N]=-RD*CO+XM:Y[N]=-RD*SI+YM X[C]=RD*CO+XM:Y[C]=RD*SI+YM
1そうだね
プレイ済み
返信[20]
親投稿
ぴったり画面におさまりました。 でも、確かに処理落ちしそうですね。 まあ、作ってから考えます← ゲーム内容はそうです。ツムツム系です。 ちなみにこの球体は、 パワーストーンがモデルになっています^^
1そうだね
プレイ済み
返信[21]
親投稿
案の定、画面一杯に表示すると、 結構処理落ちしますね。 Newでも12fpsまで下がります。 処理速度を上げようと、 既に当たり判定を終えたスプライトの処理を もう一度しないように、 「C=0」を「C=N」に変えてみたんですが、 最初は問題ないんですが、 量が増えると、石が暴れだします…(笑) 何が悪かったんですかね… 他に良い軽量化の方法があれば、 教えて下さいm(_ _)m
0そうだね
プレイ済み
返信[22]
親投稿
Hanzo rzsense
その方法は、一見、高速化に寄与するように見えますが、実は致命的な弱点を孕んでいます。 例えば、#0,#1,#2の3つのストボールがあるとして、#0と#1の衝突判定の後、#1と#2の衝突判定を実行したときに、もし#1の軌道が変わったら、#0と#1の衝突判定をもう一度やり直す必要があるわけですが、ご指摘の方法だと、そのやり直しが行われる機会が失われるからです。 とは言え、確かに、何かうまい方法があるような気もしますね。ちょっと頭の体操に、考えてみるとしますか。
1そうだね
プレイ済み
返信[23]
親投稿
oh...気になったから来てみたものの、話が複雑すぎてわけわかめ…関係ない話すまぬ
1そうだね
プレイ済み
返信[24]
親投稿
石の量が増えると、重みで やっぱりめり込んじゃいますね… なんとかならないかなぁ。
0そうだね
プレイ済み
返信[25]
親投稿
かろうじて自己解決…? 下に石が当たっているときは、 重力処理を行わないようにしてみました。
0そうだね
プレイ済み
返信[26]
親投稿
Hanzo rzsense
なるほど、それは賢明ですね。 障害物があってそれ以上進めない方向には、速度成分を加算しないのが基本です。 それにしても、25fpsなら結構速いじゃないですか。
1そうだね
プレイ済み
返信[27]
親投稿
New3DSでこの速度なので、 旧3DSだと大変なことになりそうです。
0そうだね
プレイ済み
返信[28]
親投稿
だいぶゲームが出来てきました。 そこで、スタッフロール的なもの(書く名前が少なすぎるので殆どパワーストーンの名前紹介)を作ってるんですけど、 「スペシャルサンクス」って、 お世話になった人とかに 「特別な感謝」として書くんですよね? hanzoさんの名前書いて良いですか? ^^
0そうだね
プレイ済み
返信[29]
親投稿
Hanzo rzsense
大した手助けもできていない気がするので、かえって恐縮ですが、もちろん名前を書いていただけるのは嬉しいです(^^)
0そうだね
プレイ済み
返信[30]
親投稿
このゲームで一番重要な、スプライト同士の衝突処理の方法をわざわざサンプルまで作って教えてくれたんですもん! 感謝するのは当然です♪(^ω^
0そうだね
プレイ済み
返信[31]
親投稿
ゲームも完成しましたし、 そろそろ新しいトピックも立てたいので、 このトピックを閉じようと思います。 いろいろありがとうございました!
0そうだね
プレイ済み