C 球赛:项目

C 球赛:项目,c,opengl,C,Opengl,我正在做一个项目,其中一个球会有随机运动,分数显示在左上角,计时器功能为1分钟在右上角。 这样做的目的是,球员将点击球,得分将增加1,球的速度将增加。 到目前为止,我已经做了随机运动,显示了分数,但我无法计算球的位置,因为当光标移动到球上时,分数需要显示,否则就不能。所以请帮我检测移动球上方的鼠标。这是我的密码: #include<GL/glut.h> #include<math.h> #include<stdbool.h> #include&l

我正在做一个项目,其中一个球会有随机运动,分数显示在左上角,计时器功能为1分钟在右上角。 这样做的目的是,球员将点击球,得分将增加1,球的速度将增加。 到目前为止,我已经做了随机运动,显示了分数,但我无法计算球的位置,因为当光标移动到球上时,分数需要显示,否则就不能。所以请帮我检测移动球上方的鼠标。这是我的密码:

    #include<GL/glut.h> 
#include<math.h> 
#include<stdbool.h> 
#include<stdio.h> 
#define PI 3.14159265f 


GLfloat ballRadius = 0.2; 
GLfloat ballX = 0.0f; 
GLfloat ballY = 0.0f; 
GLfloat ballXMax,ballXMin,ballYMax,ballYMin; 
GLfloat xSpeed = 0.02f; 
GLfloat ySpeed = 0.007f; 
int refreshMills = 30; 
int x1,xa,ya; 
int score = 0; 
int last_mx = 0, last_my = 0, cur_mx = 0, cur_my = 0; 
int arcball_on = false; 
int posx = -1,posy=0,posz=1; 
char *string; 
GLdouble clipAreaXLeft,clipAreaXRight,clipAreaYBottom,clipA reaYTop; 




void color() 
{ 
     if(score<=5) 
          glColor3f(1.0,0.0,0.0); 
     else 
          glColor3ub( rand()%250, rand()%250, rand()%250 ); 
}    
void balldisp() 
{ 
    glTranslatef(ballX,ballY,0.0f); 
    glBegin(GL_TRIANGLE_FAN); 
    color(); 
    glVertex2f(0.0f,0.0f); 
    int numSegments = 100; 

    GLfloat angle; 
    int i; 
    for(i=0;i<=numSegments;i++) 
    { 
         angle = i*2.0f*PI/numSegments; 
         glVertex2f(cos(angle)*ballRadius,sin(angle)*ballRa dius); 
    } 
    glEnd(); 

    ballX += xSpeed; 
    ballY += ySpeed; 

   if(ballX > ballXMax) 
   {
        xa=ballX; 
        ballX = ballXMax; 
        xSpeed = -xSpeed; 

   } 
   else if(ballX < ballXMin) 
   { 
        xa=ballX; 
        ballX = ballXMin; 
        xSpeed = -xSpeed; 

    } 
   if(ballY > ballYMax) 
   { 
        ya=ballY; 
        ballY = ballYMax; 
        ySpeed = -ySpeed; 

   } 
   else if(ballY < ballYMin) 
   { 
        ya=ballY; 
        ballY = ballYMin; 
        ySpeed = -ySpeed; 

    } 
} 

void scoredisp() 
{ 
    int z,j=0,k=0; 
    z=score; 
    glColor3f(1.0,0.0,0.0); 
    glLoadIdentity(); 
    glRasterPos2f(-1,1 ); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'S'); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'C'); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'O'); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'R'); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,'E'); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,' '); 
    glutBitmapCharacter (GLUT_BITMAP_TIMES_ROMAN_24,':'); 

    while(z > 9) 
    { 
        k = z % 10; 
        glRasterPos2f (-0.58,1); 
        glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,48+ k); 
        z /= 10; 
        glRasterPos2f(-0.62,1); 
     } 
     glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24,48+ z); 
} 

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
    balldisp(); 
    scoredisp(); 
    glFlush(); 
} 
void onMouse(int button, int state, int x, int y) /// I want help here to detect mouse over the ball 
{ 



    if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) 
    { 
        arcball_on = true; 
        cur_mx = x; 
        cur_my = y; 

    } 
    else 
    { 
        arcball_on = false; 
        if(cur_mx==x && cur_my==y) 
        { 
            score=score+1; 
        } 
        printf("%d",score); 
    } 



//return score; 

