diff --git a/breakout/breakout.c b/breakout/breakout.c index 8644b33..cf7e1b4 100644 --- a/breakout/breakout.c +++ b/breakout/breakout.c @@ -1,7 +1,6 @@ #ifdef _WIN32 #include #include -#define _ #else #include #endif @@ -10,6 +9,11 @@ #include #include +typedef struct coord { + double x; + double y; +} coord; + typedef struct colour { double r; double g; @@ -39,15 +43,36 @@ typedef struct brick { int y; int width; int height; - struct brick *container; } brick; +typedef struct brickCD { + char isLeaf; + int x; + int y; + int width; + int height; + struct brickCD *container; + int brickID; +} brickCD; + +double heronsFormula(coord a, coord b, coord c) { + double A = sqrt(pow((a.x - b.x), 2) + pow((a.y - b.y), 2)); + double B = sqrt(pow((b.x - c.x), 2) + pow((b.y - c.y), 2)); + double C = sqrt(pow((c.x - a.x), 2) + pow((c.y - a.y), 2)); + double s = (A + B + C) / 2; + return sqrt(s*(s - A)*(s - B)*(s - C)); +} +char vertexWithinQuad(coord point, coord *quad); + void updatePaddle(Uint32 tickrate, paddle *thePaddle, char moveX, int winWidth, int winHeight); void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth, int winHeight); void drawPaddle(paddle *thePaddle, int winWidth, int winHeight, colour *c); void drawBall(ball *theBall, colour *c); void drawBg(int winWidth, int winHeight, colour *c1, colour *c2); +void drawBricks(brick *bricks, int brickCount, int winWidth, int winHeight, colour *colours); + +void initialiseBricks(brick *bricks, int *brickCount); int main(void) { @@ -149,50 +174,14 @@ int main(void) { char moveX=0; - brick bricklayout = { - .brickType = 0, - .x = 0, - .y = 0, - .width = winWidth, - .height = winHeight, - .container = malloc(sizeof(brick)*2), - }; - - bricklayout.container[0] = (brick) { - .brickType = 1, - .x = 0, - .y = 0, - .width = 100, - .height = 10, - .container = NULL - }; - - bricklayout.container[1] = (brick) { - .brickType = 1, - .x = 108, - .y = 0, - .width = 100, - .height = 10, - .container = NULL - }; - - char msgtxt[100]; - sprintf(msgtxt, "Array seems to be %d long", sizeof(bricklayout.container)); - MessageBox(0, msgtxt, "Debug info", MB_OK); - - for (int i=0; i<(sizeof(*bricklayout.container) / sizeof(bricklayout.container[0]));i++) { - char msgtxt[100]; - sprintf(msgtxt, "Brick type %d, x %d, y %d, width %d, height %d", bricklayout.container[i].brickType, bricklayout.container[i].x, bricklayout.container[i].y, bricklayout.container[i].width, bricklayout.container[i].height); - MessageBox(0, msgtxt, "Debug info", MB_OK); - } - - //char isArray; - //int x; - //int y; - //int width; - //int height; - //brick *container; - //char brickType; + brick bricks[128]; + int brickCount; + colour brickColours[4]; + brickColours[3] = (colour) { .r = 1.0000 /*255*/, .g = 0.2510 /*64 */, .b = 0.6549 /*167*/, .a = 1 }; + brickColours[2] = (colour) { .r = 0.4588 /*117*/, .g = 0.5490 /*140*/, .b = 1.0000 /*255*/, .a = 1 }; + brickColours[1] = (colour) { .r = 0.3490 /*89 */, .g = 0.8706 /*222*/, .b = 1.0000 /*255*/, .a = 1 }; + brickColours[0] = (colour) { .r = 1.0000 /*255*/, .g = 0.7569 /*193*/, .b = 0.1216 /*31 */, .a = 1 }; + initialiseBricks(&bricks, &brickCount); ball theBall = { .x = 0, @@ -297,17 +286,14 @@ int main(void) { paddleCol.r = 1.0; paddleCol.g = 1.0; paddleCol.b = 1.0; paddleCol.a = 1.0; colour bgcol1; colour bgcol2; - //bgcol1.r = 0.0824; /*21*/ bgcol2.r = 0.7216; /*184*/ - //bgcol1.g = 0.0901; /*23*/ bgcol2.g = 0.2471; /*63*/ - //bgcol1.b = 0.4431; /*113*/ bgcol2.b = 0.6078; /*155*/ - //bgcol1.a = 1.0000; /*255*/ bgcol2.a = 1.0000; /*255*/ - bgcol1.r = 0.1500; bgcol2.r = 0.3500; - bgcol1.g = 0.1500; bgcol2.g = 0.3500; - bgcol1.b = 0.1500; bgcol2.b = 0.3500; - bgcol1.a = 1.0000; bgcol2.a = 1.0000; + bgcol1.r = 0.7216; /*184*/ bgcol2.r = 0.0824; /*21 */ + bgcol1.g = 0.2471; /*63 */ bgcol2.g = 0.0901; /*23 */ + bgcol1.b = 0.6078; /*155*/ bgcol2.b = 0.4431; /*113*/ + bgcol1.a = 1.0000; /*255*/ bgcol2.a = 1.0000; /*255*/ drawPaddle(&thePaddle, winWidth, winHeight, &paddleCol); drawBall(&theBall, &paddleCol); + drawBricks(&bricks, brickCount, winWidth, winHeight, &brickColours); drawBg(winWidth, winHeight, &bgcol1, &bgcol2); glFlush(); @@ -332,6 +318,20 @@ int main(void) { return 0; } +char vertexWithinQuad(coord point, coord *quad) { + double quadArea = heronsFormula(quad[0], quad[1], quad[2]) + heronsFormula(quad[1], quad[2], quad[3]); + double testArea = 0; + testArea += heronsFormula(point, quad[0], quad[1]); + testArea += heronsFormula(point, quad[1], quad[2]); + testArea += heronsFormula(point, quad[2], quad[3]); + testArea += heronsFormula(point, quad[3], quad[0]); + if (testArea == quadArea) { + return 1; + } else { + return 0; + } +} + void updatePaddle(Uint32 tickrate, paddle *thePaddle, char moveX, int winWidth, int winHeight) { thePaddle->x += moveX * 0.5 * tickrate; if (thePaddle->x < 0-(thePaddle->width/2)) thePaddle->x = 0-(thePaddle->width/2); @@ -339,16 +339,38 @@ void updatePaddle(Uint32 tickrate, paddle *thePaddle, char moveX, int winWidth, } void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth, int winHeight) { - double ballNX = theBall->x + theBall->vX; // Calculates the position of the ball on the next step + double ballNX = theBall->x + theBall->vX; // Calculates the position of the ball's centre on the next step double ballNY = theBall->y + theBall->vY; double paddleRX = thePaddle->x - (double)(winWidth / 2); double paddleRY = 20 - (double)(winHeight / 2); - if (ballNX+theBall->radius > paddleRX && ballNY-theBall->radius < paddleRY && // If to the right and below the top left corner of paddle - ballNX-theBall->radius < paddleRX + (double)thePaddle->width && // ...and to the left of the right side of the paddle - ballNY > (paddleRY-thePaddle->height)) { // ...and above the bottom of the paddle (all now compensating for ball radius) - theBall->vY *= -1.0; - theBall->vX = ((ballNX - paddleRX - (double)(thePaddle->width/2))/((double)thePaddle->width/2))*0.5; // Sets X velocity to be proportional to the relative position of the ball and the paddle on collision + coord paddle[4] = { + { .x = paddleRX, .y = paddleRY }, + { .x = paddleRX, .y = paddleRY+thePaddle->height }, + { .x = paddleRX+thePaddle->width, .y = paddleRY+thePaddle->height }, + { .x = paddleRX+thePaddle->width, .y = paddleRY }, + }; + + // Collision with paddle + // (Testing each vertex of ball) + + char colliding = 0; + int mults[4] = { -1,-1,1,1 }; + + for (int i = 0, j = 3; i < 4; i++, j++) { + coord ballN = { .x = ballNX+(theBall->radius*mults[i%4]), .y = ballNY+(theBall->radius*mults[j%4]) }; + if (vertexWithinQuad(ballN, paddle)) colliding = 1; + } + + if (colliding) { + if (theBall->x + theBall->radius < paddleRX) { // Left side collision + theBall->vX *= -1.0; + } else if (theBall->x - theBall->radius > paddleRX + thePaddle->width) { // Right side collision + theBall->vX *= -1.0; + } else { + theBall->vY *= -1.0; + theBall->vX = ((ballNX - paddleRX - (double)(thePaddle->width / 2)) / ((double)thePaddle->width / 2))*0.5; // Sets X velocity to be proportional to the relative position of the ball and the paddle on collision + } } if (ballNX > winWidth / 2 || ballNX < (-1.0*winWidth/2)) { // Collision with walls @@ -412,12 +434,150 @@ void drawBall(ball *theBall, colour *c) { glBegin(GL_QUADS); glColor3f(c->r, c->g, c->b); - glVertex3d(0.0, 0.0, 0.0); - glVertex3d(0.0, 8.0, 0.0); - glVertex3d(8.0, 8.0, 0.0); - glVertex3d(8.0, 0.0, 0.0); + glVertex3d(-1.0*theBall->radius, 1.0*theBall->radius, 0.0); + glVertex3d(-1.0*theBall->radius, -1.0*theBall->radius, 0.0); + glVertex3d( 1.0*theBall->radius, -1.0*theBall->radius, 0.0); + glVertex3d( 1.0*theBall->radius, 1.0*theBall->radius, 0.0); glEnd(); glPopMatrix(); glMatrixMode(matrixmode); } + +void drawBricks(brick *bricks, int brickCount, int winWidth, int winHeight, colour *colours) { + for (int i = 0; i < brickCount; i++) { + GLint matrixmode = 0; + glGetIntegerv(GL_MATRIX_MODE, &matrixmode); + glPushMatrix(); + glTranslated((double)bricks[i].x-(winWidth/2), (double)bricks[i].y, 0.0); + glBegin(GL_QUADS); + glColor3f( + colours[bricks[i].brickType-1].r, + colours[bricks[i].brickType-1].g, + colours[bricks[i].brickType-1].b + ); + glVertex3d(0.0, 0.0, 0.0); + glVertex3d(0.0, (double)bricks[i].height, 0.0); + glVertex3d((double)bricks[i].width, (double)bricks[i].height, 0.0); + glVertex3d((double)bricks[i].width, 0.0, 0.0); + glEnd(); + glPopMatrix(); + glMatrixMode(matrixmode); + } +} + +void initialiseBricks(brick *bricks, int *brickCount) { + bricks[0 ] = (brick) { .brickType = 1, .x = 17, .y = 130, .width = 30, .height = 10 }; + bricks[1 ] = (brick) { .brickType = 1, .x = 49, .y = 130, .width = 30, .height = 10 }; + bricks[2 ] = (brick) { .brickType = 1, .x = 81, .y = 130, .width = 30, .height = 10 }; + bricks[3 ] = (brick) { .brickType = 1, .x = 113, .y = 130, .width = 30, .height = 10 }; + bricks[4 ] = (brick) { .brickType = 1, .x = 145, .y = 130, .width = 30, .height = 10 }; + bricks[5 ] = (brick) { .brickType = 1, .x = 177, .y = 130, .width = 30, .height = 10 }; + bricks[6 ] = (brick) { .brickType = 1, .x = 209, .y = 130, .width = 30, .height = 10 }; + bricks[7 ] = (brick) { .brickType = 1, .x = 241, .y = 130, .width = 30, .height = 10 }; + bricks[8 ] = (brick) { .brickType = 1, .x = 273, .y = 130, .width = 30, .height = 10 }; + bricks[9 ] = (brick) { .brickType = 1, .x = 305, .y = 130, .width = 30, .height = 10 }; + bricks[10 ] = (brick) { .brickType = 1, .x = 337, .y = 130, .width = 30, .height = 10 }; + bricks[11 ] = (brick) { .brickType = 1, .x = 369, .y = 130, .width = 30, .height = 10 }; + bricks[12 ] = (brick) { .brickType = 1, .x = 401, .y = 130, .width = 30, .height = 10 }; + bricks[13 ] = (brick) { .brickType = 1, .x = 433, .y = 130, .width = 30, .height = 10 }; + bricks[14 ] = (brick) { .brickType = 1, .x = 17, .y = 142, .width = 30, .height = 10 }; + bricks[15 ] = (brick) { .brickType = 1, .x = 49, .y = 142, .width = 30, .height = 10 }; + bricks[16 ] = (brick) { .brickType = 1, .x = 81, .y = 142, .width = 30, .height = 10 }; + bricks[17 ] = (brick) { .brickType = 1, .x = 113, .y = 142, .width = 30, .height = 10 }; + bricks[18 ] = (brick) { .brickType = 1, .x = 145, .y = 142, .width = 30, .height = 10 }; + bricks[19 ] = (brick) { .brickType = 1, .x = 177, .y = 142, .width = 30, .height = 10 }; + bricks[20 ] = (brick) { .brickType = 1, .x = 209, .y = 142, .width = 30, .height = 10 }; + bricks[21 ] = (brick) { .brickType = 1, .x = 241, .y = 142, .width = 30, .height = 10 }; + bricks[22 ] = (brick) { .brickType = 1, .x = 273, .y = 142, .width = 30, .height = 10 }; + bricks[23 ] = (brick) { .brickType = 1, .x = 305, .y = 142, .width = 30, .height = 10 }; + bricks[24 ] = (brick) { .brickType = 1, .x = 337, .y = 142, .width = 30, .height = 10 }; + bricks[25 ] = (brick) { .brickType = 1, .x = 369, .y = 142, .width = 30, .height = 10 }; + bricks[26 ] = (brick) { .brickType = 1, .x = 401, .y = 142, .width = 30, .height = 10 }; + bricks[27 ] = (brick) { .brickType = 1, .x = 433, .y = 142, .width = 30, .height = 10 }; + bricks[28 ] = (brick) { .brickType = 2, .x = 17, .y = 154, .width = 30, .height = 10 }; + bricks[29 ] = (brick) { .brickType = 2, .x = 49, .y = 154, .width = 30, .height = 10 }; + bricks[30 ] = (brick) { .brickType = 2, .x = 81, .y = 154, .width = 30, .height = 10 }; + bricks[31 ] = (brick) { .brickType = 2, .x = 113, .y = 154, .width = 30, .height = 10 }; + bricks[32 ] = (brick) { .brickType = 2, .x = 145, .y = 154, .width = 30, .height = 10 }; + bricks[33 ] = (brick) { .brickType = 2, .x = 177, .y = 154, .width = 30, .height = 10 }; + bricks[34 ] = (brick) { .brickType = 2, .x = 209, .y = 154, .width = 30, .height = 10 }; + bricks[35 ] = (brick) { .brickType = 2, .x = 241, .y = 154, .width = 30, .height = 10 }; + bricks[36 ] = (brick) { .brickType = 2, .x = 273, .y = 154, .width = 30, .height = 10 }; + bricks[37 ] = (brick) { .brickType = 2, .x = 305, .y = 154, .width = 30, .height = 10 }; + bricks[38 ] = (brick) { .brickType = 2, .x = 337, .y = 154, .width = 30, .height = 10 }; + bricks[39 ] = (brick) { .brickType = 2, .x = 369, .y = 154, .width = 30, .height = 10 }; + bricks[40 ] = (brick) { .brickType = 2, .x = 401, .y = 154, .width = 30, .height = 10 }; + bricks[41 ] = (brick) { .brickType = 2, .x = 433, .y = 154, .width = 30, .height = 10 }; + bricks[42 ] = (brick) { .brickType = 2, .x = 17, .y = 166, .width = 30, .height = 10 }; + bricks[43 ] = (brick) { .brickType = 2, .x = 49, .y = 166, .width = 30, .height = 10 }; + bricks[44 ] = (brick) { .brickType = 2, .x = 81, .y = 166, .width = 30, .height = 10 }; + bricks[45 ] = (brick) { .brickType = 2, .x = 113, .y = 166, .width = 30, .height = 10 }; + bricks[46 ] = (brick) { .brickType = 2, .x = 145, .y = 166, .width = 30, .height = 10 }; + bricks[47 ] = (brick) { .brickType = 2, .x = 177, .y = 166, .width = 30, .height = 10 }; + bricks[48 ] = (brick) { .brickType = 2, .x = 209, .y = 166, .width = 30, .height = 10 }; + bricks[49 ] = (brick) { .brickType = 2, .x = 241, .y = 166, .width = 30, .height = 10 }; + bricks[50 ] = (brick) { .brickType = 2, .x = 273, .y = 166, .width = 30, .height = 10 }; + bricks[51 ] = (brick) { .brickType = 2, .x = 305, .y = 166, .width = 30, .height = 10 }; + bricks[52 ] = (brick) { .brickType = 2, .x = 337, .y = 166, .width = 30, .height = 10 }; + bricks[53 ] = (brick) { .brickType = 2, .x = 369, .y = 166, .width = 30, .height = 10 }; + bricks[54 ] = (brick) { .brickType = 2, .x = 401, .y = 166, .width = 30, .height = 10 }; + bricks[55 ] = (brick) { .brickType = 2, .x = 433, .y = 166, .width = 30, .height = 10 }; + bricks[56 ] = (brick) { .brickType = 3, .x = 17, .y = 178, .width = 30, .height = 10 }; + bricks[57 ] = (brick) { .brickType = 3, .x = 49, .y = 178, .width = 30, .height = 10 }; + bricks[58 ] = (brick) { .brickType = 3, .x = 81, .y = 178, .width = 30, .height = 10 }; + bricks[59 ] = (brick) { .brickType = 3, .x = 113, .y = 178, .width = 30, .height = 10 }; + bricks[60 ] = (brick) { .brickType = 3, .x = 145, .y = 178, .width = 30, .height = 10 }; + bricks[61 ] = (brick) { .brickType = 3, .x = 177, .y = 178, .width = 30, .height = 10 }; + bricks[62 ] = (brick) { .brickType = 3, .x = 209, .y = 178, .width = 30, .height = 10 }; + bricks[63 ] = (brick) { .brickType = 3, .x = 241, .y = 178, .width = 30, .height = 10 }; + bricks[64 ] = (brick) { .brickType = 3, .x = 273, .y = 178, .width = 30, .height = 10 }; + bricks[65 ] = (brick) { .brickType = 3, .x = 305, .y = 178, .width = 30, .height = 10 }; + bricks[66 ] = (brick) { .brickType = 3, .x = 337, .y = 178, .width = 30, .height = 10 }; + bricks[67 ] = (brick) { .brickType = 3, .x = 369, .y = 178, .width = 30, .height = 10 }; + bricks[68 ] = (brick) { .brickType = 3, .x = 401, .y = 178, .width = 30, .height = 10 }; + bricks[69 ] = (brick) { .brickType = 3, .x = 433, .y = 178, .width = 30, .height = 10 }; + bricks[70 ] = (brick) { .brickType = 3, .x = 17, .y = 190, .width = 30, .height = 10 }; + bricks[71 ] = (brick) { .brickType = 3, .x = 49, .y = 190, .width = 30, .height = 10 }; + bricks[72 ] = (brick) { .brickType = 3, .x = 81, .y = 190, .width = 30, .height = 10 }; + bricks[73 ] = (brick) { .brickType = 3, .x = 113, .y = 190, .width = 30, .height = 10 }; + bricks[74 ] = (brick) { .brickType = 3, .x = 145, .y = 190, .width = 30, .height = 10 }; + bricks[75 ] = (brick) { .brickType = 3, .x = 177, .y = 190, .width = 30, .height = 10 }; + bricks[76 ] = (brick) { .brickType = 3, .x = 209, .y = 190, .width = 30, .height = 10 }; + bricks[77 ] = (brick) { .brickType = 3, .x = 241, .y = 190, .width = 30, .height = 10 }; + bricks[78 ] = (brick) { .brickType = 3, .x = 273, .y = 190, .width = 30, .height = 10 }; + bricks[79 ] = (brick) { .brickType = 3, .x = 305, .y = 190, .width = 30, .height = 10 }; + bricks[80 ] = (brick) { .brickType = 3, .x = 337, .y = 190, .width = 30, .height = 10 }; + bricks[81 ] = (brick) { .brickType = 3, .x = 369, .y = 190, .width = 30, .height = 10 }; + bricks[82 ] = (brick) { .brickType = 3, .x = 401, .y = 190, .width = 30, .height = 10 }; + bricks[83 ] = (brick) { .brickType = 3, .x = 433, .y = 190, .width = 30, .height = 10 }; + bricks[84 ] = (brick) { .brickType = 4, .x = 17, .y = 202, .width = 30, .height = 10 }; + bricks[85 ] = (brick) { .brickType = 4, .x = 49, .y = 202, .width = 30, .height = 10 }; + bricks[86 ] = (brick) { .brickType = 4, .x = 81, .y = 202, .width = 30, .height = 10 }; + bricks[87 ] = (brick) { .brickType = 4, .x = 113, .y = 202, .width = 30, .height = 10 }; + bricks[88 ] = (brick) { .brickType = 4, .x = 145, .y = 202, .width = 30, .height = 10 }; + bricks[89 ] = (brick) { .brickType = 4, .x = 177, .y = 202, .width = 30, .height = 10 }; + bricks[90 ] = (brick) { .brickType = 4, .x = 209, .y = 202, .width = 30, .height = 10 }; + bricks[91 ] = (brick) { .brickType = 4, .x = 241, .y = 202, .width = 30, .height = 10 }; + bricks[92 ] = (brick) { .brickType = 4, .x = 273, .y = 202, .width = 30, .height = 10 }; + bricks[93 ] = (brick) { .brickType = 4, .x = 305, .y = 202, .width = 30, .height = 10 }; + bricks[94 ] = (brick) { .brickType = 4, .x = 337, .y = 202, .width = 30, .height = 10 }; + bricks[95 ] = (brick) { .brickType = 4, .x = 369, .y = 202, .width = 30, .height = 10 }; + bricks[96 ] = (brick) { .brickType = 4, .x = 401, .y = 202, .width = 30, .height = 10 }; + bricks[97 ] = (brick) { .brickType = 4, .x = 433, .y = 202, .width = 30, .height = 10 }; + bricks[98 ] = (brick) { .brickType = 4, .x = 17, .y = 214, .width = 30, .height = 10 }; + bricks[99 ] = (brick) { .brickType = 4, .x = 49, .y = 214, .width = 30, .height = 10 }; + bricks[100] = (brick) { .brickType = 4, .x = 81, .y = 214, .width = 30, .height = 10 }; + bricks[101] = (brick) { .brickType = 4, .x = 113, .y = 214, .width = 30, .height = 10 }; + bricks[102] = (brick) { .brickType = 4, .x = 145, .y = 214, .width = 30, .height = 10 }; + bricks[103] = (brick) { .brickType = 4, .x = 177, .y = 214, .width = 30, .height = 10 }; + bricks[104] = (brick) { .brickType = 4, .x = 209, .y = 214, .width = 30, .height = 10 }; + bricks[105] = (brick) { .brickType = 4, .x = 241, .y = 214, .width = 30, .height = 10 }; + bricks[106] = (brick) { .brickType = 4, .x = 273, .y = 214, .width = 30, .height = 10 }; + bricks[107] = (brick) { .brickType = 4, .x = 305, .y = 214, .width = 30, .height = 10 }; + bricks[108] = (brick) { .brickType = 4, .x = 337, .y = 214, .width = 30, .height = 10 }; + bricks[109] = (brick) { .brickType = 4, .x = 369, .y = 214, .width = 30, .height = 10 }; + bricks[110] = (brick) { .brickType = 4, .x = 401, .y = 214, .width = 30, .height = 10 }; + bricks[111] = (brick) { .brickType = 4, .x = 433, .y = 214, .width = 30, .height = 10 }; + *brickCount = 112; +} \ No newline at end of file