Merge branch 'dev' into 'master'

New Version with working Main menu

See merge request czg6669/breakout!2
This commit is contained in:
Michael Chen 2018-01-18 15:19:03 +00:00
commit b4aac4d41b
35 changed files with 871 additions and 136 deletions

3
.gitignore vendored
View File

@ -1,14 +1,11 @@
# git ls-files --others --exclude-from=.git/info/exclude # git ls-files --others --exclude-from=.git/info/exclude
# Lines that start with '#' are comments. # Lines that start with '#' are comments.
# For a project mostly in C, the following would be a good set of
# exclude patterns (uncomment them if you want to use them):
*.depend *.depend
*.cbp *.cbp
*.layout *.layout
sdl2-config sdl2-config
*.exclude *.exclude
*.o *.o
highscoretest.c
*.psd *.psd
*.exe *.exe
!bhi.exe !bhi.exe

Binary file not shown.

View File

@ -1,13 +1,15 @@
libs = -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lSDL2_image -lSDL2_ttf libs = -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lSDL2_image -lSDL2_ttf
includes = -I".\include" includes = -I".\include"
compiler = gcc compiler = gcc
warningLevel = -Wall warningLevel = -Wall -Wno-unused-variable -Wno-unused-but-set-variable
sources = *.c sources = *.c
linker = -L".\lib" linker = -L".\lib"
dir = bin dir = bin
target = Breakout.exe target = Breakout
args = -o args = -o
all: all:
$(compiler) $(warningLevel) $(includes) $(sources) $(linker) $(libs) $(args) $(dir)\$(target) $(compiler) $(warningLevel) $(includes) $(sources) $(linker) $(libs) $(args) $(dir)\$(target)
run:
cd $(dir) && $(target) cd $(dir) && $(target)

BIN
bin/assets/fonts/ae-bi.ttf Normal file

Binary file not shown.

BIN
bin/assets/fonts/ka1.ttf Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bin/assets/images/Texts.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 151 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 59 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

Binary file not shown.

View File

