【问题标题】:Brick Breaker help. circles, paddles, and awkward bouncing破砖机帮助。圆圈、桨和笨拙的弹跳
【发布时间】:2011-07-26 06:11:21
【问题描述】:

我用 OpenGL 编写了一个简单的破砖游戏。球是使用 :

绘制的 2D 圆
for (float angle = 0; angle < (10); angle+=0.01)
 {
     glVertex2f((x_pos + sin(angle) * RADIUS), (y_pos + (cos(angle)) * RADIUS));
 }

当游戏更改为全屏时,这会导致失真。 RADIUS 定义为 0.025 。 我也需要帮助使桨的运动平稳。 另外,如果你玩了几次游戏,你会注意到在最左边,当球碰到球拍时,它会上升到一定的高度,然后弹回来。 完整代码:

#include <GL/openglut.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#define RADIUS 0.025
#define SPEED  0.001
int WIDTH = 900;
int HEIGHT =  650;
int RATIO = WIDTH/HEIGHT;
bool show[5][10];
float x_brick[4][9];
float y_brick[4][9];
float P_XPOS = 0;
float P_YPOS = -0.8;
bool phit_center = false , phit_corner = false;
bool game_over = false;
bool RIGHT = 1,LEFT = 0,UP = 1,DOWN = 0;
bool started = false;
float x_pos = 0,y_pos = -0.75;
bool hit = false;
int lives  = 3;
using namespace std;
void b_draw()
{
      glColor3f(1.0,0.0,0.0);
      glBegin(GL_QUADS);
      for(int a = 0; a < 9; a++)
      {
              for(int b = 0; b < 4; b++)
              {
                      if(show[b][a] == 1)
                      {
                                    glVertex2f(x_brick[b][a],y_brick[b][a]);
                                    glVertex2f(x_brick[b][a],y_brick[b][a] - 0.10); 
                                    glVertex2f(x_brick[b][a]+0.2,y_brick[b][a] - 0.10);
                                    glVertex2f(x_brick[b][a]+0.2,y_brick[b][a]);  
                      }
              }
      }
      glEnd();
}
void c_draw()
{
     glColor3f(0.0,0.0,0.0);
     glBegin(GL_TRIANGLE_FAN);
     glVertex2f(x_pos,y_pos);
     for (float angle = 0; angle < (10); angle+=0.01)
     {
         glVertex2f((x_pos + sin(angle) * RADIUS), (y_pos + (cos(angle)) * RADIUS));
     }
     glEnd();
}
bool b_hit()
{
     hit = false;
     int flag = 1;
     for(int a = 0; a < 10; a++)
     {
             for(int b =0; b < 4; b++)
             {
                     if(x_pos >= x_brick[b][a] && x_pos <= x_brick[b][a] + 0.2)
                     {
                              if(y_pos <= y_brick[b][a] && y_pos >= y_brick[b][a] - 0.1)
                              {
                                       if(show[b][a] == 1)
                                       {
                                                     show[b][a] = 0;
                                                     flag = 0;
                                                     hit = true;
                                                     break;
                                       }
                              }
                     }
             }
             if(flag == 0)
                     break;
     }
     return hit;
}
bool crashed()
{
     if(y_pos < P_YPOS - 0.05)
              return true;
     else return false;;
}
void p_hit()
{
     phit_corner = false;
     phit_center = false;
     if(x_pos <= P_XPOS + 0.13 && x_pos >= P_XPOS - 0.13)
     {
              if(y_pos <= P_YPOS)
              {
                       phit_center = true;
              }
     }
     else if((x_pos >= P_XPOS + 0.13 && x_pos <= P_XPOS + 0.2) || (x_pos <= P_XPOS - 0.13 && x_pos >= P_XPOS - 0.2))
     {
               if(y_pos <= P_YPOS)
               {
                        phit_corner = true;
               }
     }
}
 void c_move()
 {
      if(UP && RIGHT)
      {
           x_pos += (SPEED);
           y_pos += (SPEED);       
      }
      if(UP && LEFT)
      {
            x_pos -= (SPEED);
            y_pos += (SPEED);
      }
      if(DOWN && RIGHT)
      {
              x_pos += (SPEED);
              y_pos -= (SPEED);
      }
      if(DOWN && LEFT)
      {
              x_pos -= (SPEED);
              y_pos -= (SPEED);
      }
      b_hit();
      if(x_pos >= (RATIO-RADIUS))
      {
               RIGHT = 0;
               LEFT = 1;
      }
      else if(x_pos <= (-RATIO+RADIUS))
      {
           RIGHT = 1;
           LEFT = 0;
      }
      if(y_pos >= (RATIO-RADIUS) || hit )
      {
                  UP = 0;
                  DOWN = 1;
      }
      else if(y_pos <= (-RATIO+RADIUS) || hit )
      {
           UP = 1;
           DOWN = 0;
      }
      p_hit();
      if(phit_center)
      {
                     DOWN = 0;
                     UP = 1;
      }
      if(phit_corner)
      {
                     if(LEFT)
                     {
                             LEFT = 0;
                             RIGHT = 1;
                     }
                     else
                     {
                         RIGHT = 0;
                         LEFT = 1;
                     }
                     UP = 1;
                     DOWN = 0;
      }
}
void p_draw()
{
     glColor3f(0.0,0.0,0.0);
     glBegin(GL_QUADS);
                      glVertex2f(P_XPOS-0.2,P_YPOS);
                      glVertex2f(P_XPOS+0.2,P_YPOS);
                      glVertex2f(P_XPOS+0.2,P_YPOS-0.05);
                      glVertex2f(P_XPOS-0.2,P_YPOS-0.05);
     glEnd();
}

