汽车游戏中的变速箱实现


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
我想起了这个出色的深入教程:《汽车物理游戏》。在本文的大约三分之一处,开始讨论引擎力传递。
埃里克

Answers:


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时,可以凭经验以固定的3600 rpm步进降低它。

这是你的错误。齿轮之间的转速下降并不固定。您可以通过创建第二个数组来解决此问题,该数组存储每个齿轮之间的rpm下降的确切数量。

修复它的第二种方法是使用基于物理的计算。您正在进行仿真,因此可以进行数值积分。使用时间,dt和euler集成或Verlet集成。名称听起来很复杂,而实际上并非如此。

基本上,这意味着您将为给定的rpm创建发动机扭矩的查找表。然后,您会考虑到空气阻力随速度的平方增加。然后,仿真将通过逆转牛顿第二定律来计算下一个速度f=m a
要查找a=f/m,然后进行Euler积分:speed=speed+a*dt。的m是大约1200(典型的汽车重量)。f是来自发动机扭矩的力,该力减小到变速箱中,然后通过考虑车轮的半径使用杠杆公式转换为力。(矢量叉积通常是乘积,但可以通过将扭矩乘以半径来简化。因为netwton /米乘米=牛顿。)

这样,根据线性汽车速度向后计算发动机的转速。


2
没有exact number of RPM drop between each gear。正如@Baldrickk所指出的,这是一个比率。虽然将变速箱的输出设为扭矩而不是转速是一个好主意,但是有关风阻和垂直积分的讨论有点超出了问题的范围,不是吗?
贾斯汀

是。对于这个问题的答案,我会推荐鲍德里克的答案。我赞成。
v.oddou 2014年

5

齿轮用作减速机构。

使用变速箱中只有两个传动比的简化变速器,一个输入齿轮(发动机)和一个输出齿轮(齿轮箱的一个传动比),我们就有两个不同的减速比。

因此,对于带有x齿的输入齿轮和x / 2齿的输出齿轮,输出齿轮的速度是输入齿轮的速度的两倍(二比一的比率)

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 

当换到2档时,速度是10000,因此将其插入相同的公式,我们现在有:

vehicleSpeed = 10000 #computed above
selectedGear = 2

因此我们的新转速:

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

然后通过差速器(可以抽象为另一个齿轮,进一步将其抽象化,如果需要,可以查找,抱歉,可以张贴两个链接)进一步减小10000,然后通过车轮尺寸来计算以公里或英里/小时为单位的地面速度。

您必须考虑到换低档会提高发动机转速这一事实,因此一种简单的方法是检查maxRPM并在变速后将转速限制为最大转速,从而降低车速。

因此,基本上,每次换档时,您都需要根据车速计算engineRPM,将其限制为maxRPM,然后回到“正常”状态,从用户输入中更新rpm并以此为基础计算速度。

为了进行真实的仿真,您必须至少考虑发动机扭矩(v.oddou的回答)和离合器打滑,这些因素结合在一起会产生以下影响:-升档时,假设换挡足够快,以使发动机转速不会下降,则将在降低发动机rpm的同时提高速度,直到达到平衡为止-降档时,将降低车速,直到将发动机提高到新的rpm,但这可能超出了“简单”的实现方式。


4

请记住,参与式手动变速箱是双向的。发动机可以使车辆加速,就像车辆(更具体而言,其动量)可以使发动机加速一样。

在早期的手动变速器中,这是一个真正的问题。降档会突然将发动机踢到更高的转速,从而使点火周期不同步,并可能导致发动机熄火。这被专业驾驶所抵消,在专业驾驶中,驾驶员必须在松开离合器以接合变速器之前将发动机调至正确的速度。

直到开发了同步网。这是一种在输入和输出速度同步之前阻止变速器接合的机制。

因此,我的建议是您模拟同步啮合,直到发动机转速和汽车速度在当前水平匹配之前,才接合变速箱​​。


2

现有的答案似乎太复杂了。对于游戏,RPM只是屏幕上的指示器。实际速度是实际变量。齿轮比决定了如何将发动机转速转换为RPM。换档会改变传动比,但不会改变速度。显然,RPM也随着传动比的变化而变化。

超速行驶(降档超过您的8500 RPM限制)是您单独实施的,但这在汽车中是一件坏事,您可以在游戏中让它成为一件坏事。


2
现有的答案正是我所见过的大多数游戏,甚至是简单的街机游戏,因为它实际上并不那么复杂。屏幕上的RPM可能只是一个数字,但是这种方法既可以提供数字(您仍然可以调整视觉指示符),也可以提供匹配这些数字的行为
Selali Adob​​or,2014年

2

正如其他人提到的那样,车速应该是实际值,并且应该从中得出RPM。升档应该导致发动机转速降低,因为每公里/小时的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 = (maxRPM * speed) / maxSpeedsPerGear[gear - 1] ;

由于齿轮比以前高1,因此RPM会更低。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.