// xSpeed=xSpeed+0.02; 
// ySpeed=ySpeed+0.002; 
} 
void onMotion(int x, int y) 
{ 
    if (arcball_on)
    { 
        cur_mx = x; 
        cur_my = y; 
        printf("%d",cur_mx);
    } 
} 


void reshape(GLsizei width,GLsizei height) 
{ 
    if(height ==0) height = 1; 
        GLfloat aspect = (GLfloat)width / (GLfloat)height; 
        glViewport(0,0,width,height); 
        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity(); 
    if(width >=height) 
    { 
        clipAreaXLeft = -1.0 * aspect; 
        clipAreaXRight = 1.0 * aspect; 
        clipAreaYBottom = -1.0; 
        clipAreaYTop = 1.0; 
    } 
    else 
    { 
        clipAreaXLeft = -1.0; 
        clipAreaXRight = 1.0 ; 
        clipAreaYBottom = -1.0 / aspect; 
        clipAreaYTop = 1.0/ aspect; 
    } 
    gluOrtho2D(clipAreaXLeft,clipAreaXRight,clipAreaYB ottom,clipAreaYTop+0.10); 
    ballXMin = clipAreaXLeft + ballRadius; 
    ballXMax = clipAreaXRight - ballRadius; 
    ballYMin = clipAreaYBottom + ballRadius; 
    ballYMax = clipAreaYTop - ballRadius; 
} 

void Timer(int value) 
{ 
    glutPostRedisplay(); 
    glutTimerFunc(refreshMills,Timer,5); 
} 