@ -10,23 +10,27 @@
#include "breakout.h" #include "breakout.h"
#include "vector.h" #include "vector.h"
#define BALL_TexturePath "assets/images/ball.png"
#define PADDLE_TexturePath "assets/images/paddle.png"
#define BLOCK_TexturePath "assets/images/spritesheet.png"
#ifndef __nullptr__ #ifndef __nullptr__
#define Nullptr(type) (type *)0 #define Nullptr(type) (type *)0
#endif // __nullptr__ #endif // __nullptr__
int BLOCK_TextureCount = 24;
int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight; int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight;
SDL_Texture * BALL_Texture; SDL_Texture * BALL_Texture;
SDL_Rect * BALL_SourceRects;
Ball ball;
Paddle paddle;
SDL_Texture * PADDLE_Texture; SDL_Texture * PADDLE_Texture;
SDL_Texture * BLOCK_Texture;
SDL_Rect * BALL_SourceRects;
SDL_Rect * PADDLE_SourceRects; SDL_Rect * PADDLE_SourceRects;
SDL_Rect * BLOCK_SourceRects;
Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys; Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys;
double BALL_Speed = 15.0f;
int PADDLE_Speed = 10;
bool BREAKOUT_IsInit = false; bool BREAKOUT_IsInit = false;
bool BALL_IsInit = false; bool BALL_IsInit = false;
bool PADDLE_IsInit = false; bool PADDLE_IsInit = false;
bool BLOCK_IsInit = false;
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
if (!BREAKOUT_IsInit) { if (!BREAKOUT_IsInit) {
@ -36,46 +40,90 @@ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
BREAKOUT_BoxHeight = height; BREAKOUT_BoxHeight = height;
BALL_Initialize(renderer); BALL_Initialize(renderer);
PADDLE_Initialize(renderer); PADDLE_Initialize(renderer);
BLOCK_Initialize(renderer);
printf("Game initialized!\n"); printf("Game initialized!\n");
BREAKOUT_IsInit = true; BREAKOUT_IsInit = true;
} else printf("Game is already initialized!\n"); } else printf("Game is already initialized!\n");
} } /* BREAKOUT_INITIALIZE */
Scenery BREAKOUT_CreateDefault(){
Scenery scenery;
scenery.BlockCount = 60;
scenery.ball = BALL_CreateDefault();
scenery.paddle = PADDLE_CreateDefault();
scenery.blocks = malloc(scenery.BlockCount * sizeof(Block));
int index;
for (int y = 0; y < 6; y++) {
index = 10 * y;
for (int x = 0; x < 10; x++) {
scenery.blocks[x + index] = BLOCK_CreateDefault();
scenery.blocks[x + index].TargetRect = (SDL_Rect) {.x = ((192 * x) + 4), .y = ((96 * y) + 2), .w = 184, .h = 92 };
scenery.blocks[x + index].TextureIndex = y + x + 2;
// printf("Block created at index: %d\n", (x + index));
// printf("Block Target: %d %d %d %d\n", ( scenery.blocks[x + index].TargetRect.x), ( scenery.blocks[x + index].TargetRect.y), ( scenery.blocks[x + index].TargetRect.w), ( scenery.blocks[x + index].TargetRect.h));
// printf("Block Texture index: %d\n", scenery.blocks[x + index].TextureIndex);
// system("pause");
}
}
return scenery;
} /* BREAKOUT_CreateDefault */
// This Function is obsolete! Do not use it!
void BREAKOUT_ChangeSize(int width, int height){ void BREAKOUT_ChangeSize(int width, int height){
BREAKOUT_BoxWidth = width; BREAKOUT_BoxWidth = width;
BREAKOUT_BoxHeight = height; BREAKOUT_BoxHeight = height;
} }
void BREAKOUT_Update(Uint8 * keystate){ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
BALL_Update(&ball, &paddle); PADDLE_Update(&(scenery->paddle), keystate); // Update paddle before ball because paddle is not static!
PADDLE_Update(&paddle, keystate); BALL_Update(&(scenery->ball), &(scenery->paddle), (scenery->blocks), (scenery->BlockCount));
for (int i = 0; i < (scenery->BlockCount); i++) {
BLOCK_Update((scenery->blocks) + i);
}
} }
void BREAKOUT_Draw(SDL_Renderer * renderer){ void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){
BALL_Draw(renderer, &ball); for (int i = 0; i < (scenery->BlockCount); i++) {
PADDLE_Draw(renderer, &paddle); BLOCK_Draw(renderer, &((scenery->blocks)[i]));
}
BALL_Draw(renderer, &(scenery->ball));
PADDLE_Draw(renderer, &(scenery->paddle));
} }
void BREAKOUT_DEINITIALIZE(){ void BREAKOUT_DEINITIALIZE(){
if (BREAKOUT_IsInit) { if (BREAKOUT_IsInit) {
printf("De-initializing Game...\n"); printf("De-initializing Game...\n");
SDL_DestroyTexture(BALL_Texture); free(PADDLE_MoveLeftKeys);
SDL_DestroyTexture(PADDLE_Texture); free(PADDLE_MoveRightKeys);
free(BALL_SourceRects);
free(PADDLE_SourceRects);
free(BLOCK_SourceRects);
BALL_Deinitialize();
PADDLE_Deinitialize();
BLOCK_Deinitialize();
printf("Game de-initialized!\n"); printf("Game de-initialized!\n");
BREAKOUT_IsInit = false; BREAKOUT_IsInit = false;
} else printf("Game is already de-initialized!\n"); } else printf("Game is already de-initialized!\n");
} }
void BREAKOUT_DestroyObject(Scenery * scenery){
for (size_t i = 0; i < (scenery->BlockCount); i++) {
BLOCK_DestroyObject((scenery->blocks) + i);
}
BALL_DestroyObject(&(scenery->ball));
PADDLE_DestroyObject(&(scenery->paddle));
free((scenery->blocks));
}
void BALL_Initialize(SDL_Renderer * renderer){ void BALL_Initialize(SDL_Renderer * renderer){
if (!BALL_IsInit) { if (!BALL_IsInit) {
printf("Initializing Ball...\n"); printf("Initializing Ball...\n");
BALL_Texture = IMG_LoadTexture(renderer, "assets/images/ball.png"); BALL_Texture = IMG_LoadTexture(renderer, BALL_TexturePath);
if (!BALL_Texture) printf("Ball texture failed to load!\n"); if (!BALL_Texture) printf("Ball texture failed to load!\n");
BALL_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect)); BALL_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect));
if (!BALL_SourceRects) printf("FATAL! Memory allocation failed!\n"); if (!BALL_SourceRects) printf("FATAL! Memory allocation failed!\n");
BALL_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 512, .h = 512 }; BALL_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 512, .h = 512 };
ball = BALL_CreateDefault();
paddle = PADDLE_CreateDefault();
printf("Ball initialized!\n"); printf("Ball initialized!\n");
BALL_IsInit = true; BALL_IsInit = true;
} else printf("Ball is already initialized!\n"); } else printf("Ball is already initialized!\n");
@ -85,13 +133,14 @@ Ball BALL_CreateDefault(){
double rotation = (double)(rand() % 360); double rotation = (double)(rand() % 360);
return (Ball) { return (Ball) {
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2, .y = BREAKOUT_BoxHeight / 2 }, .Location = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 },
.Momentum = (Vector) {.x = 0.0f, .y = BALL_Speed }, .Momentum = (Vector) {.x = 0.0f, .y = 15.0f },
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 50, .h = 50 }, .TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 50, .h = 50 },
.Size = 25.0f, .Size = 25.0f,
.Rotation = rotation, .Rotation = rotation,
.RotationValue = 2, .RotationValue = 2,
.TextureIndex = 0 .TextureIndex = 0,
.Speed = 15.0f
}; // Objekt für die Eigenschaften des Balls }; // Objekt für die Eigenschaften des Balls
} }
@ -101,28 +150,54 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
} }
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){
SDL_Point ballCenter = (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) }; SDL_Point ballCenter = BALL_GetCenter(obj);
// THIS IS CURRENTLY A RECTANGLE COLLIDE if (((obj->TargetRect).x) + ((obj->TargetRect).w) < (rect->x)) return false;
if (((obj->TargetRect).x) + ((obj->TargetRect).w) < (rect->x)) { if (((obj->TargetRect).x) > (rect->x) + (rect->w)) return false;
return false; if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) return false;
} if (((obj->TargetRect).y) > (rect->y) + (rect->h)) return false;
if (((obj->TargetRect).x) > (rect->x) + (rect->w)) { // Already returned with false if square ball hitbox didnt collide with rect
return false; Vector center = (Vector) {.x = ballCenter.x, .y = ballCenter.y };
} Vector corner;
if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) { // Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt!
return false; // double perpendicular, oldMomentum, angle;
} // oldMomentum = fmod((double)(vectorRotation(obj->Momentum) + 180), 360.0f);
if (((obj->TargetRect).y) > (rect->y) + (rect->h)) {
return false; bool left, right, top, bottom, yMid = false, xMid = false;
} left = (ballCenter.x) < (rect->x);
// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt right = (ballCenter.x) > (rect->x) + (rect->w);
if ((ballCenter.x) < (rect->x) || (ballCenter.x) > (rect->x) + (rect->w)) { top = (ballCenter.y) < (rect->y);
bottom = (ballCenter.y) > (rect->y) + (rect->h);
// if (top)
// corner.y = rect->y;
// else if (bottom)
// corner.y = (rect->y) + (rect->w);
// else
// yMid = true;
// if (left)
// corner.x = rect->x;
// else if (right)
// corner.x = (rect->x) + (rect->w);
// else
// xMid = true;
yMid = !(top || bottom);
xMid = !(left || right);
if (yMid)
(obj->Momentum).x = -(obj->Momentum).x; (obj->Momentum).x = -(obj->Momentum).x;
} if (xMid)
if ((ballCenter.y) < (rect->y) || (ballCenter.y) > (rect->y) + (rect->h)) {
(obj->Momentum).y = -(obj->Momentum).y; (obj->Momentum).y = -(obj->Momentum).y;
} // if (yMid && xMid) printf("WARNING: Ball is completely inside block!\n");
// if (yMid || xMid) { // Ball collides with Edge
// } else { // Ball collides with corner
// /*
// * perpendicular = vectorRotation(vectorSub(center, corner));
// * angle = fabs(perpendicular - oldMomentum);
// * if (oldMomentum < perpendicular)
// * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum + (2 * angle)), (obj->Speed));
// * else
// * (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum - (2 * angle)), (obj->Speed));
// */
// }
return true; return true;
} /* BALL_CollideWithRect */ } /* BALL_CollideWithRect */
@ -143,56 +218,83 @@ bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2){
} }
void BALL_SteerMomentum(Ball * obj, Paddle * paddle){ void BALL_SteerMomentum(Ball * obj, Paddle * paddle){
int paddleHalfLen = ((paddle->TargetRect).w / 2.0f); double paddleHalfLen = ((double)((paddle->TargetRect).w) / 2.0f);
double offset = (((obj->TargetRect).x) + (obj->Size)) - ((paddle->TargetRect).x + paddleHalfLen); double offset = (((obj->TargetRect).x) + (obj->Size)) - ((paddle->TargetRect).x + paddleHalfLen);
offset *= 60.0f; offset /= paddleHalfLen;
offset /= (double)(paddleHalfLen); offset *= (paddle->SteeringAngle);
printf("Offset = %.2f\n", offset); DOUBLE_Constrain(&offset, -(paddle->SteeringAngle), (paddle->SteeringAngle));
(obj->Momentum) = getScaledDirectionalUnitVector(offset, BALL_Speed); (obj->Momentum) = getDirectionalUnitVector(offset);
} }
void BALL_Update(Ball * obj, Paddle * paddle){ void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location){
Vector oldMomentum = obj->Momentum; rect->x = (int)round(Location->x);
rect->y = (int)round(Location->y);
}
(obj->Rotation) += (obj->RotationValue); SDL_Point BALL_GetCenter(Ball * obj){
return (SDL_Point) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) };
}
void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount){
Vector oldMomentum = obj->Momentum;
Vector oldLocation = obj->Location;
SDL_Point ballCenter = BALL_GetCenter(obj);
(obj->Rotation) += (obj->RotationValue); // No effect on physics
(obj->Location) = vectorAdd((obj->Location), oldMomentum); (obj->Location) = vectorAdd((obj->Location), oldMomentum);
if (BALL_CollideWithRect(obj, &(paddle->TargetRect))) { if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) {
(obj->Location) = vectorSub((obj->Location), oldMomentum); // Maybe remove this (obj->Location) = oldLocation; // Maybe remove this
BALL_SteerMomentum(obj, paddle); BALL_SteerMomentum(obj, paddle); // Sets it to unit vector!
(obj->Location) = vectorAdd((obj->Location), (obj->Momentum)); // Maybe remove this // Following assumes that the paddle position was udated before the ball was updated
// BUG/GLITCH: Make sure that the postition of the ball is not shifted into the borders of the game!
while (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) { // Move away from rect in small steps
(obj->Location) = vectorAdd((obj->Location), (obj->Momentum));
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
}
(obj->Momentum) = vectorScaleTo((obj->Momentum), (obj->Speed));
}
for (size_t i = 0; i < BlockCount; i++) {
if (blocks[i].HP <= 0) continue;
oldMomentum = obj->Momentum;
oldLocation = obj->Location;
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
BLOCK_DealDamage(blocks + i, 1);
(obj->Location) = vectorAdd(oldLocation, (obj->Momentum));
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
}
} }
if ((obj->Location).y > BREAKOUT_BoxHeight) if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2, .y = BREAKOUT_BoxHeight / 2 }; // Dead (obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead
if ((obj->Location).y < 0.0f) else if ((obj->Location).y < 0.0f)
(obj->Momentum).y = -(obj->Momentum).y; (obj->Momentum).y = -(obj->Momentum).y;
if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size))) if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size)))
(obj->Momentum).x = -(obj->Momentum).x; (obj->Momentum).x = -(obj->Momentum).x;
(obj->TargetRect).x = (int)round((obj->Location).x); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
(obj->TargetRect).y = (int)round((obj->Location).y);
} /* BALL_Update */ } /* BALL_Update */
void BALL_DestroyObject(Ball * obj){ void BALL_DestroyObject(Ball * obj){
} }
void BALL_Deinitialize(){ void BALL_Deinitialize(){
if (BALL_IsInit) { if (BALL_IsInit) {
printf("De-initializing Ball...\n"); printf("De-initializing Ball...\n");
SDL_DestroyTexture(BALL_Texture);
printf("Ball de-initialized!\n"); printf("Ball de-initialized!\n");
BALL_IsInit = false; BALL_IsInit = false;
} else printf("Ball is already de-initialized!\n"); } else printf("Ball is already de-initialized!\n");
} }
void PADDLE_Initialize(SDL_Renderer * renderer){ void PADDLE_Initialize(SDL_Renderer * renderer){
if (!PADDLE_IsInit) { if (!PADDLE_IsInit) {
printf("Initializing Paddle...\n"); printf("Initializing Paddle...\n");
PADDLE_Texture = IMG_LoadTexture(renderer, "assets/images/paddle.png"); PADDLE_Texture = IMG_LoadTexture(renderer, PADDLE_TexturePath);
if (!PADDLE_Texture) printf("Paddle texture failed to load!\n"); if (!PADDLE_Texture) printf("Paddle texture failed to load!\n");
PADDLE_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect)); PADDLE_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect));
if (!PADDLE_SourceRects) printf("FATAL! Memory allocation failed!\n"); if (!PADDLE_SourceRects) printf("FATAL! Memory allocation failed!\n");
PADDLE_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 512, .h = 512 }; PADDLE_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 1000, .h = 100 };
PADDLE_MoveLeftKeys = (Uint8 *)malloc(2 * sizeof(Uint8)); PADDLE_MoveLeftKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
if (!PADDLE_MoveLeftKeys) printf("FATAL! Memory allocation failed!\n"); if (!PADDLE_MoveLeftKeys) printf("FATAL! Memory allocation failed!\n");
PADDLE_MoveRightKeys = (Uint8 *)malloc(2 * sizeof(Uint8)); PADDLE_MoveRightKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
@ -203,7 +305,6 @@ void PADDLE_Initialize(SDL_Renderer * renderer){
PADDLE_MoveRightKeys[0] = 2; PADDLE_MoveRightKeys[0] = 2;
PADDLE_MoveRightKeys[1] = SDL_SCANCODE_RIGHT; PADDLE_MoveRightKeys[1] = SDL_SCANCODE_RIGHT;
PADDLE_MoveRightKeys[2] = SDL_SCANCODE_D; PADDLE_MoveRightKeys[2] = SDL_SCANCODE_D;
ball = BALL_CreateDefault();
printf("Paddle initialized!\n"); printf("Paddle initialized!\n");
PADDLE_IsInit = true; PADDLE_IsInit = true;
} else printf("Paddle is already initialized!\n"); } else printf("Paddle is already initialized!\n");
@ -214,48 +315,151 @@ Paddle PADDLE_CreateDefault(){
return (Paddle) { return (Paddle) {
.TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = defaultpaddlewidth, .h = 30 }, .TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = defaultpaddlewidth, .h = 30 },
.TextureIndex = 0 .TextureIndex = 0,
.Speed = 10,
.SteeringAngle = 40.0f,
.Mode = KeyboardControl
}; // Objekt für die Eigenschaften des Balls }; // Objekt für die Eigenschaften des Balls
} }
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj){ void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj){
// printf("Paddle drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).x); // printf("Paddle drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).x);
// SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect)); SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect));
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); // SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDrawRect(renderer, &(obj->TargetRect)); // SDL_RenderDrawRect(renderer, &(obj->TargetRect));
} }
bool KeyPressed(Uint8 * keystate, Uint8 * keyArray){ bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray){
for (int i = 0; i < (*keyArray); i++) { for (int i = 0; i < (*keyArray); i++) {
if (keystate[keyArray[(i + 1)]]) return true; if (keystate[keyArray[(i + 1)]]) return true;
} }
return false; return false;
} }
void constrain(int * variable, int min, int max){ void INT_Constrain(int * variable, int min, int max){
if (*variable > max) if (*variable > max)
*variable = max; *variable = max;
else if (*variable < min) else if (*variable < min)
*variable = min; *variable = min;
} }
void PADDLE_Update(Paddle * obj, Uint8 * keystate){ void DOUBLE_Constrain(double * variable, double min, double max){
bool leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys), rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys); if (*variable > max)
*variable = max;
else if (*variable < min)
*variable = min;
}
void PADDLE_Update(Paddle * obj, const Uint8 * keystate){
bool leftKeyPressed = false, rightKeyPressed = false;
int paddleXMid = (obj->TargetRect).x + ((obj->TargetRect).w / 2);
int mouseX;
switch (obj->Mode) {
case MouseControl:
SDL_GetMouseState(&mouseX, NULL);
if (abs(mouseX - paddleXMid) > (obj->Speed)) {
if (mouseX > paddleXMid)
rightKeyPressed = true;
else
leftKeyPressed = true;
}
break;
case KeyboardControl:
leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys);
rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys);
break;
default:
printf("Unknown Paddle Control Mode: %d!\n", obj->Mode);
break;
}
if (leftKeyPressed && (!rightKeyPressed)) { if (leftKeyPressed && (!rightKeyPressed)) {
((obj->TargetRect).x) -= PADDLE_Speed; ((obj->TargetRect).x) -= (obj->Speed);
} else if ((!leftKeyPressed) && rightKeyPressed) { } else if ((!leftKeyPressed) && rightKeyPressed) {
((obj->TargetRect).x) += PADDLE_Speed; ((obj->TargetRect).x) += (obj->Speed);
} }
constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w))); INT_Constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w)));
} } /* PADDLE_Update */
void PADDLE_DestroyObject(Paddle * obj){ void PADDLE_DestroyObject(Paddle * obj){
} }
void PADDLE_Deinitialize(){ void PADDLE_Deinitialize(){
if (PADDLE_IsInit) { if (PADDLE_IsInit) {
printf("De-initializing Paddle...\n"); printf("De-initializing Paddle...\n");
SDL_DestroyTexture(PADDLE_Texture);
printf("Paddle de-initialized!\n"); printf("Paddle de-initialized!\n");
PADDLE_IsInit = false; PADDLE_IsInit = false;
} else printf("Paddle is already de-initialized!\n"); } else printf("Paddle is already de-initialized!\n");
} }
void BLOCK_Initialize(SDL_Renderer * renderer){
if (!BLOCK_IsInit) {
printf("Initializing Block...\n");
BLOCK_Texture = IMG_LoadTexture(renderer, BLOCK_TexturePath);
if (!BLOCK_Texture) printf("Block texture failed to load!\n");
BLOCK_SourceRects = (SDL_Rect *)malloc(BLOCK_TextureCount * sizeof(SDL_Rect));
if (!BLOCK_SourceRects) printf("FATAL! Memory allocation failed!\n");
BLOCK_SourceRects[0] = (SDL_Rect) {.x = 2000, .y = 1500, .w = 1000, .h = 500 };
BLOCK_SourceRects[1] = (SDL_Rect) {.x = 2000, .y = 2000, .w = 1000, .h = 500 };
BLOCK_SourceRects[2] = (SDL_Rect) {.x = 2000, .y = 2500, .w = 1000, .h = 500 };
BLOCK_SourceRects[3] = (SDL_Rect) {.x = 0, .y = 3000, .w = 1000, .h = 500 };
BLOCK_SourceRects[4] = (SDL_Rect) {.x = 1000, .y = 3000, .w = 1000, .h = 500 };
BLOCK_SourceRects[5] = (SDL_Rect) {.x = 2000, .y = 3000, .w = 1000, .h = 500 };
BLOCK_SourceRects[6] = (SDL_Rect) {.x = 0, .y = 3500, .w = 1000, .h = 500 };
BLOCK_SourceRects[7] = (SDL_Rect) {.x = 1000, .y = 3500, .w = 1000, .h = 500 };
BLOCK_SourceRects[8] = (SDL_Rect) {.x = 2000, .y = 3500, .w = 1000, .h = 500 };
BLOCK_SourceRects[9] = (SDL_Rect) {.x = 0, .y = 500, .w = 1000, .h = 500 };
BLOCK_SourceRects[10] = (SDL_Rect) {.x = 2000, .y = 0, .w = 1000, .h = 500 };
BLOCK_SourceRects[11] = (SDL_Rect) {.x = 0, .y = 1000, .w = 1000, .h = 500 };
BLOCK_SourceRects[12] = (SDL_Rect) {.x = 0, .y = 1500, .w = 1000, .h = 500 };
BLOCK_SourceRects[13] = (SDL_Rect) {.x = 1000, .y = 0, .w = 1000, .h = 500 };
BLOCK_SourceRects[14] = (SDL_Rect) {.x = 1000, .y = 500, .w = 1000, .h = 500 };
BLOCK_SourceRects[15] = (SDL_Rect) {.x = 1000, .y = 1000, .w = 1000, .h = 500 };
BLOCK_SourceRects[16] = (SDL_Rect) {.x = 1000, .y = 1500, .w = 1000, .h = 500 };
BLOCK_SourceRects[17] = (SDL_Rect) {.x = 0, .y = 2000, .w = 1000, .h = 500 };
BLOCK_SourceRects[18] = (SDL_Rect) {.x = 1000, .y = 2000, .w = 1000, .h = 500 };
BLOCK_SourceRects[19] = (SDL_Rect) {.x = 0, .y = 2500, .w = 1000, .h = 500 };
BLOCK_SourceRects[20] = (SDL_Rect) {.x = 1000, .y = 2500, .w = 1000, .h = 500 };
BLOCK_SourceRects[21] = (SDL_Rect) {.x = 0, .y = 0, .w = 1000, .h = 500 };
BLOCK_SourceRects[22] = (SDL_Rect) {.x = 2000, .y = 500, .w = 1000, .h = 500 };
BLOCK_SourceRects[23] = (SDL_Rect) {.x = 2000, .y = 1000, .w = 1000, .h = 500 };
printf("Block initialized!\n");
BLOCK_IsInit = true;
} else printf("Block is already initialized!\n");
} /* PADDLE_Initialize */
Block BLOCK_CreateDefault() {
return (Block) {
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 100, .h = 50 },
.TextureIndex = (rand() % BLOCK_TextureCount),
.HP = 1
}; // Objekt für die Eigenschaften des Balls
}
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj){
if ((obj->HP) > 0) {
// printf("Block drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).y);
SDL_RenderCopy(renderer, BLOCK_Texture, (BLOCK_SourceRects + (obj->TextureIndex)), &(obj->TargetRect));
}
}
void BLOCK_DealDamage(Block * obj, int dmg){
if (((obj->HP) -= dmg) <= 0) printf("Block was destroyed!\n");
}
void BLOCK_Update(Block * obj){
// Do nothing currently
}
void BLOCK_DestroyObject(Block * obj){
}
void BLOCK_Deinitialize(){
if (BLOCK_IsInit) {
printf("De-initializing Block...\n");
SDL_DestroyTexture(BLOCK_Texture);
printf("Block de-initialized!\n");
BLOCK_IsInit = false;
} else printf("Block is already de-initialized!\n");
}

