車のゲームでのトランスミッションの実装


23

私は手動のギア変更でシンプルな車のゲームを作成しようとしています。しかし、ギアの変更を実装するのに少し苦労しています。

「車」の現在のコードは次のとおりです。

int gear = 1; // Current gear, initially the 1st
int gearCount = 5; // Total no. of gears

int speed = 0; // Speed (km/h), initially 0
int[] maxSpeedsPerGear = new int[]
{
    40,  // First gear max. speed at max. RPM
    70,  // Second gear max. speed at max. RPM
    100, // and so on
    130,
    170
}

int rpm = 0; // Current engine RPM
int maxRPM = 8500; // Max. RPM

public void update(float dt)
{
    if(rpm < maxRPM)
    {
        rpm += 65 / gear; // The higher the gear, the slower the RPM increases
    }

    speed = (int) ((float)rpm / (float)maxRPM) * (float)maxSpeedsPerGear[gear - 1]);

    if(isKeyPressed(Keys.SPACE))
    {
        if(gear < gearCount)
        {
            gear++; // Change the gear
            rpm -= 3600; // Drop the RPM by a fixed amount
            if(rpm < 1500) rpm = 1500; // Just a silly "lower limit" for RPM
        }
    }
}

ただし、この実装は実際には機能しません。最初のギアは正常に機能しますが、次のギアの変更により速度が低下します。いくつかのデバッグメッセージを追加することにより、RPM制限で変更するときにこれらの速度値を取得します。

Speed at gear 1 before change: 40
Speed after changing from gear 1 to gear 2: 41

Speed at gear 2 before change: 70
Speed after changing from gear 2 to gear 3: 59

Speed at gear 3 before change: 100
Speed after changing from gear 3 to gear 4: 76

Speed at gear 4 before change: 130
Speed after changing from gear 4 to gear 5: 100

ご覧のとおり、各変更後の速度は、変更前は遅くなっています。ギアを変更するときに速度が低下しないように、ギアを変更する前の速度をどのように考慮しますか?


1
この優れた詳細チュートリアル:Car Physics for Gamesを思い出します。記事の約3分の1で、エンジンの力の伝達について話し始めます。
エリック14年

回答:


17

車の新しいギアと現在の速度に基づいて新しいRPMを計算します。

speed = (int) ((float)rpm / (float)maxRPM) * (float)maxSpeedsPerGear[gear - 1]);

so:代わりに:

rpm -= 3600; // Drop the RPM by a fixed amount

つかいます:

rpm = max(maxRPM,(float)maxRPM * (float)speed / (float)maxSpeedsPerGear[gear - 1]);

速度はギア変更の前後で同じになり、そこから加速/減速できます。

編集:max(maxRPM, calc)制限するために追加しました。車のように、これは速度のかなり突然の損失をもたらすはずです


29

これは、速度の計算に慣性がないためです。エンジンの回転数とギアの絶対的な結果として計算するだけです。しかし、ギアシフトアップ後に新しいrpmを計算する場合、経験的に3600 rpmの固定ステップでそれを下げます。

これはあなたの間違いです。rpmドロップダウンはギア間で固定されていません。各ギア間の正確なrpmドロップ数を格納する2番目の配列を作成することで、これを修正できます。

修正できる2番目の方法は、物理ベースの計算を使用することです。シミュレーションを実行しているため、数値積分を実行できます。時間dt、、およびオイラー統合、またはVerlet統合を使用します。これは名前が複雑に聞こえますが、実際はそうではありません。

基本的には、特定のrpmでエンジントルクのルックアップテーブルを作成することを意味します。次に、速度の2乗に伴って増加する空気抵抗を考慮します。次に、シミュレーションは、ニュートンの2番目の法則を逆にすることにより、次の速度を計算しf=m aます。、次にオイラー積分
を見つけるa=f/mには:speed=speed+a*dt。これmは約1200(典型的な車の重量)です。fエンジントルクから派生した力で、ギアボックスに還元され、ホイールの半径を考慮してレバー式を使用して力に変換されます。(通常、ベクトルの外積ですが、トルクと半径を乗算することで単純化できます。netwton/ metersはmeters = newtonsに乗算されるためです。)

このようにして、エンジンの回転数は、線形の車速の関数として逆算されます。


2
ありませんexact number of RPM drop between each gear。@Baldrickkが指摘しているように、これは比率です。そして、トランスミッションの出力を速度ではなくトルクにすることは素晴らしいアイデアですが、風の抵抗とベルレットの統合についての議論は、この質問の範囲外です。
ジャスティン14年

はい。質問への回答の場所については、Baldrickkの回答をお勧めします。私はそれを支持しました。
v.oddou 14年

5

歯車は減速機構として使用されます。

ギアボックスに2つの比率、1つの入力ギア(エンジン)、1つの出力ギア(ギアボックスの比率の1つ)を備えた単純化されたトランスミッションを使用すると、2つの異なる減速比があります。

したがって、x歯の入力ギアとx / 2歯の出力ギアの場合、出力ギアの速度は入力ギアの速度の2倍です(2対1の比率)

rpm2 = rpm1 * gearRatio

ここで:

