我如何更新我的openGL屏幕,使其显示每个帧?

q5iwbnjs  于 2022-11-04  发布在  其他
关注(0)|答案(2)|浏览(228)

我正在尝试模拟击退,这样只要你与矩形碰撞,你将收到击退,但我不知道如何更新屏幕,使您可以看到球员向后移动,由于它,我们可以在checkCollisionRect()函数中看到这一点,我曾尝试使用glutDisplayFunc(display)来显示向后移动的播放器的每一帧,但它不起作用,并且只更新屏幕一次循环结束,而不是循环的每次迭代结束。
密码:


# include <stdio.h>

# include <stdlib.h>

# include <GL/glut.h>

# ifdef __unix__

# include <unistd.h>

# elif defined _WIN32

# include <windows.h>

# define sleep(x) Sleep(1000 * (x))

# endif

int width=1000; //Screen width
int height=500; //Screen height
int px=200; //Player pos x
int py=100; //Player pos y
float playerSpeed=5.0;

void init(){
 glClearColor(0.3,0.3,0.3,0);
 gluOrtho2D(0,width,height,0);
}

void display(){
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 //-----------------------Draw----------------------
 checkCollisionRect(px,py,10,10,200,200,100,100);
 drawRect(200,200,100,100); //rect
 drawRect(px,py,10,10); //player
 //-------------------------------------------------
 glutSwapBuffers();
 glutPostRedisplay();
}

void drawRect(int tlx,int tly,int boxWidth,int boxHeight){
 glBegin(GL_POLYGON);
 glVertex2f(tlx,tly+boxHeight); //Bottom Left
 glVertex2f(tlx,tly); //Top Left
 glVertex2f(tlx+boxWidth,tly); //Top Right
 glVertex2f(tlx+boxWidth,tly+boxHeight); //Bottom Right
 glEnd();
}

void checkCollisionRect(x1, y1, w1, h1, x2, y2, w2, h2) {
 if (x1>x2+w2 || x1+w1<x2 || y1>y2+h2 || y1+h1<y2)
  glColor3f(0, 1, 0);
 else {
  glColor3f(1, 0, 0);
  int i;
  if (x1 < x2) {       // player hit the left wall
   for(i=0;i<10;i++){
    px -= i;
    sleep(0.1);
    display();
   }
  }
  if (x1+w1 > x2+w2) { // player hit the right wall
   for(i=0;i<10;i++){
    px += i;
    sleep(0.1);
    display();
   }
  }
  if (y1 < y2) {       // player hit the top wall
   for(i=0;i<10;i++){
    py -= i;
    sleep(0.1);
    display();

   }
  }
  if (y1+h1 > y2+h2) { // player hit the bottom wall
   for(i=0;i<10;i++){
    py += i;
    sleep(0.1);
    display();
   }
  }
 }
}

void drawSquare(px,py,size){
 glPointSize(size);
 glBegin(GL_POINTS);
 glVertex2i(px,py);
 glEnd();
}

void Buttons(unsigned char key,int x,int y){
 if(key=='a'){px-=playerSpeed;}     
 if(key=='d'){px+=playerSpeed;} 
 if(key=='w'){py-=playerSpeed;}
 if(key=='s'){py+=playerSpeed;}
}               

int main(int argc, char**argv){ 
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(width,height);
 glutCreateWindow("OpenGL");
 init();
 glutDisplayFunc(display);
 glutKeyboardFunc(Buttons);
 glutMainLoop();
 return 0;
}
62o28rlo

62o28rlo1#

这里的问题是display是递归的:它调用checkCollisionRectcheckCollisionRect在内部循环中调用display,在进程中休眠。为了解决这个问题,你需要引入一个专用的更新函数,它需要通过调用glutIdleFunc来注册。当所有事件都处理完后,它将被GLUT调用。在这个函数中,你应该执行一次游戏状态更新的迭代,调用glutPostRedisplay(不应从display btw调用)并返回,让GLUT执行显示函数并处理输入事件。

2wnc66cl

2wnc66cl2#

