Liny_@NotePad

沉迷ACG中

使用XNA引擎做3D赛车小游戏..(5)

YOYO posted @ 2009年9月27日 22:35 in 【游戏开发】 with tags XNA , 4167 阅读

汽车和道路都画好了,那么下面就是障碍物了,本文只做障碍物的显示,碰撞检测留到下节 - -

截图如下:

  1. 首先新建障碍物类Obstacle,导入XNA:
    1. using Microsoft.Xna.Framework.Graphics;
    2. using Microsoft.Xna.Framework.Content;
    3. using Microsoft.Xna.Framework;
  2. 在Obstacle类中增加成员:
    1. public Vector3 position;                                                //障碍物的位置
    2. public BasicEffect basicEffect;
    3. VertexDeclaration vertexDeclaration;
    4. VertexBuffer vertexBuffer;
    5. IndexBuffer triangleListIndexBuffer;
  3. 在Obstacle类中增加方法LoadContentObstacle,用于加载障碍物的顶点信息:
    1. public void LoadContentObstacle()
    2. {
    3.         vertexDeclaration = new VertexDeclaration(basicEffect.GraphicsDevice, VertexPositionColor.VertexElements)//GraphicsDevice使用的顶点格式
    4.         VertexPositionColor[] verts = new VertexPositionColor[8];              // 立方体的8个顶点
    5.  
    6.         verts[0].Position = new Vector3(-1.0f, 1.0f, 1.0f);                  // 顶点0位置
    7.         verts[0].Color = Color.Aqua;                                                      // 顶点0颜色
    8.  
    9.         verts[1].Position = new Vector3(1.0f, 1.0f, 1.0f);                    // 顶点1
    10.         verts[1].Color = Color.Brown;
    11.  
    12.         verts[2].Position = new Vector3(-1.0f, -1.0f, 1.0f);                // 顶点2
    13.         verts[2].Color = Color.LightPink;
    14.  
    15.         verts[3].Position = new Vector3(1.0f, -1.0f, 1.0f);                 // 顶点3
    16.         verts[3].Color = Color.Red;                                                        
    17.  
    18.         verts[4].Position = new Vector3(-1.0f, 1.0f, -1.0f);                  // 顶点4
    19.         verts[4].Color = Color.Green;
    20.  
    21.         verts[5].Position = new Vector3(1.0f, 1.0f, -1.0f);                      // 顶点5
    22.         verts[5].Color = Color.Black;
    23.  
    24.         verts[6].Position = new Vector3(-1.0f, -1.0f, -1.0f);               // 顶点6
    25.         verts[6].Color = Color.LightPink;
    26.  
    27.         verts[7].Position = new Vector3(1.0f, -1.0f, -1.0f);                // 顶点7
    28.         verts[7].Color = Color.Red;
    29.  
    30.         vertexBuffer = new VertexBuffer(basicEffect.GraphicsDevice,
    31.                 VertexPositionColor.SizeInBytes * (verts.Length), BufferUsage.None);
    32.         vertexBuffer.SetData<VertexPositionColor>(verts);
    33.  
    34.         // 顶点索引,按顺序分别绘制前面、右面、上面、左面、后面和下面
    35.         short[] index = { 4, 5, 6, 5, 7, 6, 5, 1, 7, 7, 1, 3, 4, 0, 1, 4, 1, 5, 2, 0, 4, 2, 4, 6, 3, 1, 0, 3, 0, 2, 2, 6, 7, 2, 7, 3 };
    36.         triangleListIndexBuffer = new IndexBuffer(basicEffect.GraphicsDevice, sizeof(short) * index.Length, BufferUsage.None, IndexElementSize.SixteenBits);
    37.         triangleListIndexBuffer.SetData<short>(index);
    38. }
  4. 在Obstacle类中增加DrawObstacle方法,用于绘制障碍物:
    1. public void ObstacleDraw()
    2. {
    3.         basicEffect.GraphicsDevice.RenderState.CullMode = CullMode.None;
    4.         basicEffect.GraphicsDevice.VertexDeclaration = vertexDeclaration;
    5.         basicEffect.GraphicsDevice.Vertices[0].SetSource(vertexBuffer, 0, VertexPositionColor.SizeInBytes);
    6.         basicEffect.GraphicsDevice.Indices = triangleListIndexBuffer;
    7.         basicEffect.Begin();
    8.         foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
    9.         {
    10.                 pass.Begin();
    11.                 basicEffect.GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, 8, 0, 12);
    12.                 pass.End();
    13.         }
    14.         basicEffect.End();
    15. }
  5. 在Game1类中增加障碍物对象:
    1. public BasicEffect basicEffect;
    2. Obstacle obstacle;
  6. 在Game1类的Initialize方法中初始化障碍物对象:
    1.             basicEffect = new BasicEffect(graphics.GraphicsDevice, null);
    2.             basicEffect.View = view;
    3.             basicEffect.Projection = projection;
    4.             basicEffect.VertexColorEnabled = true;
    5.  
    6.             obstacle = new Obstacle();
    7.             obstacle.basicEffect = basicEffect;
  7.  在Game1类的LoadContent方法中调用障碍物对象的LoadContentObstacle方法:
    1. obstacle.LoadContentObstacle();
  8. 一段公路总是会有多个障碍物,而为了让汽车能够躲避,障碍物的距离应该为2倍车长以上,因此我们在Car类中增加以下属性:
    1. public float carDiameter;                  // 汽车的最大直径
    2. public BoundingSphere CarBoundingSphere;// 包含汽车的球,用来检测和障碍物的碰撞
  9. 同时,修改Car类的CarModel的setter方法:
    1.         public Model CarModel
    2.         {
    3.             set
    4.             {
    5.                 model = value;                    // 每当素材管道读入car.x文件,重新计算车的最大直径
    6.                 CarBoundingSphere = model.Meshes[0].BoundingSphere; // 得到包含第一个部件的球体
    7.                 for (int i = 1; i < model.Meshes.Count; i++)
    8.                 {
    9.                     //循环后,CarBoundingSphere是包含汽车所有部件的球体
    10.                     CarBoundingSphere = BoundingSphere.CreateMerged(CarBoundingSphere, model.Meshes[i].BoundingSphere); //得到一个球包含参数指定的两个球
    11.                 }
    12.  
    13.                 CarBoundingSphere.Radius *= 0.84f;                              // CarDraw方法的世界变换中车尺寸放大0.85倍
    14.                 CarBoundingSphere.Center.Z += -3.0f;                // CarDraw方法的世界变换中车位置改变
    15.                 carDiameter = CarBoundingSphere.Radius * 2;               // 车直径=(2*半径)
    16.             }
    17.         }
  10. 在Game1类的Draw方法中绘制多个障碍物:
    1.         int numberToAdd = (int)((100.0f / car.carDiameter) / 2.0f);     // 一段公路放置障碍物的最大数量
    2.         float depth = 0.0f;                                                       // 障碍物Z坐标的偏移值
    3.         float x = -2.5f;                                                                        // -2.5表示障碍物在公路的左侧
    4.  
    5.         for (int i = 0; i < numberToAdd; i++)
    6.         {
    7.                 depth = 2.0f * i * car.carDiameter;                              // 障碍物间隔为2倍车长
    8.                 basicEffect.World = Matrix.CreateTranslation(x, 0.7f, RoadDepth0 - depth);
    9.                 obstacle.ObstacleDraw();
    10.                 basicEffect.World = Matrix.CreateTranslation(x, 0.7f, RoadDepth1 - depth);
    11.                 obstacle.ObstacleDraw();
    12.  
    13.                 if (x == 2.5f)                      // 障碍物左一个,右一个
    14.                         x = -2.5f;
    15.                 else
    16.                         x = 2.5f;
    17.         }

 

此时界面上已经显示了若干障碍物,但是没有做碰撞检测,因此汽车碰到是没有任何效果的。


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter