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
# 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
*.cbp
*.layout
sdl2-config
*.exclude
*.o
highscoretest.c
*.psd
*.exe
!bhi.exe

Binary file not shown.

View File

@ -1,13 +1,15 @@
libs = -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lSDL2_image -lSDL2_ttf
includes = -I".\include"
compiler = gcc
warningLevel = -Wall
warningLevel = -Wall -Wno-unused-variable -Wno-unused-but-set-variable
sources = *.c
linker = -L".\lib"
dir = bin
target = Breakout.exe
target = Breakout
args = -o
all:
$(compiler) $(warningLevel) $(includes) $(sources) $(linker) $(libs) $(args) $(dir)\$(target)
run:
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 "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__
#define Nullptr(type) (type *)0
#endif // __nullptr__
int BLOCK_TextureCount = 24;
int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight;
SDL_Texture * BALL_Texture;
SDL_Rect * BALL_SourceRects;
Ball ball;
Paddle paddle;
SDL_Texture * PADDLE_Texture;
SDL_Texture * BLOCK_Texture;
SDL_Rect * BALL_SourceRects;
SDL_Rect * PADDLE_SourceRects;
SDL_Rect * BLOCK_SourceRects;
Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys;
double BALL_Speed = 15.0f;
int PADDLE_Speed = 10;
bool BREAKOUT_IsInit = false;
bool BALL_IsInit = false;
bool PADDLE_IsInit = false;
bool BLOCK_IsInit = false;
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
if (!BREAKOUT_IsInit) {
@ -36,46 +40,90 @@ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){
BREAKOUT_BoxHeight = height;
BALL_Initialize(renderer);
PADDLE_Initialize(renderer);
BLOCK_Initialize(renderer);
printf("Game initialized!\n");
BREAKOUT_IsInit = true;
} 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){
BREAKOUT_BoxWidth = width;
BREAKOUT_BoxHeight = height;
}
void BREAKOUT_Update(Uint8 * keystate){
BALL_Update(&ball, &paddle);
PADDLE_Update(&paddle, keystate);
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
PADDLE_Update(&(scenery->paddle), keystate); // Update paddle before ball because paddle is not static!
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){
BALL_Draw(renderer, &ball);
PADDLE_Draw(renderer, &paddle);
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){
for (int i = 0; i < (scenery->BlockCount); i++) {
BLOCK_Draw(renderer, &((scenery->blocks)[i]));
}
BALL_Draw(renderer, &(scenery->ball));
PADDLE_Draw(renderer, &(scenery->paddle));
}
void BREAKOUT_DEINITIALIZE(){
if (BREAKOUT_IsInit) {
printf("De-initializing Game...\n");
SDL_DestroyTexture(BALL_Texture);
SDL_DestroyTexture(PADDLE_Texture);
free(PADDLE_MoveLeftKeys);
free(PADDLE_MoveRightKeys);
free(BALL_SourceRects);
free(PADDLE_SourceRects);
free(BLOCK_SourceRects);
BALL_Deinitialize();
PADDLE_Deinitialize();
BLOCK_Deinitialize();
printf("Game de-initialized!\n");
BREAKOUT_IsInit = false;
} 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){
if (!BALL_IsInit) {
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");
BALL_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect));
if (!BALL_SourceRects) printf("FATAL! Memory allocation failed!\n");
BALL_SourceRects[0] = (SDL_Rect) {.x = 0, .y = 0, .w = 512, .h = 512 };
ball = BALL_CreateDefault();
paddle = PADDLE_CreateDefault();
printf("Ball initialized!\n");
BALL_IsInit = true;
} else printf("Ball is already initialized!\n");
@ -85,13 +133,14 @@ Ball BALL_CreateDefault(){
double rotation = (double)(rand() % 360);
return (Ball) {
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2, .y = BREAKOUT_BoxHeight / 2 },
.Momentum = (Vector) {.x = 0.0f, .y = BALL_Speed },
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 },
.Momentum = (Vector) {.x = 0.0f, .y = 15.0f },
.TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 50, .h = 50 },
.Size = 25.0f,
.Rotation = rotation,
.RotationValue = 2,
.TextureIndex = 0
.TextureIndex = 0,
.Speed = 15.0f
}; // 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){
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) > (rect->x) + (rect->w)) {
return false;
}
if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) {
return false;
}
if (((obj->TargetRect).y) > (rect->y) + (rect->h)) {
return false;
}
// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt
if ((ballCenter.x) < (rect->x) || (ballCenter.x) > (rect->x) + (rect->w)) {
if (((obj->TargetRect).x) + ((obj->TargetRect).w) < (rect->x)) return false;
if (((obj->TargetRect).x) > (rect->x) + (rect->w)) return false;
if (((obj->TargetRect).y) + ((obj->TargetRect).w) < (rect->y)) return false;
if (((obj->TargetRect).y) > (rect->y) + (rect->h)) return false;
// Already returned with false if square ball hitbox didnt collide with rect
Vector center = (Vector) {.x = ballCenter.x, .y = ballCenter.y };
Vector corner;
// Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt!
// double perpendicular, oldMomentum, angle;
// oldMomentum = fmod((double)(vectorRotation(obj->Momentum) + 180), 360.0f);
bool left, right, top, bottom, yMid = false, xMid = false;
left = (ballCenter.x) < (rect->x);
right = (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;
}
if ((ballCenter.y) < (rect->y) || (ballCenter.y) > (rect->y) + (rect->h)) {
if (xMid)
(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;
} /* BALL_CollideWithRect */
@ -143,56 +218,83 @@ bool RECT_Collide(SDL_Rect * rect1, SDL_Rect * rect2){
}
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);
offset *= 60.0f;
offset /= (double)(paddleHalfLen);
printf("Offset = %.2f\n", offset);
(obj->Momentum) = getScaledDirectionalUnitVector(offset, BALL_Speed);
offset /= paddleHalfLen;
offset *= (paddle->SteeringAngle);
DOUBLE_Constrain(&offset, -(paddle->SteeringAngle), (paddle->SteeringAngle));
(obj->Momentum) = getDirectionalUnitVector(offset);
}
void BALL_Update(Ball * obj, Paddle * paddle){
Vector oldMomentum = obj->Momentum;
void RECT_SetTargetPos(SDL_Rect * rect, Vector * Location){
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);
if (BALL_CollideWithRect(obj, &(paddle->TargetRect))) {
(obj->Location) = vectorSub((obj->Location), oldMomentum); // Maybe remove this
BALL_SteerMomentum(obj, paddle);
(obj->Location) = vectorAdd((obj->Location), (obj->Momentum)); // Maybe remove this
if (RECT_Collide(&(obj->TargetRect), &(paddle->TargetRect))) {
(obj->Location) = oldLocation; // Maybe remove this
BALL_SteerMomentum(obj, paddle); // Sets it to unit vector!
// 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)
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2, .y = BREAKOUT_BoxHeight / 2 }; // Dead
if ((obj->Location).y < 0.0f)
if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead
else if ((obj->Location).y < 0.0f)
(obj->Momentum).y = -(obj->Momentum).y;
if ((obj->Location).x < 0.0f || (obj->Location).x > BREAKOUT_BoxWidth - (2 * (obj->Size)))
(obj->Momentum).x = -(obj->Momentum).x;
(obj->TargetRect).x = (int)round((obj->Location).x);
(obj->TargetRect).y = (int)round((obj->Location).y);
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} /* BALL_Update */
void BALL_DestroyObject(Ball * obj){
}
void BALL_Deinitialize(){
if (BALL_IsInit) {
printf("De-initializing Ball...\n");
SDL_DestroyTexture(BALL_Texture);
printf("Ball de-initialized!\n");
BALL_IsInit = false;
} else printf("Ball is already de-initialized!\n");
}
void PADDLE_Initialize(SDL_Renderer * renderer){
if (!PADDLE_IsInit) {
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");
PADDLE_SourceRects = (SDL_Rect *)malloc(1 * sizeof(SDL_Rect));
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));
if (!PADDLE_MoveLeftKeys) printf("FATAL! Memory allocation failed!\n");
PADDLE_MoveRightKeys = (Uint8 *)malloc(2 * sizeof(Uint8));
@ -203,7 +305,6 @@ void PADDLE_Initialize(SDL_Renderer * renderer){
PADDLE_MoveRightKeys[0] = 2;
PADDLE_MoveRightKeys[1] = SDL_SCANCODE_RIGHT;
PADDLE_MoveRightKeys[2] = SDL_SCANCODE_D;
ball = BALL_CreateDefault();
printf("Paddle initialized!\n");
PADDLE_IsInit = true;
} else printf("Paddle is already initialized!\n");
@ -214,48 +315,151 @@ Paddle PADDLE_CreateDefault(){
return (Paddle) {
.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
}
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj){
// 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_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDrawRect(renderer, &(obj->TargetRect));
SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + (obj->TextureIndex), &(obj->TargetRect));
// SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
// 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++) {
if (keystate[keyArray[(i + 1)]]) return true;
}
return false;
}
void constrain(int * variable, int min, int max){
void INT_Constrain(int * variable, int min, int max){
if (*variable > max)
*variable = max;
else if (*variable < min)
*variable = min;
}
void PADDLE_Update(Paddle * obj, Uint8 * keystate){
bool leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys), rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys);
void DOUBLE_Constrain(double * variable, double min, double max){
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)) {
((obj->TargetRect).x) -= PADDLE_Speed;
((obj->TargetRect).x) -= (obj->Speed);
} 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_Deinitialize(){
if (PADDLE_IsInit) {
printf("De-initializing Paddle...\n");
SDL_DestroyTexture(PADDLE_Texture);
printf("Paddle de-initialized!\n");
PADDLE_IsInit = false;
} 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"
// Enums
typedef enum controlModeEnum {KeyboardControl = 0, MouseControl = 1} ControlMode;
// End Enums
// Structs
typedef struct ballStruct {
Vector Location, Momentum;
SDL_Rect TargetRect;
double Size, Rotation, RotationValue;
int TextureIndex;
double Speed;
} Ball; // Objekt für die Eigenschaften des Balls
typedef struct paddleStruct {
SDL_Rect TargetRect;
int TextureIndex;
int Speed;
double SteeringAngle;
ControlMode Mode;
} Paddle; // Objekt für die Eigenschaften des Paddles
typedef struct blockStruct {
Vector Location;
SDL_Rect TargetRect;
int XSize, YSize, TextureIndex;
int TextureIndex, HP;
} 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
// Prototypes
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height);
Scenery BREAKOUT_CreateDefault();
void BREAKOUT_ChangeSize(int width, int height);
void BREAKOUT_Update(Uint8 * keystate);
void BREAKOUT_Draw(SDL_Renderer * renderer);
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate);
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer);
void BREAKOUT_DEINITIALIZE();
void BREAKOUT_DestroyObject(Scenery * scenery);
void BALL_Initialize(SDL_Renderer * renderer);
Ball BALL_CreateDefault();
void BALL_Draw(SDL_Renderer * renderer, Ball * obj);
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect);
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_Deinitialize();
void PADDLE_Initialize(SDL_Renderer * renderer);
Paddle PADDLE_CreateDefault();
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj);
bool KeyPressed(Uint8 * keystate, Uint8 * keyArray);
void constrain(int * variable, int min, int max);
void PADDLE_Update(Paddle * obj, Uint8 * keystate);
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray);
void INT_Constrain(int * variable, int min, int max);
void DOUBLE_Constrain(double * variable, double min, double max);
void PADDLE_Update(Paddle * obj, const Uint8 * keystate);
void PADDLE_DestroyObject(Paddle * obj);
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
#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 "vector.h"
#include "startmenu.h"
#include "gamestate.h"
#include "highscores.h"
#include "settings.h"
#ifndef __nullptr__
#define Nullptr(type) (type *)0
#endif // __nullptr__
#include "main.h"
void DrawFrame();
void INITIALIZE();
void QUIT();
void GAMELOOP();
void mousePress(SDL_MouseButtonEvent b);
void keyPress(SDL_KeyboardEvent b);
void windowChanged(SDL_WindowEvent b);
void toggleFullscreen();
// Default Render Size (Upscaled for bigger monitors)
const int width = 1920;
const int height = 1080;
float XScale = 1.0f, YScale = 1.0f;
// End render properties
const int width = 1600; // TODO: Fullscreen
const int height = 900;
Uint8 * keystate; // TODO: export all this into scenery and enemy waves
int numKeys;
const Uint8 * keystate; // TODO: export all this into scenery and enemy waves
SDL_Window * window;
SDL_Renderer * renderer;
SDL_Event event;
bool running = true, fullscreen = false;
Ball ball;
GameState gameState = MainMenu;
Scenery scenery;
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();
while (running) { // Gameloop
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
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);
break;
case SDL_WINDOWEVENT:
windowChanged(event.window);
break;
}
HandleSDLEvents();
DrawBackground(renderer);
switch (gameState) {
case Game:
BREAKOUT_Update(&scenery, keystate);
BREAKOUT_Draw(&scenery, renderer);
break;
case MainMenu:
// Startmenu_Update(keystate);
Startmenu_Draw(renderer);
break;
case Highscores:
HIGHSCORES_Draw(renderer);
break;
case Settings:
Settings_Draw(renderer);
break;
default:
printf("Unknow state was updated: %d\n", gameState);
break;
}
GAMELOOP();
DrawFrame();
SDL_RenderPresent(renderer);
}
QUIT();
return 0;
} /* main */
void GAMELOOP() {
keystate = SDL_GetKeyboardState(NULL);
BREAKOUT_Update(keystate);
} /* GAMELOOP */
void GAME_Escape(){
running = false;
printf("GAME_Escape was called!\n");
}
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
if (b.button == SDL_BUTTON_LEFT) {
@ -97,25 +139,29 @@ void windowChanged(SDL_WindowEvent b){ // Debug prop
switch (b.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
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;
}
}
void DrawFrame(){
void DrawBackground(SDL_Renderer * renderer){
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
BREAKOUT_Draw(renderer);
SDL_RenderPresent(renderer);
}
} /* DrawFrame */
void INITIALIZE() {
printf("Initializing started...\n");
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");
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");
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);
SDL_SetWindowResizable(window, true);
@ -123,12 +169,19 @@ void INITIALIZE() {
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
printf("Renderer was created!\n");
BREAKOUT_INITIALIZE(renderer, width, height);
scenery = BREAKOUT_CreateDefault();
Load_Textures(renderer);
HIGHSCORES_Initialize();
Settings_Initialize(renderer);
printf("Initializing finished!\n");
} /* INITIALIZE */
void QUIT(){
printf("De-initializing started...\n");
Settings_Deinitialize();
HIGHSCORES_Deinitialize();
BREAKOUT_DestroyObject(&scenery);
BREAKOUT_DEINITIALIZE();
free(keystate);
TTF_Quit();
IMG_Quit();
printf("Quitting SDL_IMG finished!\n");
@ -140,3 +193,28 @@ void QUIT(){
printf("Quitting SDL finished!\n");
printf("De-initializing finished!\n");
} /* 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