View File

@ -9,48 +9,75 @@
#include "vector.h" #include "vector.h"
// Enums
typedef enum controlModeEnum {KeyboardControl = 0, MouseControl = 1} ControlMode;
// End Enums
// Structs // Structs
typedef struct ballStruct { typedef struct ballStruct {
Vector Location, Momentum; Vector Location, Momentum;
SDL_Rect TargetRect; SDL_Rect TargetRect;
double Size, Rotation, RotationValue; double Size, Rotation, RotationValue;
int TextureIndex; int TextureIndex;
double Speed;
} Ball; // Objekt für die Eigenschaften des Balls } Ball; // Objekt für die Eigenschaften des Balls
typedef struct paddleStruct { typedef struct paddleStruct {
SDL_Rect TargetRect; SDL_Rect TargetRect;
int TextureIndex; int TextureIndex;
int Speed;
double SteeringAngle;
ControlMode Mode;
} Paddle; // Objekt für die Eigenschaften des Paddles } Paddle; // Objekt für die Eigenschaften des Paddles
typedef struct blockStruct { typedef struct blockStruct {
Vector Location;
SDL_Rect TargetRect; SDL_Rect TargetRect;
int XSize, YSize, TextureIndex; int TextureIndex, HP;
} Block; // Objekt für die Eigenschaften des Paddles } Block; // Objekt für die Eigenschaften des Paddles
typedef struct sceneryStruct {
Ball ball;
Paddle paddle;
Block * blocks;
int BlockCount; // Move to scenery
} Scenery; // Objekt für die Objekte und Eigenschaften einer Szenerie
// End Structs // End Structs
// Prototypes // Prototypes
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height); void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height);
Scenery BREAKOUT_CreateDefault();
void BREAKOUT_ChangeSize(int width, int height); void BREAKOUT_ChangeSize(int width, int height);
void BREAKOUT_Update(Uint8 * keystate); void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate);
void BREAKOUT_Draw(SDL_Renderer * renderer); void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer);
void BREAKOUT_DEINITIALIZE(); void BREAKOUT_DEINITIALIZE();
void BREAKOUT_DestroyObject(Scenery * scenery);
void BALL_Initialize(SDL_Renderer * renderer); void BALL_Initialize(SDL_Renderer * renderer);
Ball BALL_CreateDefault(); Ball BALL_CreateDefault();
void BALL_Draw(SDL_Renderer * renderer, Ball * obj); void BALL_Draw(SDL_Renderer * renderer, Ball * obj);
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect); bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect);
bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2); bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2);
void BALL_Update(Ball * obj, Paddle * paddle); void BALL_SteerMomentum(Ball * obj, Paddle * paddle);
void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location);
SDL_Point BALL_GetCenter(Ball * obj);
void BALL_Update(Ball * obj, Paddle * paddle, Block * blocks, int BlockCount);
void BALL_DestroyObject(Ball * obj); void BALL_DestroyObject(Ball * obj);
void BALL_Deinitialize(); void BALL_Deinitialize();
void PADDLE_Initialize(SDL_Renderer * renderer); void PADDLE_Initialize(SDL_Renderer * renderer);
Paddle PADDLE_CreateDefault(); Paddle PADDLE_CreateDefault();
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj); void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj);
bool KeyPressed(Uint8 * keystate, Uint8 * keyArray); bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray);
void constrain(int * variable, int min, int max); void INT_Constrain(int * variable, int min, int max);
void PADDLE_Update(Paddle * obj, Uint8 * keystate); void DOUBLE_Constrain(double * variable, double min, double max);
void PADDLE_Update(Paddle * obj, const Uint8 * keystate);
void PADDLE_DestroyObject(Paddle * obj); void PADDLE_DestroyObject(Paddle * obj);
void PADDLE_Deinitialize(); void PADDLE_Deinitialize();
void BLOCK_Initialize(SDL_Renderer * renderer);
Block BLOCK_CreateDefault() ;
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj);
void BLOCK_DealDamage(Block * obj, int dmg);
void BLOCK_Update(Block * obj);
void BLOCK_DestroyObject(Block * obj);
void BLOCK_Deinitialize();
// End Prototypes // End Prototypes
#endif // __breakout_h__ #endif // __breakout_h__

