プレイ日記
簡単な物理エンジンを作りました!僕中1で物理には詳しくないので、動作が不自然、、、。
10そうだね
プレイ済み
返信[1]
親投稿
ぐちゃぐちゃで申し訳ありません、、、。
0そうだね
プレイ済み
返信[2]
親投稿
こんな感じ、、。
0そうだね
プレイ済み
返信[3]
親投稿
遅れました。key:2EV47N4Vです。良かったらご指摘御願いします。
0そうだね
プレイ済み
返信[4]
親投稿
MIKI ifconfig
重力加速度=g 質量=m シミュレーション周期=dt 空気抵抗係数=k とします。これらは定数なので途中で変えちゃダメです。 現在の速度=(vx, vy)である時、次のステップを求める式は 加速度=(ax, ay)=(-k*vx, g-k*vy) 速度=(vx, vy)=(vx+ax*dt, vy+ay*dt) 位置=(px, py)=(px+vx*dt, py+vy*dt) となります。 ここまでいいかな?? 加速度は a(acceleration)、速度は v(velocity) と表記するのが一般的です。
0そうだね
プレイ済み
返信[5]
親投稿
MIKI ifconfig
反射する場合は、厳密には交点を求めないとダメなんだけど、 まあ今のやり方(壁より進んだら壁手前にしちゃう)でもまあいいでしょう。 壁に反射する時は、反発係数を rw として、先の計算の前に 速度=(vx,vy)=(-vx*rw,vy) とします。 床の場合は反発係数=rcとして 速度=(vx,vy)=(vx,-vy*rc) とします。 これだけでOK。力学は結構シンプルだ。
0そうだね
プレイ済み
返信[6]
親投稿
MIKI ifconfig
なおこのシミュレーションは数値積分を計算してるわけなのですが ここで示したのはオイラー法と言って一番単純な方法であり、理解しやすくて計算も速いというメリットがあります。 反面、精度はよくないです。 この精度を上げるためにいろいろ工夫されており、ニュートン法、ルンゲ=クッタ法、シンプレクティク法、ニューマークβ法等があります。 興味があれば調べてみてください。
0そうだね
プレイ済み
返信[7]
親投稿
MIKI ifconfig
あ、バグってた!! 質量が入ってない! 誤: 加速度=(ax, ay)=(-k*vx, g-k*vy) 正: 加速度=(ax, ay)=(-k*vx/m, g-k*vy/m) です。失礼しました。
1そうだね
プレイ済み
返信[8]
親投稿
oh,知らない言語が次々と、、、。コメントアリガトデスッ
0そうだね
プレイ済み
返信[9]
親投稿
参考にさせていただきますっ!
0そうだね
プレイ済み
返信[10]
親投稿
おちゃめ ochame_nako
このプログラムはY方向に関しては重力加速度が0.1、速度はG、床との反発係数が0.7ということで動作面においては問題はないのですが、X方向に関してはXPとDXという2つの速度(?)が存在していてるし0.09という謎の加速度(空気抵抗?)があるため挙動が不自然になっている部分があります。 それは一旦おいといて、プログラム的に一番気になったのは32行の処理です。 「XPが1より小さくなったら0にする」というのは「一定以下の速度になったら静止する」という処理でありこれ自体は問題はないのですが、肝心の座標への加算処理となるHX=HX+XPがその「0にする処理」よりも前になるためこのプログラムでは永遠に0.09ずつ動き続けてしまいます。
0そうだね
プレイ済み
返信[11]
親投稿
おちゃめ ochame_nako
この31行、32行の部分に関しては意図通りの動作とは思えないためこういう感じでXPの値を0にする処理の後にHXの加算処理を入れるとよいです。 IF LK==1 THEN   XP=XP-0.09   IF XP<1 THEN XP=0   HX=HX+XP ENDIF これで止まらずにずっと動き続けるということが無くなります。
0そうだね
プレイ済み
返信[12]
親投稿
おちゃめ ochame_nako
X方向の動きを自然にするためにはXPとDXという2つの速度を一本化してみましょう。 2つに分けているのは壁に当たった後と前とで移動量の正負が反転するため停止処理がうまくいかなかったためだと推測しますがIF XP<1 THEN X=0というのはIF ABS(XP)<1 THEN XP=0とすればどちらの向きでも対応が可能になります。 というわけで、X方向の動きを改善したリストが下記のものです。 なお、ボールを画面内で停止させるため壁の反発係数を0.6に変えて空気抵抗係数も0.09では大きすぎると感じたので0.009に変えました。それに伴い停止処理のしきい値も1から0.1に変更しています。 ついでにボールが回転するようにしてみました。(ボールを回転させるためSPHOME 0,8,8としてスプライトの基準点を変更し地面との衝突処理もHY>214からHY>222に変更しています)
0そうだね
プレイ済み
返信[13]
親投稿
おちゃめ ochame_nako
あとはX、Y方向の初速を変えたり、壁や床の反発係数を変えたり、空気抵抗を変えたりするといろいろ動きが変わるので自分が面白いなと思った動きをゲームに採り入れると良いでしょう。例えば2箇所ある0.009という空気抵抗係数を0.03くらいにするとすごいふわふわしたボールになります。 上記の改造プログラムではボールを自然に回転させるためにANG=ANG+XP*7.2としているのですが、7.2という値は数値を変えていって自分が自然だなと思える値でも良いけど計算で簡単に求められます。 ボールの半径は8ドットなので外周は16πドットなります。 1回転は360度(SPROTの角度設定はラジアンではなく度であるため)なので360÷16π≒7.2ということです。(ANGなんて変数を用意しなくてもSPROT 0,HX*7.2でも良いけど移動量と角度が比例しているのを分かりやすくするためこうしている)
0そうだね
プレイ済み
返信[14]
親投稿
おちゃめ ochame_nako
自分が作るゲーム内での動作であれば物理法則にしたがってないといけないというルールはありません。 「自分はこういう動作をさせたい」という意図があれば仮に物理法則的に間違っていてもそれで正解といえます。 しかし、簡易的とはいえ物理シミュレーションならばある程度は物理法則にしたがって動作させる方が良いですね。自然な動きというのもそれを理解した上で作るとあっさりできたりします。 数学や物理の知識はゲーム作りに必ずしも必要とは言えませんが、知識があるとゲーム作りが楽になる(ゲーム作りの幅を広げてくれる)というだけです。
0そうだね
プレイ済み
返信[15]
親投稿
ありがとうございます!確かに最後ゆっくりゆっくり動いてたんです!
0そうだね
プレイ済み
返信[16]
親投稿
長文ありがとうございます。本当に。
0そうだね
プレイ済み
返信[17]
親投稿
ABSって絶対値を得る関数?なんですね!いやープチコン面白いっ!
0そうだね
プレイ済み