hinekure.net が http://hspdev-wiki.net/ から自動クローリングした結果を表示しています。画像やリソースなどのリンクが切れています。予めご了承ください。
物理のおおまかな話/動くボール - HSP開発wiki
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS

物理のおおまかな話

動くボール

 サッカー、野球にビリヤード、ボーリングやらゲートボールやらいろいろありますが、経験的に ボールは長い時間動くと止まると思われているでしょう。

ほんとのところはといいますと…。

  • ボールに止まろうとする力が働かないかぎりボールは、最初に受けた力や速度を維持しつづける。
  • 実際にボールを蹴ってみると壁にぶつかったわけじゃないのに、時間がたつと止まってしまうのは、 空気や地面から摩擦や抵抗としてボールを止めようとするような力が働いているからです。
  • ボールが動くのを邪魔するものがなければボールは速度を緩めることも止まることも方向を変えることも ありません。
    (このときボールは等速直線運動をします。←検索時のキーワードにどうぞ。^ ^;)
  • 何もしなければボールは1度蹴ると永遠に真っ直ぐ飛びつづけます。
  • 逆を言えば、1度蹴ってしまえば後は何もしなくてもいい。というわけです。

とまあ、こんな感じでボールは動いているわけです。
ではこの辺のことを頭に置いといて、下のスクリプトを実行して体験してみてください。

hsp2.png

+  モジュール
+  等速直線運動サンプル

サンプルの解説

変数の解説です。

px	:移動物体の x方向の位置
py	:移動物体の y方向の位置
vx	:移動物体の x方向の速度
vy	:移動物体の y方向の速度

と、こんな感じです。このように速度や座標はx方向とy方向に分けて考えます。
理由は表示上の都合と言うのもありますが、ベクトルをキーワードにして数学系サイトなどを検索してみてください。

スペースキーを押すとvxに速度が入り、移動スピードが変化します。

	if (key&16=16) & (vx=0) : vx=vx+1	;速度を与える

この行のvxに代入している値を変えると速度が変わります。

  • 一度だけ速度を与えた後は、何も出来ないことを確認してみてください。
  • あちこち値を変更してみて遊んでみてください。(おもにvxやvyの値とか)


モジュール

スクリプトをシンプルにするためモジュールを作成してあります。
モジュールで作成した命令は次のとおり。

  • DrwCls? : redrawやawaitをまとめたものです。
    • DrwCls? wt, cr,cg,cb, px,py
      wt : awaitで待機する時間。(ms)
      cr,cg,cb : ウィンドウを塗りつぶす色。
      px,py : posによる指定座標。
  • DrwArrow? : 矢印を描画
    • DrwArrow? px1,py1, px2,py2
      px1,py1 : 矢印の根元座標
      px2,py2 : 矢印の先端座標
  • sqrt : 平方根を計算します。
    • sqrt p1
      statにp1の平方根の値が返されます。

物理演算

 肝心の物理的な計算の部分の解説をします。計算はこれだけです。

	;	物理計算
	px = px + vx
	py = py + vy

え、前の座標に速度を足すと次の瞬間の座標になる??違います。


距離を x [m]、速度を v [m/s]、経過時間を t [s]としたとき、移動後の位置を求める式は

x1 = x0 + v * t

と、こんな感じです。

では、距離を x [ドット]、速度を v [ドット/コマ]、経過時間を t [コマ]とすると、移動後の位置を求める式は

x1 = x0 + v * t

と、やっぱりこんな感じです。
ちなみにドットは画面上の座標、コマはループの回数で1コマは1ループです。

1コマごとに1回計算するのでtは常にt=1[コマ]と考えてokです。

px = px + (vx * 1)

というわけで、スクリプトでは×1を省略しています。