void BallLoop()
{
     glClearColor(1.0,1.0,1.0,0);
     glDisable(GL_DEPTH_TEST);
     glClear(GL_COLOR_BUFFER_BIT);
     glMatrixMode (GL_MODELVIEW);
     glLoadIdentity();
     c_draw();
     b_draw();
     p_draw();
     glFlush();
     if(started)
                c_move();
     if(crashed())
     {           
                 x_pos = 0;
                 y_pos = -0.7;
                 started = 0;
                 UP = 1;
                 RIGHT = 1;
                 DOWN = 0;
                 LEFT = 0;
     }

     glutSwapBuffers();
     glutPostRedisplay();
}
void user_input(unsigned char key, int x, int y)
{
     if(key == 13)
     started = true;
}
void ArrowKeys(int key, int x, int y)
{
     if(key==GLUT_KEY_LEFT && P_XPOS >= -0.8)
      for(float a = 0; a < 0.05; a+= 0.001)
      {
                                      P_XPOS -=0.003;
                                      BallLoop();
      }
     if(key==GLUT_KEY_RIGHT && P_XPOS <= 0.8)
     {
                            for(float a = 0; a < 0.05; a+= 0.001)
                            {
                                      P_XPOS +=0.003;
                                      BallLoop();
                            }
     }
}
void set_xy()
{
    for(int a = 0; a < 5; a++)
    {
            for(int b = 0; b < 10; b++)
            {
                    show[a][b] = 1;
            }
    }
    int c = 0;
    for(float a = -0.94; c <= 8; a+=0.21)
    {         

              for(int b = 0; b <= 5; b++)
              {
                      x_brick[b][c] = a;

              }
              c++;
    }
    int d = 0;
    for(float s = 0.99; d <= 3; s-=0.11)
    {
              for(int  r = 0; r < 9; r++)
              {
                       y_brick[d][r] = s;
              }
              d++;
    }
}
void changeSize(int w, int h) 
{

    if(h == 0)
        h = 1;
    RATIO = w/h;
    float ratio = 1.0* w / h;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glViewport(0, 0, w, h);
    glMatrixMode(GL_MODELVIEW);
    BallLoop();
}
int main(int argc, char **argv)
{
    set_xy();
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowPosition(0,0);
    glutInitWindowSize(WIDTH,HEIGHT);                    
    glutCreateWindow("Brick Breaker - By Viraj");
    glutReshapeFunc(changeSize);
    glutDisplayFunc(BallLoop);
    glutKeyboardFunc(user_input);
    glutSpecialFunc(ArrowKeys);
    glutMainLoop(); 
    return 0;
}

【问题讨论】:

标签: c++ opengl graphics geometry


【解决方案1】:

很多人都会遇到这种问题,因为他们的代码是基于写得不好的教程。一个关键错误是在重塑处理程序中进行投影矩阵设置。在任何严肃的 OpenGL 应用程序(包括游戏)中,您将在渲染期间多次切换投影 - 对于 HUD、小地图、GUI 元素等。

相反,您在显示处理程序中设置投影,就在您需要该投影之前。您也完全错过了设置投影矩阵,您只设置了视口 - 关闭,但还不够。我不会调用显示处理程序 Ball_Loop,但是,这就是我将如何修改它:

