我正在进行一项项目,其中一个球将随机运动,分数显示在左上角,计时器功能在右上角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();
}
答案 0 :(得分:0)
您可以使用距离公式来判断鼠标是否正在接触球。
将鼠标位置从窗口转换为世界坐标
由于您拥有固定的摄像机位置和预定义的窗口大小,您可以这样做,但它不是非常通用。
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,请参阅此处NeHe Productions
void windowToWorld(int windowX, int windowY, GLdouble *worldX, GLdouble *worldY){
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posZ;
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
glGetDoublev(GL_PROJECTION_MATRIX, projection);
glGetIntegerv(GL_VIEWPORT, viewport);
winX = (GLfloat)windowX;
winY = (GLfloat)viewport[3] - (float)windowY;
glReadPixels(windowX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ);
gluUnProject(winX, winY, winZ, modelview, projection, viewport, worldX, worldY, &posZ);
}
点击球测试 使用距离公式,这部分非常简单。
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);
祝你好运!