65.9K
CodeProject 正在变化。 阅读更多。
Home

C# 中使用 OpenGL 的 3D 俄罗斯方块游戏的新版本

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (12投票s)

2012 年 5 月 8 日

CPOL

3分钟阅读

viewsIcon

49443

downloadIcon

4089

俄罗斯方块游戏的新版本。

引言

本文是我第一篇文章“基于 C# 和 OpenGL 的基本 3D 小行星游戏”的更新。在这个版本中,我添加了射击功能。我将在这里简要地解释一下。在最初的更新版本中,飞船包含四个火箭的网格,我不知道如何在 3D 编辑器中分离它们,所以我让飞船同时发射四个火箭。然后,用户 The_inventor 向我发送了 3D 文件,其中每个火箭都在一个单独的网格中,所以我决定重写这篇文章以包含这些更改。现在,每个导弹都单独发射。

首先要做的是获取包含四个火箭的网格并将它们放置在一个列表中

   m = ContentManager.GetModelByName("nave.3DS");
   m.CreateDisplayList();

   missiles.Add(new Missile(new Vector3(),m.GetMeshWithName("Missle1")));   
   m.RemoveMeshByName("Missle1");

   missiles.Add(new Missile(new Vector3(), m.GetMeshWithName("Missle2")));   
   m.RemoveMeshByName("Missle2");

   missiles.Add(new Missile(new Vector3(), m.GetMeshWithName("Missle3")));   
   m.RemoveMeshByName("Missle3");

   missiles.Add(new Missile(new Vector3(), m.GetMeshWithName("Missle4")));   
   m.RemoveMeshByName("Missle4"); 

获得网格引用后,我们将它们从模型中删除,因为我们将以不同于飞船的方式绘制和管理它们。

//This is the function that draws a missile

        public void Draw()
        {
            if (fired == false)
                initialPos = shipPos; 

            Gl.glPushMatrix();
            if (fired)
            {
                initialPos.Z -= 0.1f;
                Gl.glTranslatef(initialPos.X, initialPos.Y, initialPos.Z);
                if (Math.Abs(initialPos.Z) > 35)
                {
                    fired = false;
                    initialPos = shipPos;
                }
            }
            else
            {
                Gl.glTranslatef(shipPos.X, shipPos.Y, shipPos.Z);
            }

            AsteroidGenerator.CheckCollisionMissile(initialPos, 0.5f);

            Gl.glScalef(0.3f, 0.3f, 0.3f);
            Gl.glDisable(Gl.GL_TEXTURE_2D);
            //Dont have a missile texture
            //Gl.glBindTexture
            //(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("avion07.jpg"));
            missileMesh.Draw();
            Gl.glEnable(Gl.GL_TEXTURE_2D);  
            Gl.glPopMatrix();
        } 

获得导弹后,导弹可能只有两种状态:在飞船中和已发射。如果在飞船中,我不需要做任何事情,只需在每次平移飞船时平移导弹即可。

我通过以下方式处理导弹和小行星的碰撞。当发射一枚导弹时,它会检查是否与任何小行星发生碰撞。它的方式与飞船检查与小行星的碰撞方式相同,但它还做了另一件事:如果检测到碰撞,则小行星生成器类(持有小行星列表)会被告知删除该小行星并创建一个爆炸。爆炸是一个球体对象,每次绘制时,它都会扩大其尺寸,从而产生冲击波的想法,然后当达到特定尺寸时,该对象不再绘制。注意,这种爆炸波遵循粒子编程的一些概念,即随时间变化并且以特定的方式表现。

该项目有八个类,为该功能添加了两个

  • ExplosionWave.cs:这是处理爆炸的类,它是由 OpenGL 二次曲面绘制的球体对象。
  • AsteroidGenerator.cs:它处理在随机位置以随机大小和速度创建小行星。它还具有查询飞船和小行星之间是否发生碰撞的方法。
  • Asteroid.cs:它处理与小行星相关的所有事情,例如移动、纹理选择、绘制等。
  • Star.cs:它有一种创建随机白点并绘制它们的方法。
  • Camera.cs:它处理用户摄像头的选择以及设置场景的正确透视视图。
  • SpaceShip.cs:此类包含有关飞船的所有方法和属性,例如移动、绘制等。
  • Controller.cs:此类管理游戏创建、游戏逻辑,并包含运行游戏所需的所有类。这是一部分代码。
  • Missile.cs:此类处理导弹的绘制和逻辑。

这个游戏仅用于教育目的。我认为代码越简单,它就越漂亮。当然,有很多你可以改进的地方,例如用户 Death259 提出的对角线移动建议,我已将其包含在此版本中。当一颗小行星被摧毁时,我还增加了分数。

我希望收到对此示例的反馈。

历史

  • 2014 年 5 月 14 日:初始版本
© . All rights reserved.