Added a sticky paddle flag on death and new level, spacebar to (re)start game, ESC to exit, combined brick layouts (levels) into one function

This commit is contained in:
Joe Adams 2018-01-12 04:24:35 +00:00
parent bf52ead7cc
commit 6be9da289c
4 changed files with 1290 additions and 1148 deletions

View File

@ -22,7 +22,7 @@
int loadTextures(GLuint *texture, const char *imageLoc); int loadTextures(GLuint *texture, const char *imageLoc);
void surfaceToTexture(GLuint *texture, SDL_Surface *surface); void surfaceToTexture(GLuint *texture, SDL_Surface *surface);
void updateScore(int *playerScore, brick *bricks, int brickCount); void updateScore(int *playerScore, brick *bricks, int *brickCount, int *level, ball *theBall);
int main(void) { int main(void) {
@ -85,12 +85,6 @@ int main(void) {
* Creates the main renderer (tied to main window) * 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_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_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_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); // Allows deprecated functions to be used
@ -109,8 +103,8 @@ int main(void) {
glShadeModel(GL_SMOOTH); // GL_FLAT for flat shading instead glShadeModel(GL_SMOOTH); // GL_FLAT for flat shading instead
glEnable(GL_DEPTH_TEST); // Enables depth comparisons glEnable(GL_DEPTH_TEST); // Enables depth comparisons
glEnable(GL_TEXTURE_2D); // Enables use of textures glEnable(GL_TEXTURE_2D); // Enables use of textures
glAlphaFunc(GL_GREATER, 0); glAlphaFunc(GL_GREATER, 0); // How we plan on treating aplha
glEnable(GL_ALPHA_TEST); glEnable(GL_ALPHA_TEST); // Enables alpha testing (needed for transparent textures)
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@ -136,45 +130,57 @@ int main(void) {
* ---------------- * ----------------
*/ */
char subSteps = 2; // Draw every N+1 frames, thereby calculating movement more precisely char subSteps = 1; // Draw every N+1 frames, thereby calculating movement more precisely
int targetFPS = 60; // Limit FPS to this value, to stop unneccessary calculations int targetFPS = 60; // Limit FPS to this value, to stop unneccessary calculations
char moveX=0; char moveX=0; // Toggled between -1, 0 and 1 by keypresses later
brick bricks[2048]; int playerScore = 0;
int level = 1;
int playerLives = 3;
brick bricks[2048]; // Sets up array for the bricks to be stored in, max no. bricks is 2048
int brickCount; int brickCount;
colour brickColours[4]; colour brickColours[7]; //brickColours[n] corresponds to the colour of a brick with type n+1
brickColours[3] = (colour) { .r = 1.0000 /*255*/, .g = 0.2510 /*64 */, .b = 0.6549 /*167*/, .a = 1 }; brickColours[6] = (colour) { .r = 0.9000 /*255*/, .g = 0.9000 /*64 */, .b = 0.9000 /*167*/, .a = 1 };
brickColours[5] = (colour) { .r = 0.8000 /*255*/, .g = 0.8000 /*64 */, .b = 0.8000 /*167*/, .a = 1 };
brickColours[4] = (colour) { .r = 0.7000 /*255*/, .g = 0.7000 /*64 */, .b = 0.7000 /*167*/, .a = 1 };
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[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[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 }; brickColours[0] = (colour) { .r = 1.0000 /*255*/, .g = 0.7569 /*193*/, .b = 0.1216 /*31 */, .a = 1 };
initialiseBricks(&bricks, &brickCount); initialiseBricks(&bricks, &brickCount, level); // Sets up the bricks for level one
colour paddleCol;
paddleCol.r = 1.0; paddleCol.g = 1.0; paddleCol.b = 1.0; paddleCol.a = 1.0; // RGBA of paddle and ball
colour bgcol1; colour bgcol2;
bgcol1.r = 0.7216; /*184*/ bgcol2.r = 0.0824; /*21 */ // RGBA values for the gradient, bgcol1 refers to the bottom colour and bgcol2 to the top
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*/
ball theBall = { ball theBall = {
.x = 0, .x = 0,
.y = 0, .y = 0,
.vX = 1.5f, .vX = 1.5f, // Change to desired X / Y speeds
.vY = -5.0f, .vY = -5.0f,
.initVX = theBall.vX, .initVX = theBall.vX,
.initVY = theBall.vY, .initVY = theBall.vY,
.radius = 4, .radius = 4,
.isColliding = 0, .isColliding = 0,
.stickToPaddle = 1 .stickToPaddle = 1
}; }; // Initialising the ball
paddle thePaddle = { paddle thePaddle = {
.width = 50, .width = 50,
.height = 10, .height = 10,
.x = (winWidth/2)-(thePaddle.width/2) .x = (winWidth/2)-(thePaddle.width/2)
}; }; // Initialising the paddle
char txtL[4] = "000"; char txtL[4] = "000"; // Placeholder text
char txtR[4] = "000"; char txtR[4] = "000";
int playerScore = 0;
int level = 1;
int playerLives = 3;
/* /*
* ---------------- * ----------------
* Font stuff * Font stuff
@ -199,7 +205,7 @@ int main(void) {
* -------------------------------- * --------------------------------
*/ */
GLuint heartFullTex; GLuint heartFullTex;
GLuint heartEmptyTex; GLuint heartEmptyTex;
if ( if (
loadTextures(&heartEmptyTex, "assets/heartUsed.png") || loadTextures(&heartEmptyTex, "assets/heartUsed.png") ||
@ -251,7 +257,13 @@ int main(void) {
moveX=1; moveX=1;
break; break;
case SDLK_SPACE: case SDLK_SPACE:
theBall.stickToPaddle = 0; if (playerLives>0) theBall.stickToPaddle = 0;
else {
playerLives = 3;
level = 1;
theBall.stickToPaddle = 1;
initialiseBricks(&bricks, &brickCount, level);
}
break; break;
} }
break; break;
@ -279,7 +291,7 @@ int main(void) {
sprintf(txtR, "%03d", level); sprintf(txtR, "%03d", level);
updatePaddle(tickrate, &thePaddle, moveX, winWidth, winHeight); updatePaddle(tickrate, &thePaddle, moveX, winWidth, winHeight);
updateBall(tickrate, &theBall, &thePaddle, winWidth, winHeight, &bricks, brickCount, &playerLives); updateBall(tickrate, &theBall, &thePaddle, winWidth, winHeight, &bricks, brickCount, &playerLives);
updateScore(&playerScore, &bricks, brickCount); updateScore(&playerScore, &bricks, &brickCount, &level, &theBall);
} }
if (step % (subSteps+1) == 0) { if (step % (subSteps+1) == 0) {
@ -302,15 +314,6 @@ int main(void) {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); 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*/
if (playerLives==0) { if (playerLives==0) {
drawText("Game Over", font_main, textColour, (coord){ .x=0, .y=-128}); drawText("Game Over", font_main, textColour, (coord){ .x=0, .y=-128});
} }
@ -396,9 +399,10 @@ void surfaceToTexture(GLuint *texture, SDL_Surface *surface) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
} }
void updateScore(int *playerScore, brick *bricks, int brickCount) { void updateScore(int *playerScore, brick *bricks, int *brickCount, int *level, ball *theBall) {
*playerScore = 0; *playerScore = 0;
for (int i = 0; i < brickCount; i++) { char allBricksDestroyed = 1;
for (int i = 0; i < *brickCount; i++) {
if (bricks[i].destroyed == 1) { if (bricks[i].destroyed == 1) {
switch (bricks[i].brickType) { switch (bricks[i].brickType) {
case 1: case 1:
@ -414,6 +418,13 @@ void updateScore(int *playerScore, brick *bricks, int brickCount) {
*playerScore += 7; *playerScore += 7;
break; break;
} }
} else {
allBricksDestroyed = 0;
} }
} }
if (allBricksDestroyed==1) {
*level += 1;
initialiseBricks(bricks, brickCount, *level);
theBall->stickToPaddle = 1;
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1 @@
void initialiseBricks(brick *bricks, int *brickCount); void initialiseBricks(brick *bricks, int *brickCount, int level);
void initialiseBricks2(brick *bricks, int *brickCount);

View File

@ -21,10 +21,10 @@ void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth,
double paddleRY = 20 - (double)(winHeight / 2); // (Default is absolute, offset from the top left corner of window) double paddleRY = 20 - (double)(winHeight / 2); // (Default is absolute, offset from the top left corner of window)
coord paddleQ[4] = { coord paddleQ[4] = {
{ .x = paddleRX,.y = paddleRY }, // Sets up a quad (coord array) to pass to vertexWithinQuad function later { .x = paddleRX, .y = paddleRY }, // Sets up a quad (coord array) to pass to vertexWithinQuad function later
{ .x = paddleRX,.y = paddleRY - thePaddle->height }, { .x = paddleRX, .y = paddleRY - thePaddle->height },
{ .x = paddleRX + thePaddle->width,.y = paddleRY - thePaddle->height }, { .x = paddleRX + thePaddle->width, .y = paddleRY - thePaddle->height },
{ .x = paddleRX + thePaddle->width,.y = paddleRY }, { .x = paddleRX + thePaddle->width, .y = paddleRY },
}; };
// Collision with paddle // Collision with paddle
@ -74,10 +74,10 @@ void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth,
if (bricks[i].destroyed == 0) { if (bricks[i].destroyed == 0) {
coord brick[4] = { coord brick[4] = {
{ .x = bricks[i].x - (winWidth / 2),.y = bricks[i].y }, { .x = bricks[i].x - (winWidth / 2), .y = bricks[i].y }, // Set up quad for brick
{ .x = bricks[i].x - (winWidth / 2),.y = bricks[i].y - bricks[i].height }, { .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 - bricks[i].height },
{ .x = bricks[i].x - (winWidth / 2) + bricks[i].width,.y = bricks[i].y }, { .x = bricks[i].x - (winWidth / 2) + bricks[i].width, .y = bricks[i].y },
}; };
for (int j = 0, k = 3; j < 4; j++, k++) { for (int j = 0, k = 3; j < 4; j++, k++) {
@ -96,6 +96,17 @@ void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth,
theBall->vY *= -1.0; theBall->vY *= -1.0;
} }
bricks[i].destroyed = 1; bricks[i].destroyed = 1;
switch (bricks[i].brickType) {
case 5:
thePaddle->width *= 1.5;
break;
case 6:
theBall->vY *= 0.5;
break;
case 7:
theBall->radius *= 1.6;
break;
}
break; break;
} }
} }
@ -110,8 +121,7 @@ void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth,
theBall->vY *= -1.0; theBall->vY *= -1.0;
} }
if (ballNY < (-1.0*winHeight / 2)) { // Collision with floor if (ballNY < (-1.0*winHeight / 2)) { // Collision with floor
theBall->x = 0; theBall->stickToPaddle = 1;
theBall->y = 0;
theBall->vX = theBall->initVX; theBall->vX = theBall->initVX;
theBall->vY = theBall->initVY; theBall->vY = theBall->initVY;
*playerLives -= 1; *playerLives -= 1;
@ -123,6 +133,9 @@ void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth,
theBall->y += theBall->vY * 0.1 * tickrate; theBall->y += theBall->vY * 0.1 * tickrate;
} }
else { else {
// If the ball is 'stuck to paddle' (i.e. post-death/level change)
theBall->x = thePaddle->x - (double)(winWidth / 2) + (thePaddle->width) / 2; theBall->x = thePaddle->x - (double)(winWidth / 2) + (thePaddle->width) / 2;
theBall->y = 26 - (double)(winHeight / 2); theBall->y = 26 - (double)(winHeight / 2);
} }