void BallLoop()
{
     const int   win_width  = glutGet(GLUT_WINDOW_WIDTH);
     const int   win_height = glutGet(GLUT_WINDOW_HEIGHT);
     const float win_aspect = (float)win_width/(float)win_height;

     glClearColor(1.0,1.0,1.0,0);
     glDisable(GL_DEPTH_TEST);
     glClear(GL_COLOR_BUFFER_BIT);

     glViewport(0, 0, win_width, win_height);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrtho(-aspect, aspect, -1, 1, -1, 1); /* those ortho limits should match your game logic */

     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     c_draw();
     b_draw();
     p_draw();
     glFlush();
     if(started)
                c_move();
     if(crashed())
     {           
                 x_pos = 0;
                 y_pos = -0.7;
                 started = 0;
                 UP = 1;
                 RIGHT = 1;
                 DOWN = 0;
                 LEFT = 0;
     }

     glutSwapBuffers();
     glutPostRedisplay();
}

编辑 完全修复和可玩的brickbreaker.cc源代码

#include <GL/glut.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <cmath>

using namespace std;

#define RADIUS 0.025

#define RATIO (4./3.)

bool show[5][10];
float x_brick[4][9];
float y_brick[4][9];

float paddle_x = 0;
float paddle_y = -0.8;
float paddle_speed = 0;
const float PaddleSpeedFactor = 3.;

bool phit_center = false , phit_corner = false;
bool game_over = false;

float speed_x = 0.;
float speed_y = 0.;

float x_pos = 0,y_pos = -0.75;
int lives  = 3;

float T_last_frame = 0.;

void draw_bricks()
{
      glColor3f(1.0,0.0,0.0);
      glBegin(GL_QUADS);
      for(int a = 0; a < 9; a++)
      {
              for(int b = 0; b < 4; b++)
              {
                      if(show[b][a] == 1)
                      {
                                    glVertex2f(x_brick[b][a],y_brick[b][a]);
                                    glVertex2f(x_brick[b][a],y_brick[b][a] - 0.10); 
                                    glVertex2f(x_brick[b][a]+0.2,y_brick[b][a] - 0.10);
                                    glVertex2f(x_brick[b][a]+0.2,y_brick[b][a]);  
                      }
              }
      }
      glEnd();
}

void ball_draw()
{
     glColor3f(0.0,0.0,0.0);
     glBegin(GL_TRIANGLE_FAN);
     glVertex2f(x_pos,y_pos);
     for (float angle = 0; angle < (10); angle+=0.01)
     {
         glVertex2f((x_pos + sin(angle) * RADIUS), (y_pos + (cos(angle)) * RADIUS));
     }
     glEnd();
}

bool brick_hit()
{
     bool hit = false;
     int flag = 1;
     for(int a = 0; a < 10; a++)
     {
             for(int b =0; b < 4; b++)
             {
                     if(x_pos >= x_brick[b][a] && x_pos <= x_brick[b][a] + 0.2)
                     {
                              if(y_pos <= y_brick[b][a] && y_pos >= y_brick[b][a] - 0.1)
                              {
                                       if(show[b][a] == 1)
                                       {
                                                     show[b][a] = 0;
                                                     flag = 0;
                                                     hit = true;
                                                     break;
                                       }
                              }
                     }
             }
             if(flag == 0)
                     break;
     }
     return hit;
}

bool crashed()
{
     if(y_pos < paddle_y - 0.05)
              return true;

     return false;
}

void paddle_hit()
{
     phit_corner = false;
     phit_center = false;
     if(x_pos <= paddle_x + 0.13 && x_pos >= paddle_x - 0.13)
     {
              if(y_pos <= paddle_y)
              {
                       phit_center = true;
              }
     }
     else if( (x_pos >= paddle_x + 0.13 && x_pos <= paddle_x + 0.2) || 
                  (x_pos <= paddle_x - 0.13 && x_pos >= paddle_x - 0.2))
     {
               if(y_pos <= paddle_y)
               {
                        phit_corner = true;
               }
     }
}

void paddle_move(float dT)
{

    if(paddle_x < RATIO && paddle_x > -RATIO)
        paddle_x += paddle_speed * PaddleSpeedFactor * dT;

        if( paddle_x > 0.95) {
        paddle_x = 0.95;
        paddle_speed = 0.;
    }

        if( paddle_x < -0.95) {
        paddle_x = -0.95;
        paddle_speed = 0.;
    }

    paddle_speed *= (1. - 0.05);
    if( fabs(paddle_speed) < 0.01 )
        paddle_speed = 0.;
}

