|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
Note: This is an unedited contribution. If this article is inappropriate,
needs attention or copies someone else's work without reference then please
Report This Article
IntroductionThis is the first installment of a series of tutorials in which we aim to make a 3D Driving Simulation Game. With every successive tutorial we will try to make the game cooler by adding new features in graphics, physics and gameplay. The aim of this first tutorial is to simulate a car over an infinitely large plane. I know this is not exactly what we have in the real world. But we will get more realistic in later tutorials. For now imagine the world as a perfect plane with no obstacles. BackgroundThis article is not for the absolute beginner. A basic understanding of XNA Game Studio 2.0 is necessary. But If you are a beginner, I would suggest the following.
Reasonable Knowledge of Newtonian Mechanics and Geometry is necessary to understand the formulas. Using the codeThe application has been divided into three classes Let us first understand the class
Now for the most difficult part - understanding the class The first concept. At any instant the car is in some gear represented by the variable public void Accelerate()
{
free = false;
if ((gear<7)&&(speed > topSpeeds[gear]))
{
gear++;
}
if (gear == 0)
{
acceleration = accelerations[1];
}
else if (gear < 7)
acceleration = accelerations[gear];
else
{
gear = 6;
acceleration = 0;
speed = topSpeeds[6];
}
}
Now when the brake is applied the effect is that a negative acceleration whose magnitude is the acceleration at that gear added to a constant as shown. Here you also have to consider the reverse gear and the maximum speed in reverse. public void Brake()
{
free = false;
if((gear>0)&&speed<=topSpeeds[gear-1])
{
gear--;
}
if ((gear == 0) && (speed < -maxReverseSpeed))
{
acceleration = 0;
speed = -maxReverseSpeed;
}
else
{
acceleration = -accelerations[gear]-6.7f;
}
}
Also when the accelerator is released, even then a negative acceleration with magnitude same as acceleration at that gear has to be applied. And eventually the car comes at rest public void Free()
{
free = true;
if ((gear>0)&&(speed < topSpeeds[gear - 1]))
{
gear--;
}
acceleration = - accelerations[gear];
}
To determine the new position of car after every instant the following code is placed in the float speed = speed + acceleration * time;
float dist = speed * time;
Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotation);
position += addVector * dist;
To make sure the car eventually comes to stop when neither accelerator nor brake is pressed this code is used: float newSpeed = speed + acceleration * time;
if ((free == true) && (newSpeed * speed <= 0.0f))
{
gear = 1;
acceleration = accelerations[gear];
speed = 0.0f;
}
else
speed = newSpeed;
Now let us understand how a car turns. When the driver steers left or right, the plane surface makes and angle theta with the body of the car as shown in figure. Theta should uniformly increase from to 0 to a Maximum Value. Also when the steering is left free theta should eventually become zero. The code for this is as follows: if (turn == 0)
{
float newAngle = steerAngle;
if (steerAngle < 0.0f)
{
newAngle = steerAngle + time * steerSpeed;
}
else if (steerAngle > 0.0f)
{
newAngle = steerAngle - time * steerSpeed;
}
if (newAngle * steerAngle < 0.0f)
{
steerAngle = 0.0f;
}
else
steerAngle = newAngle;
}
else
{
if (turn == -1)
{
float newAngle = steerAngle - time * steerSpeed;
if (newAngle < -maxSteerAngle)
{
steerAngle = -maxSteerAngle;
}
else
{
steerAngle = newAngle;
}
}
else
{
float newAngle = steerAngle + time * steerSpeed;
if (newAngle > maxSteerAngle)
{
steerAngle = maxSteerAngle;
}
else
{
steerAngle = newAngle;
}
}
}
Now that we have understood how the tire turns, let us figure out how the car turns. Look at the figure carefully.
You will at once understand what the constants float x = (VD / Math.Abs((float)Math.Tan(steerAngle)) + HD / 2);
float r = (float)Math.Sqrt(x * x + L * L);
Now we have the radius. The angle by which the car rotates can be found out and corresponding float theta = speed * time / r;
if (steerAngle < 0.0f)
theta = -theta;
rotation = rotation * Quaternion.CreateFromAxisAngle(new Vector3(0, -1, 0), theta);
New position of car can be determined as follows. speed = speed + acceleration * time;
float dist = speed * time;
Vector3 addVector = Vector3.Transform(new Vector3(0, 0, -1), rotation);
position += addVector * dist;
The rest of the code is pretty much straight forward. I would like to thank my friend Tarang Bakshi for his help with the game physics and ideas.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||