0
button.c Normal file
View File

14
button.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __button_h__
#define __button_h__
// Structs
typedef struct buttonStruct {
SDL_Rect TargetRect;
void (*OnClick)();
} Button;
// End Structs
// Prototypes
// End Prototypes
#endif

6
gamestate.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __gamestate_h__
#define __gamestate_h__
typedef enum gameStateEnum { MainMenu = 1, Game = 2, LevelSelect = 3, SkinSelect = 4, Settings = 5, Highscores = 6 } GameState;
#endif

167
highscores.c Normal file
View File

@ -0,0 +1,167 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include "highscores.h"
#define HIGHSCORES_FontFile "assets/fonts/monofur.ttf"
int HIGHSCORES_EntriesGot = 0;
User * HIGHSCORES_UserList;
SDL_Color HIGHSCORES_FontColor;
SDL_Texture * HIGHSCORES_TableTexture;
SDL_Rect HIGHSCORES_TotalRect;
TTF_Font * HIGHSCORES_FontFamily = NULL;
SDL_Surface * tempSurface;
void HIGHSCORES_Initialize(){
printf("Initializing Highscores...\n");
HIGHSCORES_FontColor = (SDL_Color) {255, 255, 255 };
HIGHSCORES_UserList = malloc(10 * sizeof(User));
HIGHSCORES_FontFamily = TTF_OpenFont(HIGHSCORES_FontFile, 48);
if (!HIGHSCORES_FontFamily) printf("Font could not initialize! Error: %s\n", TTF_GetError());
else printf("Font was successfully initialized!\n");
printFontStyle(HIGHSCORES_FontFamily);
HIGHSCORES_TotalRect = (SDL_Rect) {.x = 0, .y = 0, .w = 1920, .h = 1080 };
printf("Highscores initialized!\n");
}
void printFontStyle(TTF_Font * ffont){
int style;
style = TTF_GetFontStyle(ffont);
printf("The font style is:");
if (style == TTF_STYLE_NORMAL)
printf(" normal");
else {
if (style & TTF_STYLE_BOLD)
printf(" bold");
if (style & TTF_STYLE_ITALIC)
printf(" italic");
if (style & TTF_STYLE_UNDERLINE)
printf(" underline");
if (style & TTF_STYLE_STRIKETHROUGH)
printf(" strikethrough");
}
printf("\n");
}
void HIGHSCORES_Draw(SDL_Renderer * renderer){
SDL_RenderCopy(renderer, HIGHSCORES_TableTexture, &HIGHSCORES_TotalRect, &HIGHSCORES_TotalRect);
} /* HIGHSCORES_Draw */
void HIGHSCORES_Deinitialize(){
printf("De-initializing Highscores...\n");
TTF_CloseFont(HIGHSCORES_FontFamily);
HIGHSCORES_FontFamily = NULL; // to be safe...
SDL_DestroyTexture(HIGHSCORES_TableTexture);
SDL_FreeSurface(tempSurface);
free(HIGHSCORES_UserList);
printf("Highscores de-initialized!\n");
}
void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer){
char * buffer = calloc(100, sizeof(char));
int count = 0;
char format[20] = "| %-58s | %-10s |";
SDL_Rect Message_rect;
SDL_Surface * HIGHSCORES_TableSurface = SDL_CreateRGBSurface(0, 1920, 1080, 32, 0, 0, 0, 0);
if (!HIGHSCORES_TableSurface) {
printf("Surface wasn't created!\n");
}
sprintf(buffer, format, "Username", "Score");
HIGHSCORES_DrawText(buffer, &Message_rect);
Message_rect.y = 70;
Message_rect.x = 50;
Message_rect.h = 50;
Message_rect.w = 50;
SDL_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect);
SDL_FreeSurface(tempSurface);
while (count < HIGHSCORES_EntriesGot) {
sprintf(buffer, format, HIGHSCORES_UserList[count].Username, HIGHSCORES_UserList[count].Score);
HIGHSCORES_DrawText(buffer, &Message_rect);
Message_rect.y = ((Message_rect.h + 15) * (count + 1)) + 140;
Message_rect.x = 50;
SDL_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect);
SDL_FreeSurface(tempSurface);
count++;
}
HIGHSCORES_TableTexture = SDL_CreateTextureFromSurface(renderer, HIGHSCORES_TableSurface);
if (!HIGHSCORES_TableTexture) {
printf("Texture wasn't created!\n");
}
SDL_FreeSurface(HIGHSCORES_TableSurface);
} /* HIGHSCORES_GenerateSurface */
void HIGHSCORES_DrawText(char * text, SDL_Rect * Message_rect){
TTF_SizeText(HIGHSCORES_FontFamily, text, &(Message_rect->w), &(Message_rect->h));
tempSurface = TTF_RenderText_Solid(HIGHSCORES_FontFamily, text, HIGHSCORES_FontColor);
}
void HIGHSCORES_ReloadList(){
printf("Call BHI interface:\n");
system("bhi top output.txt");
printf("BHI interface quit!\nBHI output handling...\n");
HIGHSCORES_EntriesGot = 0;
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
char * name, * scorestring;
int nameCharCount = 0, scoreCharCount = 0;
bool switchread = false;
HIGHSCORES_UserList = malloc(10 * sizeof(User));
fp = fopen("output.txt", "r");
if (fp == NULL)
return;
if ((read = getline(&line, &len, fp)) != -1)
if (line[0] == 0)
return;
int counter = 0;
while ((read = getline(&line, &len, fp)) != -1) {
name = malloc(read * sizeof(char));
scorestring = malloc(read * sizeof(char));
nameCharCount = 0;
scoreCharCount = 0;
switchread = false;
#ifdef DEBUG
printf("Retrieved line of length %u:\n", read);
printf("%s", line);
#endif
for (ssize_t i = 0; i < read; i++) {
if (line[i] == '+') {
switchread = true;
continue;
}
if (switchread) {
if (line[i] == '\n') break;
scorestring[scoreCharCount++] = line[i];
} else
name[nameCharCount++] = line[i];
}
name[nameCharCount] = '\0';
scorestring[scoreCharCount] = '\0';
User tmp;
strcpy(tmp.Username, name);
strcpy(tmp.Score, scorestring);
HIGHSCORES_UserList[counter++] = tmp;
}
free(name);
free(scorestring);
fclose(fp);
if (line)
free(line);
for (size_t i = 0; i < counter; i++) {
printf("User: %s -> Score: %s\n", HIGHSCORES_UserList[i].Username, HIGHSCORES_UserList[i].Score);
}
HIGHSCORES_EntriesGot = counter;
printf("BHI Interface successfully quit!\n");
} /* main */