void ball_move(float dT)
{
      x_pos += speed_x * dT;
      y_pos += speed_y * dT;

      if( brick_hit() ) {
        speed_y *= -1;
      }

      if( x_pos >= (RATIO-RADIUS) || x_pos <= (-RATIO+RADIUS ) )
      {
        speed_x *= -1;
      }

      if( y_pos >= (1.-RADIUS) )
      {
        speed_y = -1;
      }

      paddle_hit();
      if(phit_center)
      {
        speed_y = 1;
      }
      if(phit_corner)
      {
        speed_x *= -1;
        speed_y = 1;
      }
}

void paddle_draw()
{
     glColor3f(0.0,0.0,0.0);
     glBegin(GL_QUADS);
                      glVertex2f(paddle_x - 0.2, paddle_y);
                      glVertex2f(paddle_x + 0.2, paddle_y);
                      glVertex2f(paddle_x + 0.2, paddle_y - 0.05);
                      glVertex2f(paddle_x - 0.2, paddle_y - 0.05);
     glEnd();
}

void step_game()
{
     paddle_move(T_last_frame);
     ball_move(T_last_frame);

     if(crashed())
     {
    speed_x = 0;
    speed_y = 0; 
        x_pos = 0;
        y_pos = -0.7;
        paddle_speed = 0;
        paddle_x = 0;
     }

     glutPostRedisplay();
}

void launch_ball()
{
    speed_y = 1.;
    speed_x = 1.;
}

void user_input(unsigned char key, int x, int y)
{
     if(key == 13)
        launch_ball();
}

void ArrowKeys(int key, int x, int y)
{
     if(key==GLUT_KEY_LEFT)
        paddle_speed = -1.;

     if(key==GLUT_KEY_RIGHT)
        paddle_speed = +1.;
}

void set_xy()
{
    for(int a = 0; a < 5; a++)
    {
            for(int b = 0; b < 10; b++)
            {
                    show[a][b] = 1;
            }
    }
    int c = 0;
    for(float a = -0.94; c <= 8; a+=0.21)
    {         

              for(int b = 0; b <= 5; b++)
              {
                      x_brick[b][c] = a;

              }
              c++;
    }
    int d = 0;
    for(float s = 0.99; d <= 3; s-=0.11)
    {
              for(int  r = 0; r < 9; r++)
              {
                       y_brick[d][r] = s;
              }
              d++;
    }
}

void display()
{
    const int win_width  = glutGet(GLUT_WINDOW_WIDTH);
    const int win_height = glutGet(GLUT_WINDOW_HEIGHT);
    const float win_aspect = (float)win_width / (float)win_height;

    glViewport(0, 0, win_width, win_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if(win_aspect > RATIO) {
        glOrtho(-win_aspect, win_aspect, -1., 1., -1., 1.);
    } else {
        glOrtho(-RATIO, RATIO, -RATIO/win_aspect, RATIO/win_aspect, -1., 1.);
    }

    glMatrixMode(GL_MODELVIEW);

    glClearColor(0., 0., 1., 1.);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBegin(GL_QUADS);
        glColor3f(1,1,1);
        glVertex2f(-RATIO, -1);
        glVertex2f(RATIO, -1);
        glVertex2f(RATIO, 1);
        glVertex2f(-RATIO, 1);
        glEnd();

    draw_bricks();
    paddle_draw();
    ball_draw();

    glutSwapBuffers();

        // GLUT doesn't offer cross plattform timing
        // assume 60Hz refresh rate
        T_last_frame = 1./60.;
}

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

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

    glutInitWindowPosition(0,0);
    glutInitWindowSize(800, 600);

    glutCreateWindow("Brick Breaker - By Viraj");
    glutDisplayFunc(display);

    glutKeyboardFunc(user_input);
    glutSpecialFunc(ArrowKeys);

    glutIdleFunc(step_game);

    glutMainLoop(); 

    return 0;
}

EDIT 2 为了完整起见,这里是 GLFW 版本

#include <GL/glfw.h>

#include <stdlib.h>
#include <math.h>

using namespace std;

#define RADIUS 0.025

#define RATIO (4./3.)

bool show[5][10];
float x_brick[4][9];
float y_brick[4][9];

const float SpeedFactor = 10.;

float paddle_x = 0;
float paddle_y = -0.8;
float paddle_speed = 0;
const float PaddleSpeedFactor = 3.;

bool phit_center = false, phit_corner = false;
bool game_over = false;

float speed_x = 0.;
float speed_y = 0.;

