자동차 게임에서의 전송 구현


23

수동 기어 변경으로 간단한 자동차 게임을 만들려고합니다. 그러나 기어 변경을 구현하는 데 약간의 문제가 있습니다.

"car"에 대한 현재 코드는 다음과 같습니다.

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를 기억 합니다. 이 기사의 약 1/3에서 엔진 힘 전달에 대해 이야기하기 시작합니다.
Eric

답변:


17

새로운 기어와 자동차의 현재 속도를 기반으로 새로운 RPM을 계산하십시오.

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

그래서 : 대신 :

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 및 기어의 절대 결과로 계산하십시오. 그러나 기어 변속 후 새 rpm을 계산할 때는 고정 된 3600 rpm 단계로 경험적으로 낮추십시오.

이것은 당신의 실수입니다. rpm 드롭 다운은 기어간에 고정되지 않습니다. 각 기어 사이에 정확한 rpm 강하 횟수를 저장하는 두 번째 어레이를 만들어서 고칠 수 있습니다.

두 번째 방법은 물리 기반 계산을 사용하는 것입니다. 시뮬레이션을하고 있으므로 수치 적분을 할 수 있습니다. 시간, dt및 오일러 통합 또는 Verlet 통합을 사용합니다. 이름이 복잡하지만 실제로는 그렇지 않습니다.

기본적으로 주어진 rpm에서 엔진 토크에 대한 조회 테이블을 생성한다는 의미입니다. 그런 다음 속도의 제곱에 따라 증가하는 공기 저항을 고려합니다. 그런 다음 시뮬레이션은 뉴턴의 2 법칙을 반대로하여 다음 속도를 계산합니다 f=m a.
를 찾은 a=f/m다음 오일러 통합 : speed=speed+a*dt. 는 m1200 (일반 자동차 무게)에 관한 것입니다. f는 엔진 토크에서 파생 된 힘으로, 기어 박스로 축소 된 다음, 휠의 반경을 고려하여 레버 공식을 사용하여 힘으로 변환됩니다. (벡터는 일반적으로 곱을 가로 지르지 만, 반지름에 토크를 곱하면 단순화 될 수 있습니다. netwton / meters에 미터를 곱하면 미터 = 뉴턴이기 때문입니다.)

이러한 방식으로, 엔진의 rpm은 선형 자동차 속도의 함수로서 거꾸로 계산된다.


2
없습니다 exact number of RPM drop between each gear. @Baldrickk이 지적한 것처럼 비율입니다. 변속기의 출력이 속도가 아닌 토크가되도록하는 것이 좋은 생각이지만 바람 저항과 버렛 통합에 대한 논의는 문제의 범위를 약간 벗어난 것입니다.
Justin

예. 질문에 대한 답을 얻으려면 Baldrickk의 답변을 추천합니다. 나는 그것을 upvoted.
v.oddou

5

기어 는 감속 메커니즘으로 사용됩니다.

기어 박스에서 두 개의 비율, 하나의 입력 기어 (엔진) 및 하나의 출력 기어 (기어 박스의 비율 중 하나) 로 단순화 된 변속기 를 사용하면 서로 다른 감속비가 있습니다.

따라서 x 이빨을 가진 입력 기어와 x / 2 이빨이있는 출력 기어의 경우, 출력 기어의 속도는 입력 기어 속도의 두 배입니다 (2 : 1 비율).

rpm2 = rpm1 * gearRatio

어디에:

gearRatio = teeth1 / teeth2

따라서 하드 코딩 된 속도로 각 기어를 제한하는 대신 비율로 제한 할 수 있습니다. 그런 다음 특정 (rpmEngine, 기어) 쌍의 속도를 계산하고 기어가 변경 될 때 알려진 속도와 새 쌍이 주어지면 엔진 속도를 계산할 수 있습니다.

단순화하기 위해 두 기어에 연결된 엔진 만 사용하십시오.

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 

두 번째 기어로 변속 할 때 10000이 속도이므로 동일한 공식으로 연결하면 다음과 같습니다.

vehicleSpeed = 10000 #computed above
selectedGear = 2

따라서 우리의 새로운 rpm :

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

