在本文中,将探讨如何使用C#和OpenGL开发一个3D小行星射击游戏。将重点介绍射击功能的实现。在游戏的初始版本中,飞船包含了四个火箭的网格模型,但当时不知道如何在3D编辑器中将它们分离,因此飞船会同时发射四个火箭。后来,用户The_inventor提供了一个包含每个火箭单独网格的3D文件,这促使重写这篇文章,以包含这些变化。现在,每个导弹都可以单独发射。
首先,需要获取包含四个火箭的网格模型,并将它们添加到一个列表中:
var 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");
获取网格引用后,将其从模型中删除,因为将以与飞船不同的方式绘制和管理它们。
下面是绘制导弹的函数:
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);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, ContentManager.GetTextureByName("avion07.jpg"));
missileMesh.Draw();
Gl.glEnable(Gl.GL_TEXTURE_2D);
Gl.glPopMatrix();
}
获取导弹后,导弹可能只有两种状态:在飞船中和发射后。如果它在飞船中,不需要做任何事情,只需在每次移动飞船时移动导弹即可。
以以下方式处理导弹与小行星的碰撞。当导弹发射时,它会检查是否与任何小行星发生碰撞。它与飞船检查与小行星碰撞的方式相同,但它还做了另一件事:如果检测到碰撞,它会告诉持有小行星列表的小行星生成器类删除那个小行星并创建一个爆炸。爆炸是一个球体对象,每次绘制时都会扩大其大小,给人一种冲击波的感觉,然后当达到特定大小时,对象不再绘制。注意,这种爆炸波遵循一些粒子编程的概念,即在一定时间内存活并以特定方式表现。
该项目有八个类,为这个功能添加了两个:
以下是其他类的简要说明:
这个游戏仅用于教育目的。认为代码越简单,就越美观。当然,还有很多可以改进的地方,比如用户Death259提出的对角线移动建议,已经包含在这个版本中。还增加了当小行星被摧毁时的得分。