我已经找到了一个解决方案,虽然我一直无法找到一种方法来更新屏幕,但我已经找到了一种方法来实现敲回任何方式。这是使用一个循环内的主要绘制函数。代码:


# include <stdio.h>

# include <stdlib.h>

# include <GL/glut.h>

# ifdef __unix__

# include <unistd.h>

# elif defined _WIN32

# include <windows.h>

# define sleep(x) Sleep(1000 * (x))

# endif

# define or ||

# define and &&

int width=1000; //Screen width
int height=500; //Screen height
int px=200; //Player pos x
int py=100; //Player pos y
float playerSpeed=1.0;
int knockBackBoolRight=0;
int knockBackBoolLeft=0;
int knockBackBoolBottom=0;
int knockBackBoolTop=0;
int knockBackCounter=0;

void drawRect(int tlx,int tly,int boxWidth,int boxHeight){
 glBegin(GL_POLYGON);
 glVertex2f(tlx,tly+boxHeight); //Bottom Left
 glVertex2f(tlx,tly); //Top Left
 glVertex2f(tlx+boxWidth,tly); //Top Right
 glVertex2f(tlx+boxWidth,tly+boxHeight); //Bottom Right
 glEnd();
}

void checkCollisionRect(x1, y1, w1, h1, x2, y2, w2, h2) {
 if (x1>x2+w2 || x1+w1<x2 || y1>y2+h2 || y1+h1<y2){
 }
 else {
  if (x1 < x2) {       // player hit the left wall
   knockBackBoolLeft=1;
  }
  if (x1+w1 > x2+w2){ // player hit the right wall
   knockBackBoolRight=1;
  }
  if (y1 < y2){       // player hit the top wall
   knockBackBoolTop=1;
  }
  if (y1+h1 > y2+h2){ // player hit the bottom wall
   knockBackBoolBottom=1;
  }
 } 
}

void drawSquare(px,py,size){
 glPointSize(size);
 glBegin(GL_POINTS);
 glVertex2i(px,py);
 glEnd();
}

void Buttons(unsigned char key,int x,int y){
 if(key=='a'){px-=playerSpeed;}     
 if(key=='d'){px+=playerSpeed;} 
 if(key=='w'){py-=playerSpeed;}
 if(key=='s'){py+=playerSpeed;}
}     

void init(){
 glClearColor(0.3,0.3,0.3,0);
 gluOrtho2D(0,width,height,0);
}

void userDisplay(){
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 //---------------------Objects---------------------
 //-----------------------Draw----------------------
 drawRect(200,200,100,100); //rect
 drawRect(px,py,10,10); //player
 //---------------------Checks----------------------
 checkCollisionRect(px,py,10,10,200,200,100,100);

 if(knockBackBoolTop==1 or knockBackBoolBottom==1 or knockBackBoolLeft==1 or knockBackBoolRight==1){
  playerSpeed=0;
 }
 else{
  playerSpeed=1.0;
 }

 if(knockBackCounter<=15){
  if(knockBackBoolLeft==1){    // player hit the left wall
    knockBackCounter++;
    px-=3;
    sleep(0.01);
  }
  if(knockBackBoolTop==1){     // player hit the top wall
    knockBackCounter++;
    py-=3;
    sleep(0.01);
  }
  if(knockBackBoolRight==1){   // player hit the right wall
    knockBackCounter++;
    px+=3;
    sleep(0.01);
  }
  if(knockBackBoolBottom==1){ // player hit the bottom wall
    knockBackCounter++;    
    py+=3;
    sleep(0.01);
  }
 }
 else{
   knockBackCounter=0;
   knockBackBoolBottom=0;
   knockBackBoolTop=0;
   knockBackBoolLeft=0;
   knockBackBoolRight=0;
 }
 //-------------------------------------------------
 glutSwapBuffers();
 glutPostRedisplay();
}

void main(int argc, char**argv){ 
 glutInit(&argc, argv);
 glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
 glutInitWindowSize(width,height);
 glutCreateWindow("OpenGL");
 init();
 glutDisplayFunc(userDisplay);
 glutKeyboardFunc(Buttons);
 glutMainLoop();
}

相关问题