c - Ball Game : Project -
i'm working on project ball have random motion, score displayed on top left corner , timer function of 1 min on top right corner. purpose player click on ball , score incremented 1 , speed of ball increase. till have made random motion, score displayed i'm not able calculate position of ball in when cursor goes on ball score needs displayed otherwise not. me in detecting mouse on moving ball. here code :
#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) /// want here detect mouse on 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(); }
you use distance formula conclude whether mouse touching ball.
- convert click location window coordinates world coordinates.
- calculate distance between center of ball , mouse.
- if distance less balls radius, mouse touching.
converting mouse position window world coordinates
since have fixed camera position , predefined window size, isn't versatile.
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; }
the more general way using gluunproject, see here 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); }
testing ball clicked part simple using distance formula.
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; }
finally can find out whether ball clicked this.
gldouble worldclickx, worldclicky; bool clicked; windowtoworld(x, y, &worldclickx, &worldclicky); clicked = ismouseoverball(ballx, bally, worldclickx, worldclicky);
good luck!
Comments
Post a Comment