From 9628bb86f9f31f6186b473ea3b386286c0e92623 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Tue, 9 Feb 2010 18:54:57 -0500 Subject: Add Paddle/Ball collision detection. Signed-off-by: Matt Turner --- ball.c | 102 ++++++++++++++++++++++++++++--------------------------------- ball.h | 14 ++++++--- glpong3d.c | 61 ++++++++++++++++++++---------------- glpong3d.h | 16 +++------- paddle.c | 41 +++++++++++++------------ paddle.h | 6 +++- 6 files changed, 122 insertions(+), 118 deletions(-) diff --git a/ball.c b/ball.c index e5a0c4e..f5f9876 100644 --- a/ball.c +++ b/ball.c @@ -1,31 +1,23 @@ #include "SDL.h" #include "SDL_opengl.h" +#include "glpong3d.h" #include "ball.h" -typedef struct { - Coord_t coord; - GLfloat w, h; - GLfloat r, g, b; - GLfloat xv, yv, zv; - GLfloat rotate; -} Ball_t; - -static Ball_t ball; static GLuint ball_texture; void -GLPong_BallDraw(void) { +GLPong_BallDraw(const Ball_t * ball) { glLoadIdentity(); glBindTexture(GL_TEXTURE_2D, ball_texture); glEnable(GL_TEXTURE_2D); - glColor3f(ball.r, ball.g, ball.b); - glTranslatef(ball.coord.x, ball.coord.y, ball.coord.z); + glColor3f(ball->r, ball->g, ball->b); + glTranslatef(ball->x, ball->y, ball->z); glBegin(GL_QUADS); - glTexCoord2f(0.0f, 1.0f); glVertex2f(ball.w, ball.h); /* Lower Left */ - glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, ball.h); /* Lower Right */ - glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 0.0f); /* Upper Right */ - glTexCoord2f(0.0f, 0.0f); glVertex2f(ball.w, 0.0f); /* Upper Left */ + glTexCoord2f(0.0f, 1.0f); glVertex2f(ball->w, ball->h); /* Lower Left */ + glTexCoord2f(1.0f, 1.0f); glVertex2f(0.0f, ball->h); /* Lower Right */ + glTexCoord2f(1.0f, 0.0f); glVertex2f(0.0f, 0.0f); /* Upper Right */ + glTexCoord2f(0.0f, 0.0f); glVertex2f(ball->w, 0.0f); /* Upper Left */ glEnd(); glDisable(GL_TEXTURE_2D); @@ -33,80 +25,80 @@ GLPong_BallDraw(void) { /* Lower Left */ glLoadIdentity(); glColor3f(1.0f, 0.0f, 0.0f); - glTranslatef(ball.coord.x, ball.coord.y, ball.coord.z); + glTranslatef(ball->x, ball->y, ball->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Lower Right */ glLoadIdentity(); - glTranslatef(ball.coord.x + ball.w, ball.coord.y, ball.coord.z); + glTranslatef(ball->x + ball->w, ball->y, ball->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Top Right */ glLoadIdentity(); - glTranslatef(ball.coord.x + ball.w, ball.coord.y + ball.h, ball.coord.z); + glTranslatef(ball->x + ball->w, ball->y + ball->h, ball->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Top Left */ glLoadIdentity(); - glTranslatef(ball.coord.x, ball.coord.y + ball.h, ball.coord.z); + glTranslatef(ball->x, ball->y + ball->h, ball->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); #endif glLoadIdentity(); - glTranslatef(0.0f, 0.0f, ball.coord.z); + glTranslatef(0.0f, 0.0f, ball->z); glCallList(box); } void -GLPong_BallInit(GLuint texture) { - ball.w = 0.5f; - ball.h = 0.5f; - ball.coord.x = -(ball.w / 2); - ball.coord.y = -(ball.h / 2); - ball.coord.z = GLPONG_FRONT_Z; - ball.r = 1.0f; - ball.g = 0.0f; - ball.b = 0.0f; - ball.xv = 0.02f; - ball.yv = 0.01f; - ball.zv = -0.05f; +GLPong_BallInit(Ball_t * ball, GLuint texture) { + ball->w = 0.5f; + ball->h = 0.5f; + ball->x = -(ball->w / 2); + ball->y = -(ball->h / 2); + ball->z = GLPONG_FRONT_Z; + ball->r = 1.0f; + ball->g = 0.0f; + ball->b = 0.0f; + ball->xv = 0.02f; + ball->yv = 0.01f; + ball->zv = -0.05f; ball_texture = texture; } void -GLPong_BallMove(void) { - ball.coord.x += ball.xv; - if (ball.coord.x > 1.0f) { - ball.coord.x = 1.0f; - ball.xv = -ball.xv; - } else if (ball.coord.x + ball.w < -1.0f) { - ball.coord.x = -1.0f - ball.w; - ball.xv = -ball.xv; +GLPong_BallMove(Ball_t * ball) { + ball->x += ball->xv; + if (ball->x > 1.0f) { + ball->x = 1.0f; + ball->xv = -ball->xv; + } else if (ball->x + ball->w < -1.0f) { + ball->x = -1.0f - ball->w; + ball->xv = -ball->xv; } - ball.coord.y += ball.yv; - if (ball.coord.y > 0.5f) { - ball.coord.y = 0.5f; - ball.yv = -ball.yv; - } else if (ball.coord.y + ball.h < -0.5f) { - ball.coord.y = -0.5f - ball.h; - ball.yv = -ball.yv; + ball->y += ball->yv; + if (ball->y > 0.5f) { + ball->y = 0.5f; + ball->yv = -ball->yv; + } else if (ball->y + ball->h < -0.5f) { + ball->y = -0.5f - ball->h; + ball->yv = -ball->yv; } - ball.coord.z += ball.zv; - if (ball.coord.z < GLPONG_BACK_Z) { - ball.coord.z = GLPONG_BACK_Z; - ball.zv = -ball.zv; - } else if (ball.coord.z > GLPONG_FRONT_Z) { - ball.coord.z = GLPONG_FRONT_Z; - ball.zv = -ball.zv; + ball->z += ball->zv; + if (ball->z < GLPONG_BACK_Z) { + ball->z = GLPONG_BACK_Z; + ball->zv = -ball->zv; + } else if (ball->z > GLPONG_FRONT_Z) { + ball->z = GLPONG_FRONT_Z; + ball->zv = -ball->zv; } } diff --git a/ball.h b/ball.h index bf3e849..fcda649 100644 --- a/ball.h +++ b/ball.h @@ -4,10 +4,16 @@ #include "SDL.h" #include "SDL_opengl.h" -#include "glpong3d.h" +typedef struct { + GLfloat x, y, z; + GLfloat w, h; + GLfloat r, g, b; + GLfloat xv, yv, zv; + GLfloat rotate; +} Ball_t; -void GLPong_BallDraw(void); -void GLPong_BallInit(GLuint texture); -void GLPong_BallMove(void); +void GLPong_BallDraw(const Ball_t * ball); +void GLPong_BallInit(Ball_t * ball, GLuint texture); +void GLPong_BallMove(Ball_t * ball); #endif diff --git a/glpong3d.c b/glpong3d.c index 60d720b..2fd98f6 100644 --- a/glpong3d.c +++ b/glpong3d.c @@ -1,5 +1,6 @@ #include #include +#include #include "SDL.h" #include "SDL_opengl.h" @@ -15,13 +16,15 @@ static int GLPong_Init(GLPong_t * GLPong); static int GLPong_HandleEvents(void); -static void GLPong_Draw(void); +static void GLPong_Draw(const GLPong_t * GLPong); +static bool GLPong_Collide(const Ball_t * ball, const Paddle_t * paddle); static void GLPong_CleanUp(void); -static void GLPong_Move(void); +static void GLPong_Move(GLPong_t * GLPong); static void SDL_GL_GetMouseState(GLfloat * x, GLfloat * y); static GLuint SDL_GL_SurfaceToTexture(SDL_Surface * surface); int main(int argc, char * argv[]) { + GLPong_t GLPong; unsigned int frames = 0; int done = 0; int action; @@ -45,12 +48,12 @@ int main(int argc, char * argv[]) { break; } - GLPong_Move(); + GLPong_Move(&GLPong); /* begin drawing */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - GLPong_Draw(); + GLPong_Draw(&GLPong); frames++; if (frames == 30) { @@ -137,7 +140,7 @@ GLPong_Init(GLPong_t * GLPong) { /*temp = IMG_Load("ball.png");*/ /* disabled since it's already loaded for the icon */ texture = SDL_GL_SurfaceToTexture(temp); - GLPong_BallInit(texture); + GLPong_BallInit(&GLPong->ball, texture); SDL_FreeSurface(temp); temp = IMG_Load("paddle-skyos.png"); @@ -194,16 +197,28 @@ GLPong_HandleEvents(void) { } static void -GLPong_Move(void) { +GLPong_Move(GLPong_t * GLPong) { GLfloat x, y; SDL_GL_GetMouseState(&x, &y); - GLPong_PaddleMove(&GLPong.front_paddle, x, y); + GLPong_PaddleMove(&GLPong->front_paddle, x, y); - GLPong_BallMove(); + GLPong_BallMove(&GLPong->ball); + + if (GLPong_Collide(&GLPong->ball, &GLPong->front_paddle) + || GLPong_Collide(&GLPong->ball, &GLPong->back_paddle)) { + if (GLPong->ball.zv < 0) { + GLPong->ball.zv -= 0.005f; + } else { + GLPong->ball.zv += 0.005f; + } +#ifdef DEBUG + printf("Collision: x: %.3f, y: %.2f, z: %.2f\n", GLPong->ball.x, GLPong->ball.y, GLPong->ball.z); +#endif + } } -void GLPong_Draw(void) { +void GLPong_Draw(const GLPong_t * GLPong) { float count; glColor3f(0.0f, 1.0f, 0.0f); @@ -235,29 +250,23 @@ void GLPong_Draw(void) { glVertex3f(-1.5f, 1.0f, GLPONG_BACK_Z); glEnd(); - GLPong_PaddleDraw(&GLPong.back_paddle); + GLPong_PaddleDraw(&GLPong->back_paddle); - GLPong_BallDraw(); + GLPong_BallDraw(&GLPong->ball); - GLPong_PaddleDraw(&GLPong.front_paddle); + GLPong_PaddleDraw(&GLPong->front_paddle); } -#if 0 -void GLPong_Collide(Ball_t * ball, const Paddle_t * paddle) { - if (ball->coord.z == paddle->coord.z) { - if (ball->coord.x + ball->w < paddle->coord.x) return; /* if ball is left of paddle */ - if (ball->coord.x > paddle->coord.x + paddle->w) return; /* if ball is right of paddle */ - if (ball->coord.y > paddle->coord.y + paddle->h) return; /* if ball is above paddle */ - if (ball->coord.y + ball->h < paddle->coord.y) return; /* if ball is below paddle */ - if (ball->zv < 0) { - ball->zv -= 0.005f; - } else { - ball->zv += 0.005f; - } - printf("x: %.3f, y: %.2f, z: %.2f\n", ball->coord.x, ball->coord.y, ball->coord.z); +bool GLPong_Collide(const Ball_t * ball, const Paddle_t * paddle) { + if (ball->z == paddle->z) { + if (ball->x + ball->w < paddle->x) return false; /* if ball is left of paddle */ + if (ball->x > paddle->x + paddle->w) return false; /* if ball is right of paddle */ + if (ball->y > paddle->y + paddle->h) return false; /* if ball is above paddle */ + if (ball->y + ball->h < paddle->y) return false; /* if ball is below paddle */ + return true; } + return false; } -#endif void GLPong_CleanUp(void) { diff --git a/glpong3d.h b/glpong3d.h index 13615db..1952131 100644 --- a/glpong3d.h +++ b/glpong3d.h @@ -4,6 +4,9 @@ #include "SDL.h" #include "SDL_opengl.h" +#include "ball.h" +#include "paddle.h" + #define GLPONG_WIDTH 800.0f #define GLPONG_HEIGHT 600.0f @@ -25,23 +28,12 @@ #define AMASK 0xff000000 #endif -typedef struct { - GLfloat x, y, z; -} Coord_t; - -typedef struct { - Coord_t coord; - GLfloat w, h; - GLfloat r, g, b; -} Paddle_t; - typedef struct { Paddle_t front_paddle; Paddle_t back_paddle; + Ball_t ball; } GLPong_t; -GLPong_t GLPong; - GLuint box; #endif diff --git a/paddle.c b/paddle.c index 7dcb2f2..4c4c9f0 100644 --- a/paddle.c +++ b/paddle.c @@ -14,7 +14,7 @@ GLPong_PaddleDraw(const Paddle_t * paddle) { glBindTexture(GL_TEXTURE_2D, paddle_texture); glEnable(GL_TEXTURE_2D); glColor3f(paddle->r, paddle->g, paddle->b); - glTranslatef(paddle->coord.x + (paddle->w / 2), paddle->coord.y + (paddle->h / 2), paddle->coord.z); + glTranslatef(paddle->x + (paddle->w / 2), paddle->y + (paddle->h / 2), paddle->z); glBegin(GL_QUADS); glTexCoord2f(0.168f, 1.0f); glVertex2f(paddle->w / 2, paddle->h / 2); /* Upper Right */ glTexCoord2f(0.832f, 1.0f); glVertex2f(-paddle->w / 2, paddle->h / 2); /* Upper Left */ @@ -27,33 +27,33 @@ GLPong_PaddleDraw(const Paddle_t * paddle) { /* Lower Left */ glLoadIdentity(); glColor3f(0.0f, 0.0f, 1.0f); - glTranslatef(paddle->coord.x, paddle->coord.y, paddle->coord.z); + glTranslatef(paddle->x, paddle->y, paddle->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Lower Right */ glLoadIdentity(); glColor3f(1.0f, 0.0f, 0.0f); - glTranslatef(paddle->coord.x + paddle->w, paddle->coord.y, paddle->coord.z); + glTranslatef(paddle->x + paddle->w, paddle->y, paddle->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Top Right */ glLoadIdentity(); - glTranslatef(paddle->coord.x + paddle->w, paddle->coord.y + paddle->h, paddle->coord.z); + glTranslatef(paddle->x + paddle->w, paddle->y + paddle->h, paddle->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Top Left */ glLoadIdentity(); - glTranslatef(paddle->coord.x, paddle->coord.y + paddle->h, paddle->coord.z); + glTranslatef(paddle->x, paddle->y + paddle->h, paddle->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); /* Center */ glLoadIdentity(); glColor3f(0.0f, 1.0f, 0.0f); - glTranslatef(paddle->coord.x + paddle->w / 2.0f, paddle->coord.y + paddle->h / 2.0f, paddle->coord.z); + glTranslatef(paddle->x + paddle->w / 2.0f, paddle->y + paddle->h / 2.0f, paddle->z); glBegin(GL_POINTS); glVertex3f(0.0f, 0.0f, 0.0f); glEnd(); @@ -64,9 +64,9 @@ void GLPong_PaddleInit(Paddle_t * paddle, GLfloat z, GLuint texture) { paddle->w = 0.66f; paddle->h = 0.5f; - paddle->coord.x = paddle->w / 2.0f; - paddle->coord.y = paddle->h / 2.0f; - paddle->coord.z = z; + paddle->x = paddle->w / 2.0f; + paddle->y = paddle->h / 2.0f; + paddle->z = z; paddle->r = 1.0f; paddle->g = 1.0f; paddle->b = 1.0f; @@ -76,8 +76,8 @@ GLPong_PaddleInit(Paddle_t * paddle, GLfloat z, GLuint texture) { void GLPong_PaddleMove(Paddle_t * paddle, GLfloat x, GLfloat y) { - GLfloat old_x = paddle->coord.x; - GLfloat old_y = paddle->coord.y; + GLfloat old_x = paddle->x; + GLfloat old_y = paddle->y; GLfloat mouse_x; GLfloat mouse_y; @@ -96,29 +96,30 @@ GLPong_PaddleMove(Paddle_t * paddle, GLfloat x, GLfloat y) { mouse_x = x - (paddle->w / 2.0f); mouse_y = -(y + (paddle->h / 2.0f)); - printf("(mouse_x, mouse_y) = (%.3f, %.3f)\n", mouse_x, mouse_y); +#ifdef DEBUG + printf("(mouse_x, mouse_y) = (%.3f, %.3f)\n", mouse_x, mouse_y); printf("x diff is %f\n", fabs(mouse_x - old_x)); + printf("y diff is %f\n", fabs(mouse_y - old_y)); +#endif if (fabs(mouse_x - old_x) > 0.33f / 2.0f) { if (mouse_x > old_x) { - paddle->coord.x += 0.33f / 2.0f; + paddle->x += 0.33f / 2.0f; } else { - paddle->coord.x -= 0.33f / 2.0f; + paddle->x -= 0.33f / 2.0f; } } else { - paddle->coord.x = mouse_x; + paddle->x = mouse_x; } - printf("y diff is %f\n", fabs(mouse_y - old_y)); - if (fabs(mouse_y - old_y) > 0.25f / 2.0f) { if (mouse_y > old_y) { - paddle->coord.y += 0.25f / 2.0f; + paddle->y += 0.25f / 2.0f; } else { - paddle->coord.y -= 0.25f / 2.0f; + paddle->y -= 0.25f / 2.0f; } } else { - paddle->coord.y = mouse_y; + paddle->y = mouse_y; } } diff --git a/paddle.h b/paddle.h index 14b7ed8..61962e7 100644 --- a/paddle.h +++ b/paddle.h @@ -4,7 +4,11 @@ #include "SDL.h" #include "SDL_opengl.h" -#include "glpong3d.h" +typedef struct { + GLfloat x, y, z; + GLfloat w, h; + GLfloat r, g, b; +} Paddle_t; void GLPong_PaddleDraw(const Paddle_t * paddle); void GLPong_PaddleInit(Paddle_t * paddle, GLfloat z, GLuint texture); -- cgit v1.2.3