射击子弹opengl

时间:2011-11-05 14:36:48

标签: opengl graphics 3d 2d glut

我有以下代码,它为我画了一个“太空船”,我可以用我的箭头键顺时针和逆时针旋转。当按下另一把钥匙时,我正试图让飞船射出子弹(它可以是任何钥匙)。我是OpenGL的新手,我对如何做到这一点很困惑。我尝试了很多方法,但没有一种方法可行。下面是我绘制宇宙飞船的代码以及我如何控制它。有人可以用子弹帮助我吗?

struct 
{
    float rotateSpaceCraft;
} scene; 

void SpaceCraft (){
    glBegin(GL_TRIANGLE_FAN);
    //specify the vertices to draw Ship in 2d space
    glColor3f(1.0, 0.0, 1.0);
    glVertex2f( X_CENTRE + LENGTH * 0, Y_CENTRE + LENGTH * 12); 
    glColor3f(1.0, 1.0, 0.0);
    glVertex2f( X_CENTRE - LENGTH * 8, Y_CENTRE - LENGTH * 8);
    glColor3f(0.0, 1.0, 1.0);
    glVertex2f( X_CENTRE - LENGTH  * 0, Y_CENTRE - LENGTH * 0);
    glColor3f(1.0, 0.0, 0.0);
    glVertex2f( X_CENTRE + LENGTH * 8, Y_CENTRE - LENGTH * 8);
    glEnd();
}

void display(void)
{
    glClear (GL_COLOR_BUFFER_BIT);   /* clear window */
    glColor3f(1.0, 1.0, 1.0);        /* white drawing objects */
    /* define object to be drawn as a square polygon */   

    glPushMatrix();
    glRotatef(scene.rotateSpaceCraft, 0.0, 0.0, 1.0);  
    SpaceCraft();
    glPopMatrix();
    glutSwapBuffers();

    glFlush();     /* execute drawing commands in buffer */

}

static void specialKey(int key, int x, int y)
{
    switch(key) 
    {
    case GLUT_KEY_LEFT:
        scene.rotateSpaceCraft = fmod(scene.rotateSpaceCraft + 7, 360);
        break;
    case GLUT_KEY_RIGHT:
        scene.rotateSpaceCraft = fmod(scene.rotateSpaceCraft - 7, 360);
        break;
    default:
        break;
    }
    glutPostRedisplay();
}

int main(int argc, char** argv)
{

    /* window management code ... */
   /* initialises GLUT and processes any command line arguments */  
   glutInit(&argc, argv);
   /* use single-buffered window and RGBA colour model */
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   /* window width = 400 pixels, height = 400 pixels */
   glutInitWindowSize (600, 600);
   /* window upper left corner at (100, 100) */
   glutInitWindowPosition (250, 50);
   /* creates an OpenGL window with command argument in its title bar */
   glutCreateWindow ("Asteroids");
   glutKeyboardFunc(key);
   glutSpecialFunc(specialKey);

   init();

   glutDisplayFunc(display);
   glutReshapeFunc(reshape);

   glutMainLoop();
   return 0;
}

2 个答案:

答案 0 :(得分:1)

一步一步你可以这样做:

  • 创建一个载有太空飞船旋转的太空船对象
  • 创建一个子弹对象(结构或类),它包含项目符号的向量,起始位置(以及子弹被触发的时间,稍后您将需要它) < / LI>
  • 创建一个场景对象,其中包含所有已发射的子弹和太空船的列表
  • 从Windows或您正在使用的任何其他平台抓取关键事件
  • 当子弹射击时,使用宇宙飞船的旋转和位置来确定新子弹的位置及其向量。

结构的一些伪代码:

struct Bullet {
    Vector3 Position;
    Vector3 Rotation;
}
struct {
    struct { 
        Vector3 Position;
        Vector3 Rotation;
    } Ship;
    Vector<Bullet*> Bullets;
} Scene;

...

void Update(void) {
    if (Key.IsPressed(Space)) {
        CreateNewBullet();
    }
}

void UpdateBullets(void) {
    for (Bullet bullet in Scene.Bullets)
    {
        // Delete bullets here if not longer used
        // and move all others
    }
}
void Draw(void) {
    // Draw spaceship here
    ....
    // Draw bullets
    for (Bullet bullet in Scene.Bullets) {
        DrawBullet(bullet);
    }
}

答案 1 :(得分:0)

我还建议使用VBO但是如果你想使用已弃用的集合,那么你要找的是渲染类似于你的SpaceCraft()函数的子弹。子弹将需要行进,因此您需要每帧翻译其位置。

glTranslatef(x, 0.0f, 0.0f);

这将转换x轴上的子弹x量。因此,您将需要一个每帧增加一定量的变量并将其传递给新的Bullet()函数。您可以像使用struct { float rotateSpaceCraft; } scene;

一样存储翻译X金额