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:
parent
a8898fe13a
commit
0d5153ea57
BIN
breakout/assets/heartFull.png
Normal file
BIN
breakout/assets/heartFull.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 315 B |
BIN
breakout/assets/heartUsed.png
Normal file
BIN
breakout/assets/heartUsed.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 269 B |
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user