int main(int argc,char* argv[]) 
{ 
    glutInit(&argc,argv); 
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); 
    glutInitWindowSize(500,500); 
    glutInitWindowPosition(100,100); 
    glutCreateWindow("Bouncing Ball"); 
    glutMouseFunc(onMouse); 
    glutMotionFunc(onMotion); 
    glutDisplayFunc(display); 
    glutReshapeFunc(reshape); 
    glutPostRedisplay(); 
    glutTimerFunc(0,Timer,0); 
    glutMainLoop(); 

}
#包括
#包括
#包括
#包括
#定义PI 3.14159265f
GLfloat球半径=0.2;
GLX=0.0f;
GLfloat ballY=0.0f;
GLfloat ballXMax、ballXMin、ballYMax、ballYMin;
GLX速度=0.02f;
GLYSpeed=0.007f;
int=30;
int-x1,xa,ya;
智力得分=0;
int last_mx=0,last_my=0,cur_mx=0,cur_my=0;
int arcball_on=假;
int posx=-1,posy=0,posz=1;
字符*字符串;
GLdouble CLIPAREAX LEFT、CLIPAREAX RIGHT、clipAreaYBottom、clipA REAITOP;
void color()
{ 
如果(得分ballYMax)
{ 
ya=巴里;
ballY=ballYMax;
ySpeed=-ySpeed;
} 
否则如果(巴利<巴利明)
{ 
ya=巴里;
ballY=ballYMin;
ySpeed=-ySpeed;
} 
} 
void scoredisp()
{ 
intz,j=0,k=0;
z=分数;
GL3F(1.0,0.0,0.0);
glLoadIdentity();
glRasterPos2f(-1,1);
glutBitmapCharacter(GLUT_位图_乘以罗马24,'S');
glutBitmapCharacter(GLUT_位图_乘以罗马24,'C');
glutBitmapCharacter(GLUT_位图_乘以罗马24,'O');
glutBitmapCharacter(GLUT_位图_乘以罗马24,'R');
glutBitmapCharacter(GLUT_位图_乘以罗马24,'E');
glutBitmapCharacter(GLUT_位图_乘以_罗马_24');
glutBitmapCharacter(GLUT_位图_乘以罗马24’:');
而(z>9)
{ 
k=z%10;
glRasterPos2f(-0.58,1);
glutBitmapCharacter(GLUT\u位图\u乘以罗马24,48+k);
z/=10;
glRasterPos2f(-0.62,1);
} 
glutBitmapCharacter(GLUT_位图_乘以罗马24,48+z);
} 
无效显示()
{ 
glClear(GL_颜色_缓冲_位| GL_深度_缓冲_位);
glMatrixMode(GLU模型视图);
glLoadIdentity();
balldisp();
scoredisp();
glFlush();
} 
void onMouse(int按钮、int状态、int x、int y)///我想在这里得到帮助,以检测鼠标在球上的位置
{ 
如果(按钮==GLUT\U LEFT\U按钮和状态==GLUT\U DOWN)
{ 
arcball_on=真;
cur_mx=x;
cur_my=y;
} 
其他的
{ 
arcball_on=假;
如果(cur_mx==x&&cur_my==y)
{ 
分数=分数+1;
} 
printf(“%d”,分数);
} 
//返回分数;
//xSpeed=xSpeed+0.02;
//ySpeed=ySpeed+0.002;
} 
移动时无效(整数x,整数y)
{ 
如果(电弧球打开)
{ 
cur_mx=x;
cur_my=y;
printf(“%d”,cur_mx);
} 
} 
空洞重塑(GLsizei宽度、GLsizei高度)
{ 
如果(高度==0)高度=1;
GLfloat纵横比=(GLfloat)宽度/(GLfloat)高度;
glViewport(0,0,宽度,高度);
glMatrixMode(GL_投影);
glLoadIdentity();
如果(宽度>=高度)
{ 
clipAreaXLeft=-1.0*纵横比;
clipAreaXRight=1.0*纵横比;
clipareayboottom=-1.0;
clipAreaYTop=1.0;
} 
其他的
{ 
clipAreaXLeft=-1.0;
clipAreaXRight=1.0;
clipAreaYBottom=-1.0/纵横比;
clipAreaYTop=1.0/纵横比;
} 
gluOrtho2D(clipAreaXLeft、clipAreaXRight、clipAreaYB-ottom、clipAreaYTop+0.10);
ballXMin=clipAreaXLeft+ballRadius;
ballXMax=clipAreaXRight-ballRadius;
ballYMin=clipAreaYBottom+ballRadius;
ballYMax=clipAreaYTop-球半径;
} 
无效计时器(int值)
{ 
再发现();
glutTimerFunc(刷新磨坊,计时器,5);
} 
int main(int argc,char*argv[])
{ 
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500500);
位置(100100);
玻璃窗(“弹跳球”);
glutMouseFunc(onMouse);
glutMotionFunc(onMotion);
glutDisplayFunc(显示器);
GLUTREFORUNC(重塑);
再发现();
glutTimerFunc(0,定时器,0);
glutMainLoop();
}

您可以使用距离公式来判断鼠标是否触球

  • 将单击位置从窗口坐标转换为世界坐标
  • 计算球的中心和鼠标之间的距离
  • 如果距离小于球体半径,则鼠标正在触摸
  • 将鼠标位置从窗口坐标转换为世界坐标

    因为你有一个固定的相机位置和一个预定义的窗口大小,你可以这样做,但它不是很通用

    void windowToWorld(int windowX, int windowY, GLdouble *worldX, GLdouble *worldY){
        int x = windowX - 500 / 2;
        int y = windowY - 500 / 2;
    
        *worldX = (double)x / 250.0;
        *worldY = -(double)y / 250.0;
    }
    
    更通用的方法是使用gluUnProject,请参见此处

    测试是在单击球后进行的 这一部分使用距离公式非常简单

    bool isMouseOverBall(float worldClickX, float worldClickY, float ballX, float ballY)
    {
        float distance = sqrt(pow(worldClickX - ballX, 2.0f) + pow(worldClickY - ballY, 2.0f));
        return distance < ballRadius;
    }
    

    祝你好运

    谢谢你能在我的代码中实现并显示我的时间不多了吗。。我正在努力,但这并没有发生,因为我用的是C语言,所以在WorldToWindows中按地址呼叫是行不通的。什么是替代,我没有考虑C和C++在传递引用时的差异。我已经对它进行了编辑,所以它现在应该可以在C中工作了。另外,在您粘贴的下面的代码中,if((worldClickX==0&&worldClickY==0))基本上永远不会为真。我不确定您想用它实现什么,但您几乎从不想将浮点值与==进行比较。你有一个布尔值“clicked”,表示球是否被点击,使用它。谢谢你的帮助。。。我的项目快完成了从昨天晚上开始我就在试这个
    bool isMouseOverBall(float worldClickX, float worldClickY, float ballX, float ballY)
    {
        float distance = sqrt(pow(worldClickX - ballX, 2.0f) + pow(worldClickY - ballY, 2.0f));
        return distance < ballRadius;
    }
    
        GLdouble worldClickX, worldClickY;
        bool clicked;
        windowToWorld(x, y, &worldClickX, &worldClickY);
        clicked = isMouseOverBall(ballX, ballY, worldClickX, worldClickY);