#ifdef _WIN32 #include #include #include #include #else #include #include #include #endif #include #include #include #include typedef struct coord { double x; double y; } coord; typedef struct colour { double r; double g; double b; double a; } colour; typedef struct paddle { int width; int height; double x; } paddle; typedef struct ball { double x; double y; double vX; double vY; double initVX; double initVY; double radius; char isColliding; } ball; typedef struct brick { char brickType; int x; int y; int width; int height; char destroyed; } 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)); } int loadTextures(GLuint *texture, const char *imageLoc); 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, brick *bricks, int brickCount, int *playerLives); void updateScore(int *playerScore, brick *bricks, int brickCount); void drawHearts(GLuint heartFullTex, GLuint heartEmptyTex, int playerLives, int winWidth, int winHeight); void drawPaddle(paddle *thePaddle, int winWidth, int winHeight, colour *c); void drawBall(ball *theBall, colour *c); void drawBricks(brick *bricks, int brickCount, int winWidth, int winHeight, colour *colours); void drawBg(int winWidth, int winHeight, colour *c1, colour *c2); void initialiseBricks(brick *bricks, int *brickCount); int main(void) { /* * RETURN CODES * 0: Success * 1: SDL init fail * 2: Error creating Window * 3: Error creating context * 4: SDL_TTF init fail * 5: Error loading font(s) * 6: Error loading image asset(s) * */ /* ---------------- * SDL Init * ---------------- */ if (SDL_Init(SDL_INIT_EVERYTHING)!=0) { perror("[FAILED] Initialising SDL: "); return 1; } if (TTF_Init() < 0) { perror("[FAILED] Initialising SDL_TTF: "); } int go; //Var for loop control int step = 0; //Var for step counter /* ---------------- * Main Window * ---------------- * Create the main output Window for SDL */ // Window vars int winPosX = 100; int winPosY = 100; int winWidth = 480; int winHeight = 720; char windowTitle[128] = "Breakout"; Uint32 timer; SDL_Window *window1 = SDL_CreateWindow( windowTitle, winPosX, winPosY, winWidth, winHeight, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL ); if (window1==NULL) { fprintf(stderr, "[FAILED] Creating Window window1"); return 2; //Error creating Window } /* * ---------------- * Renderer * ---------------- * Creates the main renderer (tied to main window) */ //SDL_Renderer * renderer1 = SDL_CreateRenderer(window1, -1, 0); //if (renderer1==NULL) { // fprintf(stderr, "[FAILED] Creating renderer renderer1 for window1"); // return 3; //} SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1); // Specifies the version of the OpenGL context SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5); // (here, 1.5) -- hello, 2003! SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); // Allows deprecated functions to be used SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); // Set depth buffer to 16 bits, if OpenGL agrees (see below) SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); // Enable double buffering SDL_GLContext context1 = SDL_GL_CreateContext(window1); // Use SDL_GL_MakeCurrent function to switch contexts if (context1 == NULL) { fprintf(stderr, "[FAILED] Creating render context context1 for window1"); return 3; } glFrontFace(GL_CCW); // Counter-clockwise winding glEnable(GL_NORMALIZE); // Vectors normalized after transforming to keep units consistent for lighting glShadeModel(GL_SMOOTH); // GL_FLAT for flat shading instead glEnable(GL_DEPTH_TEST); // Enables depth comparisons glEnable(GL_TEXTURE_2D); // Enables use of textures glAlphaFunc(GL_GREATER, 0); glEnable(GL_ALPHA_TEST); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_PROJECTION); // Sets our matrix mode (initially) to work with the projection stack glLoadIdentity(); // Projection matrix is now the identity matrix, so we can work in 2D space gluOrtho2D( -1.0*(GLdouble)(winWidth / 2), // Left (GLdouble)(winWidth / 2), // Right -1.0*(GLdouble)(winHeight / 2), // Bottom (GLdouble)(winHeight / 2) // Top ); glViewport(0, 0, winWidth, winHeight); // Set the viewport to fill the window timer = SDL_GetTicks(); /* * ---------------- * Game variables * ---------------- */ char subSteps = 2; // Draw every N+1 frames, thereby calculating movement more precisely int targetFPS = 60; // Limit FPS to this value, to stop unneccessary calculations char moveX=0; 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, .y = 0, .vX = 1.5f, .vY = -5.0f, .initVX = theBall.vX, .initVY = theBall.vY, .radius = 4, .isColliding = 0 }; paddle thePaddle = { .width = 50, .height = 10, .x = (winWidth/2)-(thePaddle.width/2) }; int playerScore = 0; int playerLives = 3; /* * ---------------- * Font stuff * ---------------- */ TTF_Font* font_main = TTF_OpenFont("assets/font_main.ttf", 24); if (font_main == NULL) { printf("[FAILED] Unable to load font\n"); return 5; } SDL_Color textColour = { .a = 255, .r = 255, .g = 255, .b = 255 }; /* * -------------------------------- * Loading required textures * -------------------------------- */ GLuint heartFullTex; GLuint heartEmptyTex; if ( loadTextures(&heartEmptyTex, "assets/heartUsed.png") || loadTextures(&heartFullTex, "assets/heartFull.png") > 1) { return 6; } /* * ---------------- * Let's go! * ---------------- */ go=1; while(go) { /* ---------------- * Timing control * ---------------- * */ Uint32 tickrate=SDL_GetTicks()-timer; timer=SDL_GetTicks(); int fps=1000/(tickrate+1); /* * ---------------- * Event handling * ---------------- */ SDL_Event incomingEvent; while (SDL_PollEvent(&incomingEvent)) { switch (incomingEvent.type) { case SDL_QUIT: // User requested program quit - e.g. window close go=0; break; case SDL_KEYDOWN: switch(incomingEvent.key.keysym.sym) { case SDLK_ESCAPE: go=0; break; case SDLK_LEFT: moveX=-1; break; case SDLK_RIGHT: moveX=1; break; } break; case SDL_KEYUP: switch(incomingEvent.key.keysym.sym) { case SDLK_LEFT: moveX=0; break; case SDLK_RIGHT: moveX=0; break; } break; } } /* * ---------------- * Update elements * ---------------- */ updatePaddle(tickrate, &thePaddle, moveX, winWidth, winHeight); updateBall(tickrate, &theBall, &thePaddle, winWidth, winHeight, &bricks, brickCount, &playerLives); updateScore(&playerScore, &bricks, brickCount); if (playerLives < 1) { go = 0; } if (step % (subSteps+1) == 0) { //step = 0; /* * ---------------- * Draw to buffer * ---------------- */ SDL_GL_MakeCurrent(window1, context1); sprintf(windowTitle, "Breakout: Score (%d), lives remaining (%d)", playerScore, playerLives); SDL_SetWindowTitle(window1, windowTitle); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); colour paddleCol; paddleCol.r = 1.0; paddleCol.g = 1.0; paddleCol.b = 1.0; paddleCol.a = 1.0; colour bgcol1; colour bgcol2; 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*/ drawHearts(heartFullTex, heartEmptyTex, playerLives, winWidth, winHeight); drawPaddle(&thePaddle, winWidth, winHeight, &paddleCol); drawBall(&theBall, &paddleCol); drawBricks(&bricks, brickCount, winWidth, winHeight, &brickColours); drawBg(winWidth, winHeight, &bgcol1, &bgcol2); glFlush(); /* * -------------------------------- * Output to Window * -------------------------------- */ SDL_GL_SwapWindow(window1); } if (SDL_GetTicks() - timer < 1000 / (targetFPS * (subSteps+1))) SDL_Delay((1000 / (targetFPS * (subSteps+1))) - (SDL_GetTicks() - timer)); step++; } /* * -------------------------------- * Clean up after ourselves * -------------------------------- */ SDL_GL_DeleteContext(context1); SDL_DestroyWindow(window1); SDL_Quit(); return 0; } int loadTextures(GLuint *texture, const char *imageLoc) { char errorMsg[512]; sprintf(errorMsg, "[FAILED] Opening %s", imageLoc); SDL_Surface *surface = IMG_Load(imageLoc); if (surface == NULL) { fprintf(stderr, errorMsg); return 1; } *texture = 0; // Start of code from SDLTutorials.com int Mode = GL_RGB; glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, *texture); if (surface->format->BytesPerPixel == 4) { Mode = GL_RGBA; } glTexImage2D(GL_TEXTURE_2D, 0, Mode, surface->w, surface->h, 0, Mode, GL_UNSIGNED_BYTE, surface->pixels); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // End of code from SDLTutorials.com // Tim Jones (2011) SDL Surface to OpenGL Texture, Available at: http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture (Accessed: 10/01/2018) 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 ((int)testArea == (int)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); if (thePaddle->x > winWidth-(thePaddle->width/2)) thePaddle->x = winWidth-(thePaddle->width/2); } void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth, int winHeight, brick *bricks, int brickCount, int *playerLives) { double ballNX = theBall->x + theBall->vX * 0.1 * tickrate; // Calculates the position of the ball's centre on the next step double ballNY = theBall->y + theBall->vY * 0.1 * tickrate; double paddleRX = thePaddle->x - (double)(winWidth / 2); // Converts paddle X/Y to coordinates relative to the center of the window as the ball double paddleRY = 20 - (double)(winHeight / 2); // (Default is absolute, offset from the top left corner of window) coord paddleQ[4] = { { .x = paddleRX, .y = paddleRY }, // Sets up a quad (coord array) to pass to vertexWithinQuad function later { .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 against paddle quad) 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]) }; // Constructs pairs of coordinates referring to each vertex of the ball if (vertexWithinQuad(ballN, paddleQ)) colliding = 1; } if (colliding) { if (theBall->isColliding == 0) { theBall->isColliding = 1; // This keeps track of any current attepmts to 'solve' collision // Without this flag, if the ball ends up within another object and moving slow enough that on the next frame it has not escaped the object, // it will repeatedly have its velocity multiplied by -1 and get stuck, effectively moving only along one axis. With this flag, // the game will ignore subsequent collisions, until it is no longer colliding. Note this does not solve the same problem where two objects // are very close to each other and on exiting one object it enters another, in which case the ball will move through the other objects 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 { // Top or bottom collision theBall->vY *= -1.0; theBall->vX = ((ballNX - paddleRX - (double)(thePaddle->width / 2)) / ((double)thePaddle->width / 2))*theBall->initVX; // Sets X velocity to be proportional to the relative position of the ball and the paddle on collision } } else { // Already solving a collision } } else { theBall->isColliding = 0; } // Collision with bricks // (Testing each vertex of ball against every brick) for (int i = 0; i < brickCount; i++) { colliding = 0; if (bricks[i].destroyed == 0) { coord brick[4] = { {.x = bricks[i].x - (winWidth / 2), .y = bricks[i].y }, {.x = bricks[i].x - (winWidth / 2), .y = bricks[i].y - bricks[i].height }, {.x = bricks[i].x - (winWidth / 2) + bricks[i].width, .y = bricks[i].y - bricks[i].height }, {.x = bricks[i].x - (winWidth / 2) + bricks[i].width, .y = bricks[i].y }, }; for (int j = 0, k = 3; j < 4; j++, k++) { coord ballN = { .x = ballNX + (theBall->radius*mults[j % 4]),.y = ballNY + (theBall->radius*mults[k % 4]) }; if (vertexWithinQuad(ballN, brick)) colliding = 1; } if (colliding) { if (theBall->x + theBall->radius < bricks[i].x - (winWidth / 2)) { // Left side collision theBall->vX *= -1.0; } else if (theBall->x - theBall->radius > bricks[i].x - (winWidth / 2) + bricks[i].width) { // Right side collision theBall->vX *= -1.0; } else { theBall->vY *= -1.0; } bricks[i].destroyed = 1; break; } } } // Collision with window boundaries if (ballNX > winWidth / 2 || ballNX < (-1.0*winWidth/2)) { // Collision with walls theBall->vX *= -1.0; } if (ballNY > winHeight / 2) { // Collision with ceiling theBall->vY *= -1.0; } if (ballNY < (-1.0*winHeight/2)) { // Collision with floor theBall->x = 0; theBall->y = 0; theBall->vX = theBall->initVX; theBall->vY = theBall->initVY; *playerLives -= 1; } // Update the ball's position theBall->x += theBall->vX * 0.1 * tickrate; theBall->y += theBall->vY * 0.1 * tickrate; } void updateScore(int *playerScore, brick *bricks, int brickCount) { *playerScore = 0; for (int i = 0; i < brickCount; i++) { if (bricks[i].destroyed == 1) { switch (bricks[i].brickType) { case 1: *playerScore += 1; break; case 2: *playerScore += 3; break; case 3: *playerScore += 5; break; case 4: *playerScore += 7; break; } } } } void drawHearts(GLuint heartFullTex, GLuint heartEmptyTex, int playerLives, int winWidth, int winHeight) { coord locations[3] = { {.x = -19, .y = -32}, { .x = 0, .y = -32 }, { .x = 19, .y = -32 } }; for (int i = 0; i < 3; i++) { if (i > playerLives-1) { glBindTexture(GL_TEXTURE_2D, heartEmptyTex); } else { glBindTexture(GL_TEXTURE_2D, heartFullTex); } GLint matrixmode = 0; glGetIntegerv(GL_MATRIX_MODE, &matrixmode); glPushMatrix(); glTranslated(0.0, (winHeight/2), 0.0); glBegin(GL_QUADS); glTexCoord2f(0, 0); glVertex3d(0.0+locations[i].x, 0.0+locations[i].y, 0.0); glTexCoord2f(0, 1); glVertex3d(0.0+locations[i].x, -15.0 + locations[i].y, 0.0); glTexCoord2f(1, 1); glVertex3d(15.0+locations[i].x, -15.0 + locations[i].y, 0.0); glTexCoord2f(1, 0); glVertex3d(15.0+locations[i].x, 0.0 + locations[i].y, 0.0); glEnd(); glPopMatrix(); glMatrixMode(matrixmode); } glBindTexture(GL_TEXTURE_2D, 0); } void drawBg(int winWidth, int winHeight, colour *c1, colour *c2) { GLint matrixmode = 0; glGetIntegerv(GL_MATRIX_MODE, &matrixmode); glPushMatrix(); glTranslated((GLdouble)(-1*winWidth/2), (GLdouble)(-1*winHeight/2), 0.0); glBegin(GL_QUADS); //Top colour glColor3f(c1->r, c1->g, c1->b); glVertex2f(winWidth, 0.0); glVertex2f(0.0,0.0); //Bottom colour glColor3f(c2->r, c2->g, c2->b); glVertex2f(0.0,winHeight); glVertex2f(winWidth, winHeight); glEnd(); } void drawPaddle(paddle *thePaddle, int winWidth, int winHeight, colour *c) { GLint matrixmode = 0; glGetIntegerv(GL_MATRIX_MODE, &matrixmode); glPushMatrix(); glTranslated((GLdouble)(thePaddle->x)-winWidth/2, (GLdouble)(20-winHeight/2), 0.0); glBegin(GL_QUADS); glColor3f(c->r, c->g, c->b); glVertex3d(0.0, 0.0, 0.0); glVertex3d(0.0, (double)-1*thePaddle->height, 0.0); glVertex3d((double)thePaddle->width, (double)-1*thePaddle->height, 0.0); glVertex3d((double)thePaddle->width, 0.0, 0.0); glEnd(); glPopMatrix(); glMatrixMode(matrixmode); } void drawBall(ball *theBall, colour *c) { GLint matrixmode = 0; glGetIntegerv(GL_MATRIX_MODE, &matrixmode); glPushMatrix(); glTranslated(theBall->x, theBall->y, 0.0); glBegin(GL_QUADS); glColor3f(c->r, c->g, c->b); 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++) { if (bricks[i].destroyed == 0) { 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, .destroyed = 0 }; bricks[1 ] = (brick) { .brickType = 1, .x = 49, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[2 ] = (brick) { .brickType = 1, .x = 81, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[3 ] = (brick) { .brickType = 1, .x = 113, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[4 ] = (brick) { .brickType = 1, .x = 145, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[5 ] = (brick) { .brickType = 1, .x = 177, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[6 ] = (brick) { .brickType = 1, .x = 209, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[7 ] = (brick) { .brickType = 1, .x = 241, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[8 ] = (brick) { .brickType = 1, .x = 273, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[9 ] = (brick) { .brickType = 1, .x = 305, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[10 ] = (brick) { .brickType = 1, .x = 337, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[11 ] = (brick) { .brickType = 1, .x = 369, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[12 ] = (brick) { .brickType = 1, .x = 401, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[13 ] = (brick) { .brickType = 1, .x = 433, .y = 130, .width = 30, .height = 10, .destroyed = 0 }; bricks[14 ] = (brick) { .brickType = 1, .x = 17, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[15 ] = (brick) { .brickType = 1, .x = 49, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[16 ] = (brick) { .brickType = 1, .x = 81, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[17 ] = (brick) { .brickType = 1, .x = 113, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[18 ] = (brick) { .brickType = 1, .x = 145, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[19 ] = (brick) { .brickType = 1, .x = 177, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[20 ] = (brick) { .brickType = 1, .x = 209, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[21 ] = (brick) { .brickType = 1, .x = 241, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[22 ] = (brick) { .brickType = 1, .x = 273, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[23 ] = (brick) { .brickType = 1, .x = 305, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[24 ] = (brick) { .brickType = 1, .x = 337, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[25 ] = (brick) { .brickType = 1, .x = 369, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[26 ] = (brick) { .brickType = 1, .x = 401, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[27 ] = (brick) { .brickType = 1, .x = 433, .y = 142, .width = 30, .height = 10, .destroyed = 0 }; bricks[28 ] = (brick) { .brickType = 2, .x = 17, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[29 ] = (brick) { .brickType = 2, .x = 49, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[30 ] = (brick) { .brickType = 2, .x = 81, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[31 ] = (brick) { .brickType = 2, .x = 113, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[32 ] = (brick) { .brickType = 2, .x = 145, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[33 ] = (brick) { .brickType = 2, .x = 177, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[34 ] = (brick) { .brickType = 2, .x = 209, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[35 ] = (brick) { .brickType = 2, .x = 241, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[36 ] = (brick) { .brickType = 2, .x = 273, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[37 ] = (brick) { .brickType = 2, .x = 305, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[38 ] = (brick) { .brickType = 2, .x = 337, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[39 ] = (brick) { .brickType = 2, .x = 369, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[40 ] = (brick) { .brickType = 2, .x = 401, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[41 ] = (brick) { .brickType = 2, .x = 433, .y = 154, .width = 30, .height = 10, .destroyed = 0 }; bricks[42 ] = (brick) { .brickType = 2, .x = 17, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[43 ] = (brick) { .brickType = 2, .x = 49, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[44 ] = (brick) { .brickType = 2, .x = 81, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[45 ] = (brick) { .brickType = 2, .x = 113, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[46 ] = (brick) { .brickType = 2, .x = 145, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[47 ] = (brick) { .brickType = 2, .x = 177, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[48 ] = (brick) { .brickType = 2, .x = 209, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[49 ] = (brick) { .brickType = 2, .x = 241, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[50 ] = (brick) { .brickType = 2, .x = 273, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[51 ] = (brick) { .brickType = 2, .x = 305, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[52 ] = (brick) { .brickType = 2, .x = 337, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[53 ] = (brick) { .brickType = 2, .x = 369, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[54 ] = (brick) { .brickType = 2, .x = 401, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[55 ] = (brick) { .brickType = 2, .x = 433, .y = 166, .width = 30, .height = 10, .destroyed = 0 }; bricks[56 ] = (brick) { .brickType = 3, .x = 17, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[57 ] = (brick) { .brickType = 3, .x = 49, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[58 ] = (brick) { .brickType = 3, .x = 81, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[59 ] = (brick) { .brickType = 3, .x = 113, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[60 ] = (brick) { .brickType = 3, .x = 145, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[61 ] = (brick) { .brickType = 3, .x = 177, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[62 ] = (brick) { .brickType = 3, .x = 209, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[63 ] = (brick) { .brickType = 3, .x = 241, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[64 ] = (brick) { .brickType = 3, .x = 273, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[65 ] = (brick) { .brickType = 3, .x = 305, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[66 ] = (brick) { .brickType = 3, .x = 337, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[67 ] = (brick) { .brickType = 3, .x = 369, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[68 ] = (brick) { .brickType = 3, .x = 401, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[69 ] = (brick) { .brickType = 3, .x = 433, .y = 178, .width = 30, .height = 10, .destroyed = 0 }; bricks[70 ] = (brick) { .brickType = 3, .x = 17, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[71 ] = (brick) { .brickType = 3, .x = 49, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[72 ] = (brick) { .brickType = 3, .x = 81, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[73 ] = (brick) { .brickType = 3, .x = 113, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[74 ] = (brick) { .brickType = 3, .x = 145, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[75 ] = (brick) { .brickType = 3, .x = 177, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[76 ] = (brick) { .brickType = 3, .x = 209, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[77 ] = (brick) { .brickType = 3, .x = 241, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[78 ] = (brick) { .brickType = 3, .x = 273, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[79 ] = (brick) { .brickType = 3, .x = 305, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[80 ] = (brick) { .brickType = 3, .x = 337, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[81 ] = (brick) { .brickType = 3, .x = 369, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[82 ] = (brick) { .brickType = 3, .x = 401, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[83 ] = (brick) { .brickType = 3, .x = 433, .y = 190, .width = 30, .height = 10, .destroyed = 0 }; bricks[84 ] = (brick) { .brickType = 4, .x = 17, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[85 ] = (brick) { .brickType = 4, .x = 49, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[86 ] = (brick) { .brickType = 4, .x = 81, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[87 ] = (brick) { .brickType = 4, .x = 113, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[88 ] = (brick) { .brickType = 4, .x = 145, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[89 ] = (brick) { .brickType = 4, .x = 177, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[90 ] = (brick) { .brickType = 4, .x = 209, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[91 ] = (brick) { .brickType = 4, .x = 241, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[92 ] = (brick) { .brickType = 4, .x = 273, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[93 ] = (brick) { .brickType = 4, .x = 305, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[94 ] = (brick) { .brickType = 4, .x = 337, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[95 ] = (brick) { .brickType = 4, .x = 369, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[96 ] = (brick) { .brickType = 4, .x = 401, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[97 ] = (brick) { .brickType = 4, .x = 433, .y = 202, .width = 30, .height = 10, .destroyed = 0 }; bricks[98 ] = (brick) { .brickType = 4, .x = 17, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[99 ] = (brick) { .brickType = 4, .x = 49, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[100] = (brick) { .brickType = 4, .x = 81, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[101] = (brick) { .brickType = 4, .x = 113, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[102] = (brick) { .brickType = 4, .x = 145, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[103] = (brick) { .brickType = 4, .x = 177, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[104] = (brick) { .brickType = 4, .x = 209, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[105] = (brick) { .brickType = 4, .x = 241, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[106] = (brick) { .brickType = 4, .x = 273, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[107] = (brick) { .brickType = 4, .x = 305, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[108] = (brick) { .brickType = 4, .x = 337, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[109] = (brick) { .brickType = 4, .x = 369, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[110] = (brick) { .brickType = 4, .x = 401, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; bricks[111] = (brick) { .brickType = 4, .x = 433, .y = 214, .width = 30, .height = 10, .destroyed = 0 }; *brickCount = 112; }