그런 다음 10000은 차동 장치 (다른 장치로 추상화 될 수 있으며 필요한 경우 검색 할 수 있습니다, 죄송합니다, 두 개의 링크를 게시 할 수 있음)와 휠 크기로지면 속도를 시간당 킬로미터 또는 마일로 계산 .

낮은 기어로 변속하면 엔진 rpm이 상승한다는 사실을 고려해야하므로 간단한 접근 방식은 maxRPM 을 확인 하고 최대 rpm으로 변속 한 후 rpm을 제한하여 차량 속도를 줄이는 것입니다.

기본적으로 기어 변속이 발생할 때마다 차량 속도에서 엔진 RPM을 계산하고 maxRPM으로 제한 한 다음 사용자 입력에서 rpm을 업데이트하고이를 기반으로 속도를 계산하는 "정상"으로 돌아갑니다.

현실적인 시뮬레이션을 위해서는 최소한 엔진 토크 (v.oddou 's answer)와 클러치 미끄러짐을 고려해야합니다. 이로 인해 다음과 같은 영향을 미칩니다.-위로 이동할 때 엔진 rpm이 떨어지지 않을만큼 충분히 빠른 경우 , 균형을 잡을 때까지 엔진 rpm이 낮아지는 동안 속도가 올라갑니다. 아래로 이동하면 엔진이 새 rpm으로 올라갈 때까지 차량 속도가 낮아 지지만 이는 "간단한"구현을 넘어선 것입니다.


4

작동 수동 변속기는 양방향 장치입니다. 차량 (특히 운동량)이 엔진을 가속 할 수있는 것처럼 엔진은 차량을 가속 할 수 있습니다.

이것은 초기 수동 변속기에서 실제 문제였습니다. 다운 시프 팅은 엔진을 갑자기 더 높은 rpm으로 발동시켜 점화 사이클을 동기화하지 않고 엔진이 정지 될 수 있습니다. 변속기를 작동시키기 위해 클러치를 풀기 전에 운전자가 엔진을 올바른 속도로 회전시켜야하는 전문적인 운전에 의해 상쇄되었습니다.

그것은 synchromesh 가 개발 될 때까지 였습니다. 입력 및 출력 속도가 동기화 될 때까지 전송이 작동하지 않도록하는 메커니즘입니다.

그래서, 내가 제안하는 것은 엔진 속도와 자동차 속도가 현재 수준에서 일치 할 때까지 Synchromesh를 에뮬레이트하고 변속기를 작동시키지 않는 것입니다.


2

기존 답변이 너무 복잡해 보입니다. 게임의 경우 RPM은 화면의 표시 기일뿐입니다. 실제 속도는 실제 변수입니다. 기어비는 엔진 속도를 RPM으로 변환하는 방법을 결정합니다. 기어를 바꾸면 비율은 변하지 만 속도는 변하지 않습니다. 분명히, RPM도 기어비의 역수로 변합니다.

과 회전 (8500RPM 한계를 넘어서 하향 변속)은 별도로 구현하는 것이지만 자동차에서는 나쁘고 게임에서는 나쁘게 만들 수 있습니다.


2
기존 답변은 내가 본 대부분의 게임, 심지어 단순한 아케이드 게임과 정확히 일치합니다. 왜냐하면 그렇게 복잡하지 않기 때문입니다. 화면의 RPM은 숫자 일 수 있지만,이 방법을 사용하면 숫자 (어쨌든 시각적 표시기를 조정할 수 있음)와 해당 숫자와 일치하는 동작이 모두 제공됩니다.
Selali Adobor

2

다른 사람들이 언급했듯이 차량 속도는 실제 값이어야하며 RPM은 그 값에서 파생되어야합니다. 상향 변속은 km / h 당 RPM 비율이 "즉시"변경되지만 차량 속도는 변하지 않기 때문에 엔진의 회전 속도가 감소해야합니다.

그러나 엔진 토크는 RPM에 따라 특정 한계까지 증가하고 그 범위를 넘어서는 것이 좋습니다. 차량이 가속하는 속도는 토크에 비례하여 속도의 제곱에 비례하는 공기 저항을 뺀 기어비로 나눠야합니다. 연속 기어의 비율이 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.