2015年6月10日水曜日

新作アプリ、パッティングゲームの製作(転がるボールのアルゴリズム)

以前の新作アプリのことを記事で書きましたが、もうだいぶ出来てきました
ベース部分はほぼEasy Basketballなのでかなり楽が出来ましたが、グリーン上を転がるボールのアルゴリズムを一から作る必要がありました
せっかくなので製作過程を書いていきます

まずは任意の初速で放たれたボールがグリーン上を転がり止まるという基本的な動きを考えます
なぜボールが止まるかというと当然地面から受ける摩擦で止まるので、摩擦係数がわかれば転がるボールのアルゴリズムが組み立てられると考えられます

調べてみるとグリーンの速さを測る道具にスティンプメータという滑り台のような道具があるようで、これでボールを射出すると初速1.83m/sで放たれどのくらい転がるかでグリーンの早さを測ることが出来ます
これで測った時の典型的な速さのグリーンの転がる距離が2.286mということなので、これを水平面上を摩擦を受けて並進する物体ということで、運動量保存の法則に入れてみます



m:ボールの重さ
v:初速(m/s)
μ:摩擦係数
g:重力加速度(m/s2)
d:移動距離(m)

ここから摩擦係数μ= 0.075が求められますね

ところが、よく調べてみるとこの計算は大間違いのようで
参考:蜂の子:グリーンの転がり摩擦係数μ
正しくは回転エネルギーを用いて計算せねばならず正しい摩擦係数(転がり摩擦係数)はμ= 0.02989715571ということです
しかしこれを使うとなると移動の計算に角速度を用いねばならず、ちょっとめんどくさいゲーム上では並進速度と摩擦係数μ= 0.075を用いた計算で特に支障はないのでこちらを使うことにします

public class Ball {
    final public static int G = 9800;    //重力加速度(mm/ss)
    final public static float u = 0.075f; //摩擦係数
    public Plot position = new Plot();   //位置
    public int speed; //並進速度(mm/s)
    public double angle; //進行方向(Radian)

    //移動処理(interval:経過時間(ms)
    public void move(long interval) {
        //摩擦による減速処理
        speed -= (u * G * interval) / 1000;
        //速度をXY成分に分割
        int xSpeed = (int)(speed * Math.cos(angle));
        int ySpeed = (int)(speed * Math.sin(angle));
        //XYの速度から位置を更新
        position.x += (xSpeed * interval) / 1000;
        position.y += (ySpeed * interval) / 1000;
    }
}

細かいことを言うとパットにはロフトがついていて打出し時にはボールは少し浮いているので、摩擦を受けない時間があったりするのですが、まあ細かいことはいいそれほどゲーム性に影響はないのでこれでよしとします

0 件のコメント:

コメントを投稿