XNA中的驾驶模拟(译文)
By robot-v1.0
本文链接 https://www.kyfws.com/games/driving-simulation-in-xna-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 7 分钟阅读 - 3078 个词 阅读量 0XNA中的驾驶模拟(译文)
原文地址:https://www.codeproject.com/Articles/29323/Driving-Simulation-in-XNA
原文作者:AmitDey
译文由本站 robot-v1.0 翻译
前言
A Tutorial to develop a driving simulator using XNA Game Studio 2.0
使用XNA Game Studio 2.0开发驾驶模拟器的教程
介绍(Introduction)
这是一系列教程的第一部分,我们旨在制作3D驾驶模拟游戏.在每个后续教程中,我们将尝试通过在图形,物理和游戏玩法中添加新功能来使游戏更酷.本教程的目的是在无限大的平面上模拟汽车.我知道这并非现实世界中的真实情况.但是在以后的教程中我们将变得更加现实.现在,将世界想象成没有障碍的完美飞机.(This is the first instalment 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.)
背景(Background)
本文不适用于绝对初学者.必须对XNA Game Studio 2.0有基本的了解.但是,如果您是初学者,我建议以下几点:(This 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:)
- 下载并安装Microsoft Visual C#2005 Express Edition,其SP1更新和XNA Game Studio 2.0.所有这些都可以从以下位置免费下载(Download and Install Microsoft Visual C# 2005 Express Edition, its SP1 Update, and XNA Game Studio 2.0. All these can be downloaded free of cost from) www.microsoft.com(www.microsoft.com) .(.)
- 仔细阅读" XNA Game Studio文档",特别是文章"您的第一个游戏:2D中的Microsoft XNA Game Studio"和"超越:3D中的XNA Game Studio".这些教程非常容易理解.(Go through the ‘XNA Game Studio Documentation’, especially the articles ‘Your First Game: Microsoft XNA Game Studio in 2D’ and ‘Going Beyond: XNA Game Studio in 3D’. These tutorials are fairly easy to comprehend.)
- 经历(Go through the) Riemer的XNA教程(Riemer’s XNA Tutorial) .阅读所有3个教程将使您对XNA有了很好的理解.但就目前而言,前两个教程就足够了.四元数的概念应清楚理解.(. Reading all the 3 tutorials will give you a very good understanding of XNA. But for now, the first 2 tutorials are sufficient. The concept of Quaternions should be clearly understood.) 要理解这些公式,必须对牛顿力学和几何有一定的了解.(Reasonable Knowledge of Newtonian Mechanics and Geometry is necessary to understand the formulas.)
使用代码(Using the Code)
该应用程序已分为三类(The application has been divided into three classes) Game1
,(,) Stuff
,(,) Car
.班级(. The class) Stuff
表示可以在屏幕上渲染的任何材质主体.班级(represents any material body that can be rendered on the screen. The class) Car
是班级的专业(is a specialization of the Class) Stuff
代表一个(which represents a) Car
.班级(. The class) Game1
是主要应用程序,并使用以下对象(is the main application and uses objects of) Stuff
和(and) Car
.(.)
让我们先了解一下课堂(Let us first understand the class) Stuff
.如果遍历代码,您将看到我已经尝试封装所有存储任何实体的信息并将其呈现在屏幕上所需的所有内容.我只提供成员变量和函数的概述,因为代码相当简单.(. If you go through the code, you will see that I have tried to encapsulate everything required to store information of any material body and render it on screen. I am only providing an overview of the member variable and function since the code is fairly straight forward.)
- 成员(The members)
viewMatrix
和(and)projectionMatrix
是(are)static
因为它们对于所有可渲染对象都是相同的.(because they are the same for all renderable objects.) - 成员(The members)
position
和(and)rotation
分别表示对象在3D空间中的位置及其方向.(represent the position of the object and its orientation respectively in 3D Space.) - 会员(The member)
cameraRotation
代表相机的方向.存储此值对于获得相机延迟的效果是必要的.(represents the orientation of the camera. Storing this is necessary to achieve the effect of camera delay.) - 会员(The member)
model
代表人体的3D模型.(represents the 3D Model of the body.) - 功能(The function)
UpdateCamera
更新(updates the)viewMatrix
根据汽车的位置和方向.(according to the position and orientation of car.) - 功能(The function)
Draw
在屏幕上渲染3D模型.(renders the 3D Model on the screen.) 现在最困难的部分-了解课程(Now for the most difficult part - understanding the class)Car
.有两个概念在起作用.第一个是撞击加速器,释放加速器并制动汽车运动的效果.第二个是转向向左或向右时汽车的转向方式.(. There are two concepts at work. The first one is the effect of hitting the accelerator, releasing it, and braking on the cars motion. The second one is how the car turns when the steering is turned left or right.) 第一个概念.在任何时刻,汽车都处于以该变量表示的某种档位(The first concept. At any instant, the car is in some gear represented by the variable)gear
.车辆的速度决定了(. The speed of the vehicle determines the)gear
.我们每个人都有最高的速度(. We have the top speed at each)gear
存储在变量中(stored in the variable)topSpeeds
.最高速度(. The top speed at)gear x
也是(is also the minimum speed for)gear x+1
.加速度各不相同(. The acceleration is different at each)gear
.(.)
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) Update
方法.(method.)
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 a 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;
现在让我们了解汽车的转弯方式.如图所示,当驾驶员向左或向右转向时,平面与汽车车身成一个角度θ. Theta应该从0均匀增加到最大值.同样,当转向离开时,theta最终应变为零.的代码如下:(Now let us understand how a car turns. When the driver steers left or right, the plane surface makes an angle theta with the body of the car as shown in the 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)
HD
,(,) VD
和(and) L
代表.(represent.) O
是3D模型的起源.我们假设(is the origin of the 3D Model. We assume that the) car
将围绕标记为"车削中心"的点旋转,半径为(will rotate about the point marked “Center Of Turning” with radius) r
.的价值(. The value of) r
可以使用三角函数来计算:(can be calculated using trignometry:)
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) Quaternion
被建造.(is created.)
float theta = speed * time / r;
if (steerAngle < 0.0f)
theta = -theta;
rotation = rotation * Quaternion.CreateFromAxisAngle(new Vector3(0, -1, 0), theta);
新的(New the) 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.) 我要感谢我的朋友Tarang Bakshi对游戏物理和思想方面的帮助.(I would like to thank my friend, Tarang Bakshi, for his help with the game physics and ideas.)
历史(History)
- 14(14)日(th)2008年9月:初始职位(September, 2008: Initial post)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C# C#2.0 WinXP Win2003 .NET2.0 VS2008 Visual-Studio VS2005 Dev Architect 新闻 翻译