float x_pos;
float y_pos;
int lifes = 0;

void draw_bricks()
{
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_QUADS);
    for (int a = 0; a < 9; a++) {
        for (int b = 0; b < 4; b++) {
            if (show[b][a] == 1) {
                glVertex2f(x_brick[b][a], y_brick[b][a]);
                glVertex2f(x_brick[b][a], y_brick[b][a] - 0.10);
                glVertex2f(x_brick[b][a] + 0.2,
                       y_brick[b][a] - 0.10);
                glVertex2f(x_brick[b][a] + 0.2, y_brick[b][a]);
            }
        }
    }
    glEnd();
}

void ball_draw()
{
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_TRIANGLE_FAN);
    glVertex2f(x_pos, y_pos);
    for (float angle = 0; angle < (10); angle += 0.01) {
        glVertex2f((x_pos + sin(angle) * RADIUS),
               (y_pos + (cos(angle)) * RADIUS));
    }
    glEnd();
}

bool brick_hit()
{
    for (int a = 0; a < 10; a++) {
        for (int b = 0; b < 4; b++) {
            if (x_pos >= x_brick[b][a]
                && x_pos <= x_brick[b][a] + 0.2) {
                if (y_pos <= y_brick[b][a]
                    && y_pos >= y_brick[b][a] - 0.1) {
                    if (show[b][a] == 1) {
                        show[b][a] = 0;
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

bool crashed()
{
    if (y_pos < paddle_y - 0.05)
        return true;

    return false;
}

void paddle_hit()
{
    phit_corner = false;
    phit_center = false;
    if (x_pos <= paddle_x + 0.13 && x_pos >= paddle_x - 0.13) {
        if (y_pos <= paddle_y) {
            phit_center = true;
        }
    } else if ((x_pos >= paddle_x + 0.13 && x_pos <= paddle_x + 0.2) ||
           (x_pos <= paddle_x - 0.13 && x_pos >= paddle_x - 0.2)) {
        if (y_pos <= paddle_y) {
            phit_corner = true;
        }
    }
}

void paddle_move(float dT)
{

    if (paddle_x < RATIO && paddle_x > -RATIO)
        paddle_x += paddle_speed * PaddleSpeedFactor * dT;

    if (paddle_x > 1.) {
        paddle_x = 1.;
        paddle_speed = 0.;
    }

    if (paddle_x < -1.) {
        paddle_x = -1.;
        paddle_speed = 0.;
    }
}

void ball_move(float dT)
{
    x_pos += speed_x * dT;
    y_pos += speed_y * dT;

    if (brick_hit()) {
        speed_y *= -1;
    }

        if (x_pos >= (RATIO - RADIUS) || x_pos <= (-RATIO + RADIUS)) {
        speed_x *= -1;
    }

    if (y_pos >= (1. - RADIUS)) {
        speed_y = -1;
    }

    paddle_hit();
    if (phit_center) {
        speed_y = 1;
    }
    if (phit_corner) {
        speed_x *= -1;
        speed_y = 1;
    }
}

void paddle_draw()
{
    glColor3f(0.0, 0.0, 0.0);
    glBegin(GL_QUADS);
    glVertex2f(paddle_x - 0.2, paddle_y);
    glVertex2f(paddle_x + 0.2, paddle_y);
    glVertex2f(paddle_x + 0.2, paddle_y - 0.05);
    glVertex2f(paddle_x - 0.2, paddle_y - 0.05);
    glEnd();
}

void reset_game()
{
    lifes = 3;
    speed_x = 0;
    speed_y = 0;
    x_pos = 0;
    y_pos = -0.7;
    paddle_speed = 0;
    paddle_x = 0;
}

void step_game(float dT)
{
    if(!lifes)
        return;

    paddle_move(dT * SpeedFactor);
    ball_move(dT * SpeedFactor);

    if (crashed()) {
        lifes--;
        speed_x = 0;
        speed_y = 0;
        x_pos = 0;
        y_pos = -0.7;
    }
}

void launch_ball()
{
    if(!lifes)
        return;

    speed_y = 1.;
    speed_x = 1.;
}

void keyboard(int key, int action)
{
    switch(key) 
    {
    case GLFW_KEY_ENTER:
        launch_ball();
        break;

    case GLFW_KEY_ESC:
        reset_game();
        break;

    case GLFW_KEY_LEFT:
        switch(action) {
        case GLFW_PRESS:
            paddle_speed = -1.;
            break;

        case GLFW_RELEASE:
            paddle_speed = 0;
            break;
        } break;

    case GLFW_KEY_RIGHT:
        switch(action) {
        case GLFW_PRESS:
            paddle_speed = 1.;
            break;

        case GLFW_RELEASE:
            paddle_speed = 0;
            break;
        } break;
    }
}

void set_xy()
{
    for (int a = 0; a < 5; a++) {
        for (int b = 0; b < 10; b++) {
            show[a][b] = 1;
        }
    }
    int c = 0;
    for (float a = -0.94; c <= 8; a += 0.21) {

        for (int b = 0; b <= 5; b++) {
            x_brick[b][c] = a;

        }
        c++;
    }
    int d = 0;
    for (float s = 0.99; d <= 3; s -= 0.11) {
        for (int r = 0; r < 9; r++) {
            y_brick[d][r] = s;
        }
        d++;
    }
}

float display()
{
    int win_width;
    int win_height;
    glfwGetWindowSize(&win_width, &win_height);
    const float win_aspect = (float)win_width / (float)win_height;

    glfwSetTime(0.);

    glViewport(0, 0, win_width, win_height);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (win_aspect > RATIO) {
        glOrtho(-win_aspect, win_aspect, -1., 1., -1., 1.);
    } else {
        glOrtho(-RATIO, RATIO, -RATIO / win_aspect, RATIO / win_aspect,
            -1., 1.);
    }

    glMatrixMode(GL_MODELVIEW);

    glClearColor(0., 0., 1., 1.);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBegin(GL_QUADS);
    glColor3f(1, 1, 1);
    glVertex2f(-RATIO, -1);
    glVertex2f(RATIO, -1);
    glVertex2f(RATIO, 1);
    glVertex2f(-RATIO, 1);
    glEnd();

    draw_bricks();
    paddle_draw();

    ball_draw();

    glfwSwapBuffers();
    return glfwGetTime();
}

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

    if( GL_FALSE == glfwInit() )
        return -1;

    if( GL_FALSE == glfwOpenWindow(800, 600, 8, 8, 8, 8, 0, 0, GLFW_WINDOW) )
        return -2;

    glfwSetWindowTitle("Viraj's Brick Breaker - GLFW version by datenwolf");
    glfwSetKeyCallback(keyboard);

    reset_game();

    while( glfwGetWindowParam(GLFW_OPENED) ) {
        glfwPollEvents();
        float const dT = display();
        step_game(dT);
    }

    glfwTerminate();

    return 0;
}

【讨论】:

  • 好吧,谢谢 :) 但它不能解决桨有点生涩和缓慢的问题。
  • @viraj:桨的生涩和缓慢是您的输入管理的一个问题。看起来您正在部分地在显示功能中执行游戏逻辑。不是理想的地方。将游戏逻辑放在空闲函数中,使用输入回调设置输入标志(哪些键被按下/按下,鼠标按下/按下鼠标按钮等,鼠标移动处理程序应该累积移动事件)并应用这些输入标记关于游戏状态。还要测量渲染和显示帧所需的时间,并使用它来提高您的游戏时间。本质上,你不应该混合渲染和游戏逻辑——解决这个问题。
  • 另外,我想在底部渲染 3 颗心。我使用方程式来绘制点并绘制心形。我把它放在显示功能中,但这会使事情变得非常缓慢。函数:mod(x)-sqrt(1-xx); mod(x)+sqrt(1-xx);
  • @datewolf 我应该在 idle 或 diplay 函数中调用 move() 函数吗?
  • @viraj:空闲函数,但坦率地说,对于用于游戏的框架来说,GLUT 不是最佳选择。您现在正面临一个问题:您无法控制事件循环。在事件回调中设置标志(哪些键被按下/按下)并在游戏逻辑中做出适当的反应。您将面临的问题之一是游戏逻辑和显示之间的时间安排。但是在显示回调中做游戏逻辑会让你的游戏卡顿。理想情况下,您会使用 GLFW 之类的东西,在单独的线程中执行所有事件处理和游戏逻辑,提前计算下一帧。
【解决方案2】:

我认为您的失真是由于您的 changeSize(...) 函数:您计算窗口的纵横比,但您不使用它。看看你从哪里偷了这个 sn-p 的代码:)

切换到全屏模式时,您会更改屏幕分辨率吗?如果这样做,则很可能像素不再是正方形,因此您需要屏幕的实际纵横比。

【讨论】:

    猜你喜欢
    • 2011-10-17
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 2023-03-05
    • 2022-01-19
    相关资源
    最近更新 更多