Added playerLives variable that is updated when the ball is reset, and used SDL_Image to load bitmaps of heart icons and function to visually represent the lives

SDL Surface to GL Texture code in loadTextures function used from http://www.sdltutorials.com/sdl-tip-sdl-surface-to-opengl-texture
This commit is contained in:
Joe Adams 2018-01-11 11:49:34 +00:00
parent a8898fe13a
commit 0d5153ea57
3 changed files with 94 additions and 5 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

View File

@ -2,8 +2,11 @@
#include <Windows.h>
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#else
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL_image.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
@ -65,16 +68,20 @@ double heronsFormula(coord a, coord b, coord c) {
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);
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 drawBg(int winWidth, int winHeight, colour *c1, colour *c2);
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);
@ -88,6 +95,7 @@ int main(void) {
* 3: Error creating context
* 4: SDL_TTF init fail
* 5: Error loading font(s)
* 6: Error loading image asset(s)
*
*/
@ -162,6 +170,8 @@ int main(void) {
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);
@ -220,6 +230,8 @@ int main(void) {
int playerScore = 0;
int playerLives = 3;
/*
* ----------------
* Font stuff
@ -238,6 +250,19 @@ int main(void) {
.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!
@ -303,8 +328,11 @@ int main(void) {
*/
updatePaddle(tickrate, &thePaddle, moveX, winWidth, winHeight);
updateBall(tickrate, &theBall, &thePaddle, winWidth, winHeight, &bricks, brickCount);
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;
@ -316,7 +344,7 @@ int main(void) {
SDL_GL_MakeCurrent(window1, context1);
sprintf(windowTitle, "Breakout: Score %d", playerScore);
sprintf(windowTitle, "Breakout: Score (%d), lives remaining (%d)", playerScore, playerLives);
SDL_SetWindowTitle(window1, windowTitle);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
@ -335,6 +363,7 @@ int main(void) {
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);
@ -365,6 +394,37 @@ int main(void) {
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;
@ -385,7 +445,7 @@ void updatePaddle(Uint32 tickrate, paddle *thePaddle, char moveX, int winWidth,
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) {
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;
@ -482,6 +542,7 @@ void updateBall(Uint32 tickrate, ball *theBall, paddle *thePaddle, int winWidth,
theBall->y = 0;
theBall->vX = theBall->initVX;
theBall->vY = theBall->initVY;
*playerLives -= 1;
}
// Update the ball's position
@ -512,6 +573,34 @@ void updateScore(int *playerScore, brick *bricks, int brickCount) {
}
}
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);