gearRatio = teeth1 / teeth2

したがって、ハードコーディングされた速度で各ギアを制限する代わりに、比率で制限することができます。次に、特定の(rpmEngine、ギア)ペアの速度を計算し、ギアが変更されたときに、既知の速度と新しいペアを指定してエンジン速度を計算できます。

単純化するには、2つのギアに接続されたエンジンのみを使用します。

rpmEngine = 5000

gearRatio[1] = 2 #low gear:  one rotation of the engine results in 2 rotations output
gearRatio[2] = 3 #high gear: one rotation of the engine results in 3 rotations output

vehicleSpeed = rpmEngine * gearRatio[selectedGear]

そう:

selectedGear = 1
vehicleSpeed = rpmEngine * gearRatio[selectedGear] #5000 * 2 = 10000 

2速にシフトする場合、10000が速度なので、同じ式でそれを差し込むと、次のようになります。

vehicleSpeed = 10000 #computed above
selectedGear = 2

したがって、新しいrpm:

rpmEngine = vehicleSpeed / gearRatio[selectedGear] #10000 / 3 = 3333.3

その10000は、ディファレンシャル(単なる別のギアとして抽象化でき、必要に応じて検索できます。申し訳ありませんが、2つのリンクを張り出すことができます)と、ホイールサイズによって時速キロメートルまたはマイルで対地速度を計算します。 。

低いギアにシフトするとエンジンの回転数が上がるという事実を考慮する必要があるため、単純なアプローチはmaxRPMをチェックし、シフト後の回転数を最大回転数に制限して、車速を下げることです。

したがって、基本的に、ギアシフトが発生するたびに、車両速度からengineRPMを計算し、maxRPMで制限してから、「通常」に戻り、ユーザー入力からrpmを更新し、それに基づいて速度を計算します。

現実的なシミュレーションを行うには、少なくともエンジントルク(v.oddouの答え)とクラッチの滑りを考慮する必要があります。これらを組み合わせると、次のような効果があります。-シフトアップ時、シフトが十分に速く、エンジンrpmが低下しないと仮定する、エンジンのrpmが低下し、バランスが取れるまで速度が上がります。シフトダウンすると、エンジンが新しいrpmに上がるまで車両の速度が下がりますが、これはおそらく「単純な」実装を超えています。


4

従事している手動変速機は双方向のデバイスであることに留意してください。車両(より具体的にはその運動量)がエンジンを加速できるように、エンジンは車両を加速できます。

これは、初期のマニュアルトランスミッションの本当の問題でした。シフトダウンすると、エンジンが突然より高い回転数になり、点火サイクルが同期しなくなり、エンジンが失速する可能性があります。これは、ドライバーがトランスミッションを接続するためにクラッチを解放する前にエンジンを正しい速度に回さなければならなかった専門家の運転によって相殺されました。

それは、シンクロメッシュが開発されるまででした。これは、入力速度と出力速度が同期するまでトランスミッションが作動しないようにするメカニズムです。

ですから、私がお勧めするのは、シンクロメッシュをエミュレートし、エンジン回転数と車速が現在のレベルで一致するまでトランスミッションを作動させないことです。


2

既存の答えは複雑すぎるようです。ゲームの場合、RPMは画面上の単なるインジケータです。実際の速度は実際の変数です。ギア比は、エンジン速度をRPMに変換する方法を決定します。ギアを変更すると、比率は変わりますが、速度は変わりません。明らかに、RPMはギア比の逆数としても変化します。

オーバーレブ(8500 RPMの制限を超えるダウンシフト)は個別に実装することですが、車では悪いことであり、ゲームでは悪いことにすることができます。


2
既存の答えは、単純なアーケードゲームでさえ、私がこれまで見たほとんどのゲームが行うこととまったく同じです。画面上のRPMは単なる数字かもしれませんが、そのアプローチは数字(とにかく視覚的なインジケーターを微調整できます)と、それらの数字に一致する動作の
両方を提供し

2

他の人が述べたように、車両速度は実際の値であり、RPMはそれから導き出されるべきです。km / hあたりのRPMの比率は「瞬時に」変化しますが、車両の速度は変わらないため、アップシフトによりエンジンの回転速度が低下します。

ただし、エンジントルクはRPMによって特定の制限まで増加し、それを超えて低下することをお勧めします。車両が加速する速度は、トルクをギア比で除算し、速度の2乗に比例する空気抵抗を引いたものに比例する必要があります。連続するギアの比率が1:41:1である場合、加速のための最適なシフトは、下位ギアのトルクが次の上位ギアのトルクの約70%に低下した時点で発生します。


2

使用して@ v.oddouを構築

max(maxRPM, calc)

ギアがシフトされると、RPMSが即座に最大になり、ギアからギアへのスムーズな移行ができなくなります。適切な方法は、速度変数を方程式として使用してRPMを解くことです。

speed = (int) ((float)rpm / (float)maxRPM) * (float)maxSpeedsPerGear[gear - 1]);

rpmを解く

rpm = (maxRPM * speed) / maxSpeedsPerGear[gear - 1] ;

ギアは以前よりも1高いため、RPMは低くなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.