20
highscores.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef __highscores_h__
#define __highscores_h__
// Structs
typedef struct userStruct {
char Username[50], Score[30];
} User;
// End Structs
// Prototypes
void HIGHSCORES_Initialize();
void printFontStyle(TTF_Font * ffont);
void HIGHSCORES_Draw(SDL_Renderer * renderer);
void HIGHSCORES_Deinitialize();
void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer);
void HIGHSCORES_DrawText(char * text, SDL_Rect * Message_rect);
void HIGHSCORES_ReloadList();
// End Prototypes
#endif

176
main.c
View File

@ -9,63 +9,105 @@
#include "breakout.h" #include "breakout.h"
#include "vector.h" #include "vector.h"
#include "startmenu.h"
#include "gamestate.h"
#include "highscores.h"
#include "settings.h"
#ifndef __nullptr__ #include "main.h"
#define Nullptr(type) (type *)0
#endif // __nullptr__
void DrawFrame(); // Default Render Size (Upscaled for bigger monitors)
void INITIALIZE(); const int width = 1920;
void QUIT(); const int height = 1080;
void GAMELOOP(); float XScale = 1.0f, YScale = 1.0f;
void mousePress(SDL_MouseButtonEvent b); // End render properties
void keyPress(SDL_KeyboardEvent b);
void windowChanged(SDL_WindowEvent b);
void toggleFullscreen();
const int width = 1600; // TODO: Fullscreen int numKeys;
const int height = 900; const Uint8 * keystate; // TODO: export all this into scenery and enemy waves
Uint8 * keystate; // TODO: export all this into scenery and enemy waves
SDL_Window * window; SDL_Window * window;
SDL_Renderer * renderer; SDL_Renderer * renderer;
SDL_Event event; SDL_Event event;
bool running = true, fullscreen = false; bool running = true, fullscreen = false;
GameState gameState = MainMenu;
Ball ball; Scenery scenery;
int main(int argc, char * args[]){ int main(int argc, char * args[]){
// system("bhi.exe"); // printf("Spielbereiche\n\t- 1: Hauptmen"ue "\n\t- 2: Spiel\n\t- 3: Level Select\n\t- 4: Settings\n\t- 5: Highscores\n");
// GAME_ChangeState(readIntFromIO("W"ae "hle einen Spielbereich aus, den du testen m"oe "chtest:", "Fehlerhafte Eingabe!\n", "%d ist kein g"ue "ltiger Spielbereich!\n", 1, 5));
INITIALIZE(); INITIALIZE();
while (running) { // Gameloop while (running) { // Gameloop
while (SDL_PollEvent(&event)) { HandleSDLEvents();
switch (event.type) { DrawBackground(renderer);
case SDL_QUIT: switch (gameState) {
running = false; case Game:
break; BREAKOUT_Update(&scenery, keystate);
case SDL_KEYDOWN: BREAKOUT_Draw(&scenery, renderer);
if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false; break;
else keyPress(event.key); case MainMenu:
break; // Startmenu_Update(keystate);
case SDL_MOUSEBUTTONDOWN: Startmenu_Draw(renderer);
mousePress(event.button); break;
break; case Highscores:
case SDL_WINDOWEVENT: HIGHSCORES_Draw(renderer);
windowChanged(event.window); break;
break; case Settings:
} Settings_Draw(renderer);
break;
default:
printf("Unknow state was updated: %d\n", gameState);
break;
} }
GAMELOOP(); SDL_RenderPresent(renderer);
DrawFrame();
} }
QUIT(); QUIT();
return 0; return 0;
} /* main */ } /* main */
void GAMELOOP() { void GAME_Escape(){
keystate = SDL_GetKeyboardState(NULL); running = false;
BREAKOUT_Update(keystate); printf("GAME_Escape was called!\n");
} /* GAMELOOP */ }
void GAME_ChangeState(GameState state){
if (gameState == state) {
printf("State wasn't changed!\n");
return;
}
gameState = state;
switch (gameState) {
case Highscores:
HIGHSCORES_ReloadList();
HIGHSCORES_GenerateTexture(renderer);
printf("State was changed to Highscores!\n");
break;
default:
printf("State was changed to %d!\n", gameState);
break;
}
}
void HandleSDLEvents(){
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
printf("NOTICE: User manually quit window!\n");
running = false;
break;
case SDL_KEYDOWN:
// if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false;
// else
keyPress(event.key);
break;
case SDL_MOUSEBUTTONDOWN:
mousePress(event.button);
button_clicked(event.button, gameState);
break;
case SDL_WINDOWEVENT:
windowChanged(event.window);
break;
}
}
} /* HandleSDLEvents */
void mousePress(SDL_MouseButtonEvent b){ // Debug prop void mousePress(SDL_MouseButtonEvent b){ // Debug prop
if (b.button == SDL_BUTTON_LEFT) { if (b.button == SDL_BUTTON_LEFT) {
@ -97,25 +139,29 @@ void windowChanged(SDL_WindowEvent b){ // Debug prop
switch (b.event) { switch (b.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED: case SDL_WINDOWEVENT_SIZE_CHANGED:
printf("Window was resized to (%d|%d)!\n", event.window.data1, event.window.data2); printf("Window was resized to (%d|%d)!\n", event.window.data1, event.window.data2);
BREAKOUT_ChangeSize(event.window.data1, event.window.data2); // BREAKOUT_ChangeSize(event.window.data1, event.window.data2);
XScale = ((double)(event.window.data1) / (double)width);
YScale = ((double)(event.window.data2) / (double)height);
SDL_RenderSetScale(renderer, XScale, YScale);
break; break;
} }
} }
void DrawFrame(){ void DrawBackground(SDL_Renderer * renderer){
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
BREAKOUT_Draw(renderer); } /* DrawFrame */
SDL_RenderPresent(renderer);
}
void INITIALIZE() { void INITIALIZE() {
printf("Initializing started...\n");
srand(time(NULL)); srand(time(NULL));
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); if (SDL_Init(SDL_INIT_EVERYTHING) != 0) printf("SDL could not initialize! Error: %s\n", SDL_GetError());
else printf("SDL was successfully initialized!\n"); else printf("SDL was successfully initialized!\n");
if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) printf("IMG could not initialize! IMG_Error: %s\n", IMG_GetError()); keystate = SDL_GetKeyboardState(&numKeys);
if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) printf("IMG could not initialize! Error: %s\n", IMG_GetError());
else printf("IMG was successfully initialized!\n"); else printf("IMG was successfully initialized!\n");
TTF_Init(); if (TTF_Init() == -1) printf("TTF could not initialize! Error: %s\n", TTF_GetError());
else printf("TTF was successfully initialized!\n");
window = SDL_CreateWindow("BreakING", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL); window = SDL_CreateWindow("BreakING", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_OPENGL);
SDL_SetWindowResizable(window, true); SDL_SetWindowResizable(window, true);
@ -123,12 +169,19 @@ void INITIALIZE() {
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
printf("Renderer was created!\n"); printf("Renderer was created!\n");
BREAKOUT_INITIALIZE(renderer, width, height); BREAKOUT_INITIALIZE(renderer, width, height);
scenery = BREAKOUT_CreateDefault();
Load_Textures(renderer);
HIGHSCORES_Initialize();
Settings_Initialize(renderer);
printf("Initializing finished!\n");
} /* INITIALIZE */ } /* INITIALIZE */
void QUIT(){ void QUIT(){
printf("De-initializing started...\n"); printf("De-initializing started...\n");
Settings_Deinitialize();
HIGHSCORES_Deinitialize();
BREAKOUT_DestroyObject(&scenery);
BREAKOUT_DEINITIALIZE(); BREAKOUT_DEINITIALIZE();
free(keystate);
TTF_Quit(); TTF_Quit();
IMG_Quit(); IMG_Quit();
printf("Quitting SDL_IMG finished!\n"); printf("Quitting SDL_IMG finished!\n");
@ -140,3 +193,28 @@ void QUIT(){
printf("Quitting SDL finished!\n"); printf("Quitting SDL finished!\n");
printf("De-initializing finished!\n"); printf("De-initializing finished!\n");
} /* QUIT */ } /* QUIT */
int readIntFromIO(char * m1, char * m2, char * m3, int min, int max){
int nitems, num;
while (1) {
while (1) {
printf(m1);
nitems = scanf("%d", &num);
if (nitems == 0) {
printf(m2);
fflush(stdin);
continue;
} else {
break;
}
}
if ((num < min) || (num > max)) {
printf(m3, num);
} else {
break;
}
}
fflush(stdin);
return(num);
} /* readIntFromIO */

42
main.h Normal file
View File

@ -0,0 +1,42 @@
#ifndef __main_h__
#define __main_h__
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include "breakout.h"
#include "vector.h"
#include "startmenu.h"
#include "gamestate.h"
#include "highscores.h"
#ifndef __nullptr__
#define Nullptr(type) (type *)0
#endif // __nullptr__
#define ae "\204"
#define oe "\224"
#define ue "\201"
#define ss "\341"
// Prototypes
void GAME_ChangeState(GameState state);
void HandleSDLEvents();
void GAME_Escape();
void mousePress(SDL_MouseButtonEvent b);
void keyPress(SDL_KeyboardEvent b);
void toggleFullscreen();
void windowChanged(SDL_WindowEvent b);
void DrawBackground(SDL_Renderer * renderer);
void INITIALIZE();
void QUIT();
int readIntFromIO(char * m1, char * m2, char * m3, int min, int max);
// End Prototypes
#endif // __main_h__

0
paddle.c Normal file
View File

62
settings.c Normal file
View File

@ -0,0 +1,62 @@
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdbool.h>
SDL_Texture* Setting_Texture;
SDL_Rect Settings_rect;
SDL_Rect BV_Bar_rect;
SDL_Rect BV_Scalar_rect;
SDL_Rect BS_Bar_rect;
SDL_Rect BT_Bar_rect;
SDL_Rect BVController_rect;
bool Settings_IsInit=false;
void Settings_Initialize (SDL_Renderer* renderer) {
BV_Bar_rect = (SDL_Rect){.y = 300,.x = 400 , .w=400, .h=100};
BV_Scalar_rect = (SDL_Rect){.y=300,.x=420,.w=20,.h=100};
BS_Bar_rect = (SDL_Rect){.y = 500,.x = 400, .w=400, .h=100};
BT_Bar_rect = (SDL_Rect){.y = 700,.x = 400, .w=400, .h=100};
Setting_Texture = IMG_LoadTexture(renderer, "assets/images/settings_title.png");
Settings_rect = (SDL_Rect){.x = 800, .y = 180, .w=313, .h=100};
Settings_IsInit = true;
}
void Settings_Draw (SDL_Renderer* renderer) {
SDL_SetRenderDrawColor(renderer,255,255,255,255);
SDL_RenderDrawRect(renderer,&BV_Bar_rect);
SDL_RenderDrawRect(renderer,&BS_Bar_rect);
SDL_RenderDrawRect(renderer,&BT_Bar_rect);
SDL_RenderDrawRect(renderer,&BV_Scalar_rect);
SDL_RenderCopy(renderer, Setting_Texture, NULL, &Settings_rect);
int x,y;
Uint32 Mousestate=SDL_GetMouseState(&x,&y);
if(y<=400&&y>=300&&x<=800&&x>=400&&(Mousestate & SDL_BUTTON(SDL_BUTTON_LEFT))){
SDL_RenderFillRect(renderer,&BV_Scalar_rect);
SDL_RenderDrawRect(renderer,&BV_Scalar_rect);
if(x>790){
BV_Scalar_rect.x=780;
}
else if(x<410){
BV_Scalar_rect.x=400;
}
else{
BV_Scalar_rect.x=x-10;
}
}
else{
SDL_RenderDrawRect(renderer,&BV_Scalar_rect);
}
printf("%d,%d\n",x,y);
}
void Settings_Deinitialize(){
if(Settings_IsInit){
SDL_DestroyTexture(Setting_Texture);
Settings_IsInit=false;
}
}

18
settings.h Normal file
View File

@ -0,0 +1,18 @@
#ifndef __Settings__
#define __Settings__
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdbool.h>
void Settings_Initialize (SDL_Renderer* renderer);
void Settings_Draw (SDL_Renderer* renderer);
void Settings_Deinitialize();
#endif

78
startmenu.c Normal file
View File

@ -0,0 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "gamestate.h"
#include "main.h"
SDL_Texture * TITLE_Texture;
SDL_Texture * PLAYBUTTON_Texture;
SDL_Texture * SKINSBUTTON_Texture;
SDL_Texture * LEVELBUTTON_Texture;
SDL_Texture * SETTINGSBUTTON_Texture;
SDL_Texture * HIGHSCORESBUTTON_Texture;
SDL_Texture * QUITBUTTON_Texture;
SDL_Rect TITLE_Rect;
SDL_Rect PLAYBUTTON_Rect;
SDL_Rect SETTINGSBUTTON_Rect;
SDL_Rect LEVELBUTTON_Rect;
SDL_Rect SKINSBUTTON_Rect;
SDL_Rect HIGHSCORESBUTTON_Rect;
SDL_Rect QUITBUTTON_Rect;
int clickInRect(SDL_MouseButtonEvent b, SDL_Rect * area_rect) {
return (((b.x) >= (area_rect->x)) && ((b.x) <= ((area_rect->x) + (area_rect->w))) && ((b.y) >= (area_rect->y)) && ((b.y) <= ((area_rect->y) + (area_rect->h))));
}
void Load_Textures(SDL_Renderer * renderer) {
TITLE_Texture = IMG_LoadTexture(renderer, "assets/images/breaking_button.png");
TITLE_Rect = (SDL_Rect) {.x = 685, .y = 50, .w = 550, .h = 250 };
PLAYBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/play_button.png");
PLAYBUTTON_Rect = (SDL_Rect) {.x = 497, .y = 400, .w = 313, .h = 178 };
SKINSBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/skins_button.png");
SKINSBUTTON_Rect = (SDL_Rect) {.x = 1110, .y = 400, .w = 313, .h = 178 };
LEVELBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/level_button.png");
LEVELBUTTON_Rect = (SDL_Rect) {.x = 497, .y = 700, .w = 313, .h = 178 };
SETTINGSBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/settings_button.png");
SETTINGSBUTTON_Rect = (SDL_Rect) {.x = 1110, .y = 700, .w = 313, .h = 178 };
HIGHSCORESBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/highscores_button.png");
HIGHSCORESBUTTON_Rect = (SDL_Rect) {.x = 1557, .y = 120, .w = 313, .h = 178 };
QUITBUTTON_Texture = IMG_LoadTexture(renderer, "assets/images/quit_button.png");
QUITBUTTON_Rect = (SDL_Rect) {.x = 50, .y = 896, .w = 235, .h = 134 };
} /* Load_Textures */
void Startmenu_Draw(SDL_Renderer * renderer) {
SDL_RenderCopy(renderer, TITLE_Texture, NULL, &TITLE_Rect);
SDL_RenderCopy(renderer, PLAYBUTTON_Texture, NULL, &PLAYBUTTON_Rect);
SDL_RenderCopy(renderer, SKINSBUTTON_Texture, NULL, &SKINSBUTTON_Rect);
SDL_RenderCopy(renderer, LEVELBUTTON_Texture, NULL, &LEVELBUTTON_Rect);
SDL_RenderCopy(renderer, SETTINGSBUTTON_Texture, NULL, &SETTINGSBUTTON_Rect);
SDL_RenderCopy(renderer, HIGHSCORESBUTTON_Texture, NULL, &HIGHSCORESBUTTON_Rect);
SDL_RenderCopy(renderer, QUITBUTTON_Texture, NULL, &QUITBUTTON_Rect);
}
void button_clicked(SDL_MouseButtonEvent b, GameState gameState) {
if (gameState == MainMenu) {
if (clickInRect(b, &PLAYBUTTON_Rect) == 1) {
GAME_ChangeState(Game);
} else if (clickInRect(b, &SKINSBUTTON_Rect) == 1) {
GAME_ChangeState(SkinSelect);
} else if (clickInRect(b, &LEVELBUTTON_Rect) == 1) {
GAME_ChangeState(LevelSelect);
} else if (clickInRect(b, &SETTINGSBUTTON_Rect) == 1) {
GAME_ChangeState(Settings);
} else if (clickInRect(b, &HIGHSCORESBUTTON_Rect) == 1) {
GAME_ChangeState(Highscores);
} else if (clickInRect(b, &QUITBUTTON_Rect) == 1) {
GAME_Escape();
}
}
}

20
startmenu.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef __Startmenu__
#define __Startmenu__
#include <stdio.h>
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include "gamestate.h"
void Load_Textures (SDL_Renderer* renderer);
void Startmenu_Draw (SDL_Renderer* renderer);
void button_clicked(SDL_MouseButtonEvent b, GameState gameState);
int clickInRect(SDL_MouseButtonEvent b, SDL_Rect* area_rect);
#endif