このように省略するには1コマあたりにかかる時間が安定していないといけないわけですが、 DirectXを使用するHSPプラグインではフレームレート(1コマにかかる時間)を一定に維持する命令が用意されています。
またちょっとした(さほど重くない)ゲームなら、1ループあたりの経過時間はほとんど問題になりません。(今回のサンプル みたいなのがそうですね。)

  • さて、これで物が動いている状態が体感できたでしょうか?動いているものに何もしなければ永遠に動きつづけるというのが体感できたでしょうか?
    さて一応、距離を求める式を載せておきます。速度一定(等速直線運動)のとき、
    (移動後の座標)=(速度)×(経過時間)+(現在の座標)
    まあ、あまり気にせず。参考までに。




おまけ

40行目付近の

	if (key&16=16) & (vx=0) : vx=vx+1    ;速度を与える

を消して次のように書き加えてみてください。

	if key&256 : vx=vx+1	;速度をxの正方向に加える
	if key&512 : vx=vx-1	;速度をxの負方向に加える

書き換えたらマウスの左右のボタンを押すと、速度vが変化するのを確認し、 動いている物体の様子をながめてみます。


HSP3版サンプル [hsp3]

HSP3では三角関数が標準で利用できますので、全方向に転がるボールを考えてみました。
画面をクリックすると、その方向にボールが転がります。
物理演算などは上で説明されているものと変わりません。

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
!
 
 
 
-
|
|
-
|
!
-
|
|
|
!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/*   等速直線運動のサンプル(for HSP3.0)   */
#module
#deffunc DrwArrow int sx, int sy, int ex, int ey
    line sx, sy, ex, ey
 
    x = sx - ex
    y = sy - ey
    ax = (x - y) / 7 + ex
    ay = (y + x) / 7 + ey
    line ex, ey, ax, ay
 
    ax = (x + y) / 7 + ex
    ay = (y - x) / 7 + ey
    line ex, ey, ax, ay
return
#global
 
#const SPEED 5
#const BALL_SIZE 6
    title "等速直線運動"
    WINX = ginfo_winx
    WINY = ginfo_winy
    gosub *resetBall
    goto *main
 
*resetBall    // ■ ボールの初期化
    moving = 0      // 運動中のフラグを初期化
    px = 100        // ボールの位置
    py = 100
    return
 
*main         // ■ メインループ
    redraw 0
    color 255, 255, 255 : boxf  // 画面初期化
    gosub *inkey
    gosub *ball
    gosub *draw
    redraw 1
    await 5
goto *main
 
 
*inkey        // ■ キー入力
    stick key
    if key & 128 : end
    if ((key >> 8) & 1) & (moving == 0) {               // 左クリック & ボールが停止中
        moving = 1  // 運動中のフラグを立てる
    }
    return
 
*ball         // ■ ボールの速度決定・移動
    if moving {     // ボールが運動中
        px += vx
        py += vy
        if (px < 0)|(WINX < px)|(py < 0)|(WINY < py) {  // 画面外に出た時
            gosub *resetBall                            // ボールの状態を初期化
        }
    } else {        // ボールが停止中
        theta = atan(mousey - py, mousex - px)          // 移動する角度を決定
        vx = int(cos(theta) * SPEED)
        vy = int(sin(theta) * SPEED)
    }
    return
 
*draw         // ■ 各種表示
    color 0, 0, 0 : pos 0, 0
    mes "座標( " + px + ", " + py + " )"
    mes "速度 v = ( " + vx + ", " + vy + " )"
    if moving == 0 : mes "画面をクリックしてください。"
 
    circle px - BALL_SIZE, py - BALL_SIZE, px + BALL_SIZE, py + BALL_SIZE
 
    color 255, 0, 0
    DrwArrow px, py, vx * 30 + px, vy * 30 + py
    return
添付ファイル:
fileb001.as
403件 [詳細]
トップ    編集凍結 差分バックアップ添付複製名前変更リロード   新規一覧単語検索最終更新   最終更新のRSS
Last-modified: 2007-07-17 (火) 22:46:44 (2335d)