射击子弹opengl

发布于 2024-12-14 03:32:25 字数 2202 浏览 3 评论 0原文

我有以下代码,它画了一个“宇宙飞船”,我可以用箭头键控制它顺时针和逆时针旋转。我试图让航天器在按下另一个键(可以是任何键)时发射子弹。我对 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;
}

I have the following code which draws me a "spacecraft" which I'm able to ctrol with my arrow keys to spin clockwise and anti-clockwise. I'm trying to get the spacecraft shoot bullets when another key is pressed (it can be any key). I am so new to OpenGL that I'm confused on how to do it. I have tried so many methods but none of them work. Below is the code where I draw my spaceship and how I control it. Can someone help me with the bullets please?

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧情别恋 2024-12-21 03:32:25

一步一步地,你可以这样做:

  • 创建一个宇宙飞船对象,它保存宇宙飞船的旋转
  • 创建一个子弹对象( struct 或 class ),它保存子弹的矢量、起始位置 ( 以及时间子弹已发射,稍后您将需要它)
  • 创建一个场景对象,其中包含所有发射的子弹和宇宙飞船的列表
  • 从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);
    }
}

Step by Step you could do it this way:

  • Create a spaceship object which holds rotation of the spaceship
  • Create a bullet object ( struct or class ), which holds the vector of the bullet, the start position ( and the time at which the bullet has been fired, you will need it later )
  • Create a scene object which holds a list of all bullets fired and the spaceship
  • Catch Key Events from Windows or any other platform you are using
  • When the bullet is fired, use the rotation and position of your spaceship to determine the position of the new bullet and the vector of it.

Some pseudo code for the structure:

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);
    }
}
瑶笙 2024-12-21 03:32:25

我还建议使用 VBO,但如果您想使用已弃用的集合来执行此操作,那么您需要的是渲染类似于 SpaceCraft() 函数的项目符号。子弹需要移动,因此您需要每帧平移它的位置。

glTranslatef(x, 0.0f, 0.0f);

这将在 x 轴上平移项目符号 x 数量。因此,您将需要一个变量,该变量每帧增加一定量并将其传递给新的 Bullet() 函数。您可以像使用 struct 一样存储翻译 X 数量
{
浮动旋转航天器;
} 场景;

I also recommend using VBO but if you want to do it with the deprecated set then what you are looking for is to render a bullet similar to your SpaceCraft() function. A bullet will need to travel so you will need to translate its position every frame.

glTranslatef(x, 0.0f, 0.0f);

This will translate the bullet x amount in the x axis. Therefore you will need a variable that increments certain amount per frame and passes it to your new Bullet() function. You can store the translation X amount just like you did with struct
{
float rotateSpaceCraft;
} scene;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文