11 Commits

28 changed files with 552 additions and 217 deletions

1
.gitignore vendored
View File

@ -8,6 +8,7 @@ sdl2-config
*.o *.o
*.psd *.psd
*.exe *.exe
*.json
!bhi.exe !bhi.exe
.tags* .tags*
*.txt *.txt

Binary file not shown.

Before

Width:  |  Height:  |  Size: 155 KiB

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 35 KiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

View File

@ -9,24 +9,43 @@
#include "breakout.h" #include "breakout.h"
#include "vector.h" #include "vector.h"
#include "font.h" #include "gamestate.h"
#include "gameover.h"
#include "main.h"
extern float XScale, YScale; extern float XScale, YScale;
extern int width, height;
#define BALL_TexturePath "assets/images/ball.png" #define BALL_TexturePath "assets/images/ball.png"
#define PADDLE_TexturePath "assets/images/paddle.png" #define PADDLE_TexturePath "assets/images/paddle.png"
#define BLOCK_TexturePath "assets/images/spritesheet.png" #define BLOCK_TexturePath "assets/images/spritesheet.png"
#define BRAEKOUT_CountdownTexturePath "assets/images/text.png"
#define BRAEKOUT_PausedTexturePath "assets/images/paused.png"
#define BALL_MinSpeed 8.0f
#define BALL_MaxSpeed 25.0f
#define BALL_AccelerationTime 10000
#define PADDLE_MaxSize 300
#define PADDLE_MinSize 50
#define PADDLE_AccelerationTime 18000
#define BREAKOUT_LiveHUDSize 35
#define BREAKOUT_LiveHUDMargin 8
#ifndef __nullptr__ #ifndef __nullptr__
#define Nullptr(type) (type *)0 #define Nullptr(type) (type *)0
#endif // __nullptr__ #endif // __nullptr__
float PADDLE_SmoothFactor = 0.1f;
int BLOCK_TextureCount = 24; int BLOCK_TextureCount = 24;
int BREAKOUT_BoxWidth, BREAKOUT_BoxHeight; int BALL_TextureCount = 9;
int BREAKOUT_CountdownTextureCount = 4;
int PADDLE_TextureCount = 9;
SDL_Texture * BALL_Texture; SDL_Texture * BALL_Texture;
SDL_Texture * BREAKOUT_CountdownTexture;
SDL_Texture * PADDLE_Texture; SDL_Texture * PADDLE_Texture;
SDL_Texture * BLOCK_Texture; SDL_Texture * BLOCK_Texture;
SDL_Texture * BREAKOUT_PausedTexture;
SDL_Rect * BALL_SourceRects; SDL_Rect * BALL_SourceRects;
SDL_Rect * BREAKOUT_CountdownSourceRects;
SDL_Rect * PADDLE_SourceRects; SDL_Rect * PADDLE_SourceRects;
SDL_Rect * BLOCK_SourceRects; SDL_Rect * BLOCK_SourceRects;
Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys; Uint8 * PADDLE_MoveLeftKeys, * PADDLE_MoveRightKeys;
@ -35,20 +54,41 @@ bool BALL_IsInit = false;
bool PADDLE_IsInit = false; bool PADDLE_IsInit = false;
bool BLOCK_IsInit = false; bool BLOCK_IsInit = false;
void BREAKOUT_INITIALIZE(SDL_Renderer * renderer, int width, int height){ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer){
if (!BREAKOUT_IsInit) { if (!BREAKOUT_IsInit) {
printf("Initializing Game...\n"); printf("Initializing Game...\n");
srand(time(NULL)); srand(time(NULL));
BREAKOUT_BoxWidth = width;
BREAKOUT_BoxHeight = height;
BALL_Initialize(renderer); BALL_Initialize(renderer);
PADDLE_Initialize(renderer); PADDLE_Initialize(renderer);
BLOCK_Initialize(renderer); BLOCK_Initialize(renderer);
BREAKOUT_CountdownTexture = IMG_LoadTexture(renderer, BRAEKOUT_CountdownTexturePath);
if (!BREAKOUT_CountdownTexture) printf("Countdown texture failed to load!\n");
BREAKOUT_PausedTexture = IMG_LoadTexture(renderer, BRAEKOUT_PausedTexturePath);
if (!BREAKOUT_PausedTexture) printf("Paused texture failed to load!\n");
BREAKOUT_CountdownTextureCount = 4;
BREAKOUT_CountdownSourceRects = (SDL_Rect *)malloc(BREAKOUT_CountdownTextureCount * sizeof(SDL_Rect));
if (!BREAKOUT_CountdownSourceRects) printf("FATAL! Memory allocation failed!\n");
BREAKOUT_CountdownSourceRects[0] = (SDL_Rect) {.x = 1, .y = 668, .w = 1000, .h = 732 };
BREAKOUT_CountdownSourceRects[1] = (SDL_Rect) {.x = 1, .y = 1, .w = 242, .h = 665 };
BREAKOUT_CountdownSourceRects[2] = (SDL_Rect) {.x = 245, .y = 1, .w = 443, .h = 665 };
BREAKOUT_CountdownSourceRects[3] = (SDL_Rect) {.x = 690, .y = 1, .w = 443, .h = 665 };
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 */ } /* BREAKOUT_INITIALIZE */
void BREAKOUT_TogglePause(Scenery * scenery){
(scenery->IsPaused) = !(scenery->IsPaused);
printf("Game was %s!\n", ( (scenery->IsPaused) ? "paused" : "unpaused"));
}
void BREAKOUT_KeyPressed(Scenery * scenery, SDL_KeyboardEvent * b){
if ((b->keysym).scancode == SDL_SCANCODE_ESCAPE) {
printf("Escape was pressed ingame! Toggle Pause...\n");
BREAKOUT_TogglePause(scenery);
}
}
Scenery BREAKOUT_CreateDefault(){ Scenery BREAKOUT_CreateDefault(){
Scenery scenery; Scenery scenery;
@ -58,9 +98,12 @@ Scenery BREAKOUT_CreateDefault(){
scenery.ball = BALL_CreateDefault(); scenery.ball = BALL_CreateDefault();
scenery.paddle = PADDLE_CreateDefault(); scenery.paddle = PADDLE_CreateDefault();
scenery.blocks = malloc(scenery.BlockCount * sizeof(Block)); scenery.blocks = malloc(scenery.BlockCount * sizeof(Block));
scenery.Frames = 0;
scenery.Score = 0;
if (!(scenery.blocks)) printf("FATAL! Memory allocation failed!\n"); if (!(scenery.blocks)) printf("FATAL! Memory allocation failed!\n");
scenery.IsPaused = false; scenery.IsPaused = false;
scenery.Lives = 3; scenery.Lives = 3;
scenery.DestroyedBlocks = 0;
int index; int index;
for (int y = 0; y < 9; y++) { for (int y = 0; y < 9; y++) {
index = 15 * y; index = 15 * y;
@ -73,29 +116,49 @@ Scenery BREAKOUT_CreateDefault(){
return scenery; return scenery;
} /* BREAKOUT_CreateDefault */ } /* BREAKOUT_CreateDefault */
// This Function is obsolete! Do not use it! void BREAKOUT_IncreaseScoreBy(Scenery * scenery, int scoreInc){
void BREAKOUT_ChangeSize(int width, int height){ (scenery->Score) += scoreInc;
BREAKOUT_BoxWidth = width; }
BREAKOUT_BoxHeight = height;
void TEXTURE_RenderCenteredSpriteSheet(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Rect * srcRect, float Scale){
SDL_Rect target;
target.w = (int)roundf(((float)(srcRect->w)) * Scale);
target.h = (int)roundf(((float)(srcRect->h)) * Scale);
target.x = ((width - (target.w)) / 2);
target.y = ((height - (target.h)) / 2);
SDL_RenderCopy(renderer, texture, srcRect, &target);
}
void TEXTURE_RenderCentered(SDL_Renderer * renderer, SDL_Texture * texture, float Scale){
int w, h;
SDL_Rect target;
SDL_QueryTexture(texture, NULL, NULL, &w, &h);
target.w = (int)roundf(((float)w) * Scale);
target.h = (int)roundf(((float)h) * Scale);
target.x = ((width - (target.w)) / 2);
target.y = ((height - (target.h)) / 2);
SDL_RenderCopy(renderer, texture, NULL, &target);
} }
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){
if (scenery->IsPaused) return; // Currently paused if (scenery->IsPaused) return;
if ((scenery->StartCountdown)-- < 0) if ((scenery->StartCountdown)-- > 0) return;
(scenery->StartCountdown) = 0; (scenery->Frames)++;
else return; // Currently Counting down
if (scenery->IsGameOver) { if (scenery->IsGameOver) {
BALL_ResetPosition(&(scenery->ball)); BALL_ResetPosition(&(scenery->ball));
PADDLE_ResetPosition(&(scenery->paddle)); PADDLE_ResetPosition(&(scenery->paddle));
scenery->StartCountdown = 240; scenery->StartCountdown = 240;
scenery->IsGameOver = false; scenery->IsGameOver = false;
scenery->Frames = 0;
if (--(scenery->Lives) <= 0) if (--(scenery->Lives) <= 0)
printf("Game over, no lives left!\n"); GAME_ChangeState(GameOver);
else else
printf("Oh oh, only %d lives left!\n", scenery->Lives); printf("Oh oh, only %d lives left!\n", scenery->Lives);
return; return;
} }
PADDLE_Update(&(scenery->paddle), keystate); // Update paddle before ball because paddle is not static! PADDLE_Update(&(scenery->paddle), scenery, keystate); // Update paddle before ball because paddle is not static!
BALL_Update(&(scenery->ball), scenery); BALL_Update(&(scenery->ball), scenery);
for (int i = 0; i < (scenery->BlockCount); i++) { for (int i = 0; i < (scenery->BlockCount); i++) {
BLOCK_Update((scenery->blocks) + i); BLOCK_Update((scenery->blocks) + i);
@ -108,29 +171,40 @@ void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){
} }
BALL_Draw(renderer, &(scenery->ball)); BALL_Draw(renderer, &(scenery->ball));
PADDLE_Draw(renderer, &(scenery->paddle)); PADDLE_Draw(renderer, &(scenery->paddle));
if (scenery->IsPaused) SCORE_DrawHUD(renderer, scenery);
FONT_RenderTextCentered(renderer, "PAUSED", 3.0f, 1); BREAKOUT_DrawLivesHUD(renderer, scenery);
else if ((scenery->StartCountdown) > 0) { if (scenery->IsPaused) {
if ((scenery->StartCountdown) <= 60) { TEXTURE_RenderCentered(renderer, BREAKOUT_PausedTexture, 0.5f);
FONT_RenderTextCentered(renderer, "GO", 6.0f, 3); } else if ((scenery->StartCountdown) > 0) { // ! Render Z-Layer !
} else if ((scenery->StartCountdown) <= 120) { TEXTURE_RenderCenteredSpriteSheet(renderer, BREAKOUT_CountdownTexture, (BREAKOUT_CountdownSourceRects + (((scenery->StartCountdown) - 1) / 60)), 1.0f);
FONT_RenderTextCentered(renderer, "1", 6.0f, 1);
} else if ((scenery->StartCountdown) <= 180) {
FONT_RenderTextCentered(renderer, "2", 6.0f, 1);
} else {
FONT_RenderTextCentered(renderer, "3", 6.0f, 1);
} }
}
void BREAKOUT_DrawLivesHUD(SDL_Renderer * renderer, Scenery * scenery){
SDL_Rect tmpRect;
tmpRect.y = BREAKOUT_LiveHUDMargin;
tmpRect.w = BREAKOUT_LiveHUDSize;
tmpRect.h = BREAKOUT_LiveHUDSize;
tmpRect.x = width - BREAKOUT_LiveHUDMargin;
for (int i = 0; i < (scenery->Lives); i++) {
tmpRect.x -= (BREAKOUT_LiveHUDSize + BREAKOUT_LiveHUDMargin);
BALL_DrawTexture(renderer, &tmpRect, (scenery->ball).TextureIndex);
} }
} }
void BREAKOUT_DEINITIALIZE(){ void BREAKOUT_DEINITIALIZE(){
if (BREAKOUT_IsInit) { if (BREAKOUT_IsInit) {
printf("De-initializing Game...\n"); printf("De-initializing Game...\n");
SDL_DestroyTexture(BREAKOUT_CountdownTexture);
SDL_DestroyTexture(BREAKOUT_PausedTexture);
free(PADDLE_MoveLeftKeys); free(PADDLE_MoveLeftKeys);
free(PADDLE_MoveRightKeys); free(PADDLE_MoveRightKeys);
free(BALL_SourceRects); free(BALL_SourceRects);
free(PADDLE_SourceRects); free(PADDLE_SourceRects);
free(BLOCK_SourceRects); free(BLOCK_SourceRects);
free(BREAKOUT_CountdownSourceRects);
BALL_Deinitialize(); BALL_Deinitialize();
PADDLE_Deinitialize(); PADDLE_Deinitialize();
BLOCK_Deinitialize(); BLOCK_Deinitialize();
@ -153,33 +227,49 @@ void BALL_Initialize(SDL_Renderer * renderer){
printf("Initializing Ball...\n"); printf("Initializing Ball...\n");
BALL_Texture = IMG_LoadTexture(renderer, BALL_TexturePath); 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_TextureCount = 9;
BALL_SourceRects = (SDL_Rect *)malloc(BALL_TextureCount * 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 = 1029, .y = 1029, .w = 512, .h = 512 };
BALL_SourceRects[1] = (SDL_Rect) {.x = 1, .y = 1, .w = 512, .h = 512 };
BALL_SourceRects[2] = (SDL_Rect) {.x = 1, .y = 515, .w = 512, .h = 512 };
BALL_SourceRects[3] = (SDL_Rect) {.x = 1, .y = 1029, .w = 512, .h = 512 };
BALL_SourceRects[4] = (SDL_Rect) {.x = 515, .y = 1, .w = 512, .h = 512 };
BALL_SourceRects[5] = (SDL_Rect) {.x = 1029, .y = 1, .w = 512, .h = 512 };
BALL_SourceRects[6] = (SDL_Rect) {.x = 515, .y = 515, .w = 512, .h = 512 };
BALL_SourceRects[7] = (SDL_Rect) {.x = 515, .y = 1029, .w = 512, .h = 512 };
BALL_SourceRects[8] = (SDL_Rect) {.x = 1029, .y = 515, .w = 512, .h = 512 };
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");
} } /* BALL_Initialize */
Ball BALL_CreateDefault(){ Ball BALL_CreateDefault(){
double rotation = (double)(rand() % 360);
return (Ball) { return (Ball) {
.Location = (Vector) {.x = BREAKOUT_BoxWidth / 2 - 15, .y = BREAKOUT_BoxHeight - 130 }, .Location = (Vector) {.x = (width / 2) - 15, .y = height - 132 },
.Momentum = (Vector) {.x = 0.0f, .y = 15.0f }, .Momentum = (Vector) {.x = 0.0f, .y = BALL_MinSpeed },
.TargetRect = (SDL_Rect) {.x = BREAKOUT_BoxWidth / 2 - 15, .y = BREAKOUT_BoxHeight - 130, .w = 30, .h = 30 }, .TargetRect = (SDL_Rect) {.x = width / 2 - 15, .y = height - 130, .w = 30, .h = 30 },
.Size = 15.0f, .Size = 15.0f,
.Rotation = rotation, .Rotation = 0,
.RotationValue = 2, .RotationValue = 9,
.TextureIndex = 0, .TextureIndex = 0,
.Speed = 15.0f .Speed = 15.0f
}; // Objekt für die Eigenschaften des Balls }; // Objekt für die Eigenschaften des Balls
} }
void BALL_ResetPosition(Ball * obj){ void BALL_ResetPosition(Ball * obj){
(obj->Location).x = BREAKOUT_BoxWidth / 2 - 15; (obj->Location).x = width / 2 - 15;
(obj->Location).y = BREAKOUT_BoxHeight - 130; (obj->Location).y = height - 130;
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
(obj->Momentum) = VECTOR_GetScaledDirectionalUnitVector(0.0f, (obj->Speed));
}
void BALL_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index){
if (index > BALL_TextureCount || index < 0) {
printf("Ball with unkown texture index %d aus [0,...,%d]\n", index, (BALL_TextureCount - 1));
return;
}
SDL_RenderCopy(renderer, BALL_Texture, BALL_SourceRects + index, dstRect);
} }
void BALL_Draw(SDL_Renderer * renderer, Ball * obj){ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
@ -267,7 +357,7 @@ SDL_Point BALL_GetCenter(Ball * obj){
void BALL_CollideWithBorders(Ball * obj){ void BALL_CollideWithBorders(Ball * obj){
if ((obj->Location).y < 0.0f) 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 > width - (2 * (obj->Size)))
(obj->Momentum).x = -(obj->Momentum).x; (obj->Momentum).x = -(obj->Momentum).x;
} }
@ -276,7 +366,7 @@ void BALL_MoveAwayFromBoundaries(Ball * obj){
((obj->Location).y)++; ((obj->Location).y)++;
while (((obj->Location).x) < 0) while (((obj->Location).x) < 0)
((obj->Location).x)++; ((obj->Location).x)++;
while ((((obj->Location).x) + ((obj->Size) * 2)) > BREAKOUT_BoxWidth) while ((((obj->Location).x) + ((obj->Size) * 2)) > width)
((obj->Location).x)--; ((obj->Location).x)--;
} }
@ -299,7 +389,16 @@ bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle){
return false; return false;
} /* BALL_CollideWithPaddle */ } /* BALL_CollideWithPaddle */
void BALL_AdaptSpeedGradient(Ball * obj, int FrameCount){
if (FrameCount > BALL_AccelerationTime)
obj->Speed = BALL_MaxSpeed;
else
obj->Speed = BALL_MinSpeed + (((double)FrameCount / (double)BALL_AccelerationTime) * (BALL_MaxSpeed - BALL_MinSpeed));
}
void BALL_Update(Ball * obj, Scenery * scenery){ void BALL_Update(Ball * obj, Scenery * scenery){
BALL_AdaptSpeedGradient(obj, (scenery->Frames));
(obj->Momentum) = VECTOR_ChangeScaleTo((obj->Momentum), (obj->Speed));
Block * blocks = (scenery->blocks); Block * blocks = (scenery->blocks);
Paddle * paddle = &(scenery->paddle); Paddle * paddle = &(scenery->paddle);
int BlockCount = scenery->BlockCount; int BlockCount = scenery->BlockCount;
@ -317,14 +416,19 @@ void BALL_Update(Ball * obj, Scenery * scenery){
oldLocation = obj->Location; oldLocation = obj->Location;
if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) { if (BALL_CollideWithRect(obj, &(blocks[i].TargetRect))) {
BLOCK_DealDamage(blocks + i, 1); BLOCK_DealDamage(blocks + i, 1);
if (blocks[i].HP <= 0) {
(scenery->DestroyedBlocks)++;
BREAKOUT_IncreaseScoreBy(scenery, (int)round((((scenery->ball).Speed) * ((scenery->ball).Speed) / 5.0f)));
}
(obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum)); (obj->Location) = VECTOR_Add(oldLocation, (obj->Momentum));
BALL_MoveAwayFromBoundaries(obj); BALL_MoveAwayFromBoundaries(obj);
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} }
} }
if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries if ((obj->Location).y > height) { // Collide with box boundaries
scenery->IsGameOver = true; scenery->IsGameOver = true;
else BALL_CollideWithBorders(obj); printf("Ball called game_over!\n");
} else BALL_CollideWithBorders(obj);
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} /* BALL_Update */ } /* BALL_Update */
@ -364,27 +468,31 @@ void PADDLE_Initialize(SDL_Renderer * renderer){
} /* PADDLE_Initialize */ } /* PADDLE_Initialize */
Paddle PADDLE_CreateDefault(){ Paddle PADDLE_CreateDefault(){
int defaultpaddlewidth = 300;
return (Paddle) { return (Paddle) {
.TargetRect = (SDL_Rect) {.x = (BREAKOUT_BoxWidth - defaultpaddlewidth) / 2, .y = BREAKOUT_BoxHeight - 100, .w = defaultpaddlewidth, .h = 30 }, .TargetRect = (SDL_Rect) {.x = (width - PADDLE_MaxSize) / 2, .y = height - 100, .w = PADDLE_MaxSize, .h = 30 },
.TextureIndex = 0, .TextureIndex = 0,
.Speed = 10, .Speed = 10,
.SteeringAngle = 40.0f, .SteeringAngle = 40.0f,
.Mode = KeyboardControl .Mode = MouseControl
}; // Objekt für die Eigenschaften des Balls }; // Objekt für die Eigenschaften des Balls
} }
void PADDLE_ResetPosition(Paddle * obj){ void PADDLE_ResetPosition(Paddle * obj){
(obj->TargetRect).x = (BREAKOUT_BoxWidth - ((obj->TargetRect).w)) / 2; (obj->TargetRect).x = (width - ((obj->TargetRect).w)) / 2;
(obj->TargetRect).y = BREAKOUT_BoxHeight - 100; (obj->TargetRect).y = height - 100;
}
void PADDLE_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index){
if (index > PADDLE_TextureCount || index < 0) {
printf("Paddle with unkown texture index %d aus [0,...,%d]\n", index, (PADDLE_TextureCount - 1));
return;
}
SDL_RenderCopy(renderer, PADDLE_Texture, PADDLE_SourceRects + index, dstRect);
} }
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_RenderDrawRect(renderer, &(obj->TargetRect));
} }
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray){ bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray){
@ -408,37 +516,45 @@ void DOUBLE_Constrain(double * variable, double min, double max){
*variable = min; *variable = min;
} }
void PADDLE_Update(Paddle * obj, const Uint8 * keystate){ void PADDLE_MoveSmooth(Paddle * obj){
bool leftKeyPressed = false, rightKeyPressed = false; int mouseX, paddleXMid, halfPaddle = ((obj->TargetRect).w / 2);
int paddleXMid = (obj->TargetRect).x + ((obj->TargetRect).w / 2);
int mouseX; SDL_GetMouseState(&mouseX, NULL);
mouseX = (int)roundf((float)mouseX / XScale);
paddleXMid = halfPaddle + (obj->TargetRect.x); // Current State
(obj->TargetRect).x = paddleXMid - (int)roundf((float)(paddleXMid - mouseX) * PADDLE_SmoothFactor) - halfPaddle;
}
void PADDLE_AdaptSpeedGradient(Paddle * obj, int FrameCount){
if (FrameCount > PADDLE_AccelerationTime)
return;
(obj->TargetRect).w = PADDLE_MaxSize - (((double)FrameCount / (double)PADDLE_AccelerationTime) * (PADDLE_MaxSize - PADDLE_MinSize));
}
void PADDLE_Update(Paddle * obj, Scenery * scenery, const Uint8 * keystate){
PADDLE_AdaptSpeedGradient(obj, (scenery->Frames));
bool leftKeyPressed, rightKeyPressed;
switch (obj->Mode) { switch (obj->Mode) {
case MouseControl: case MouseControl:
SDL_GetMouseState(&mouseX, NULL); PADDLE_MoveSmooth(obj);
mouseX = (int)roundf((float)mouseX / XScale);
if (abs(mouseX - paddleXMid) > (obj->Speed)) {
if (mouseX > paddleXMid)
rightKeyPressed = true;
else
leftKeyPressed = true;
}
break; break;
case KeyboardControl: case KeyboardControl:
leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys); leftKeyPressed = KeyPressed(keystate, PADDLE_MoveLeftKeys);
rightKeyPressed = KeyPressed(keystate, PADDLE_MoveRightKeys); 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) -= (obj->Speed); ((obj->TargetRect).x) -= (obj->Speed);
} else if ((!leftKeyPressed) && rightKeyPressed) { } else if ((!leftKeyPressed) && rightKeyPressed) {
((obj->TargetRect).x) += (obj->Speed); ((obj->TargetRect).x) += (obj->Speed);
} }
INT_Constrain(&((obj->TargetRect).x), 0, (BREAKOUT_BoxWidth - ((obj->TargetRect).w))); break;
default:
printf("Unknown Paddle Control Mode: %d!\n", obj->Mode);
break;
} /* switch */
INT_Constrain(&((obj->TargetRect).x), 0, (width - ((obj->TargetRect).w)));
} /* PADDLE_Update */ } /* PADDLE_Update */
void PADDLE_DestroyObject(Paddle * obj){ void PADDLE_DestroyObject(Paddle * obj){
@ -497,6 +613,14 @@ Block BLOCK_CreateDefault() {
}; // Objekt für die Eigenschaften des Balls }; // Objekt für die Eigenschaften des Balls
} }
void BLOCK_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index){
if (index > BLOCK_TextureCount || index < 0) {
printf("Block with unkown texture index %d aus [0,...,%d]\n", index, (BLOCK_TextureCount - 1));
return;
}
SDL_RenderCopy(renderer, BLOCK_Texture, BLOCK_SourceRects + index, dstRect);
}
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj){ void BLOCK_Draw(SDL_Renderer * renderer, Block * obj){
if ((obj->HP) > 0) { if ((obj->HP) > 0) {
// printf("Block drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).y); // printf("Block drawn at (%d|%d)!\n", (obj->TargetRect).x, (obj->TargetRect).y);

View File

@ -39,22 +39,28 @@ typedef struct sceneryStruct {
Ball ball; Ball ball;
Paddle paddle; Paddle paddle;
Block * blocks; Block * blocks;
int BlockCount, Lives, StartCountdown; int BlockCount, Lives, StartCountdown, Frames, Score, DestroyedBlocks;
bool IsPaused, IsGameOver; bool IsPaused, IsGameOver;
} Scenery; // Objekt für die Objekte und Eigenschaften einer Szenerie } 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);
void BREAKOUT_TogglePause(Scenery * scenery);
void BREAKOUT_KeyPressed(Scenery * scenery, SDL_KeyboardEvent * b);
Scenery BREAKOUT_CreateDefault(); Scenery BREAKOUT_CreateDefault();
void BREAKOUT_ChangeSize(int width, int height); void BREAKOUT_IncreaseScoreBy(Scenery * scenery, int scoreInc);
void TEXTURE_RenderCenteredSpriteSheet(SDL_Renderer * renderer, SDL_Texture * texture, SDL_Rect * srcRect, float Scale);
void TEXTURE_RenderCentered(SDL_Renderer * renderer, SDL_Texture * texture, float Scale);
void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate); void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate);
void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer); void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer);
void BREAKOUT_DrawLivesHUD(SDL_Renderer * renderer, Scenery * scenery);
void BREAKOUT_DEINITIALIZE(); void BREAKOUT_DEINITIALIZE();
void BREAKOUT_DestroyObject(Scenery * scenery); 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_ResetPosition(Ball * obj); void BALL_ResetPosition(Ball * obj);
void BALL_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index);
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);
@ -64,21 +70,26 @@ SDL_Point BALL_GetCenter(Ball * obj);
void BALL_CollideWithBorders(Ball * obj); void BALL_CollideWithBorders(Ball * obj);
void BALL_MoveAwayFromBoundaries(Ball * obj); void BALL_MoveAwayFromBoundaries(Ball * obj);
bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle); bool BALL_CollideWithPaddle(Ball * obj, Paddle * paddle);
void BALL_AdaptSpeedGradient(Ball * obj, int FrameCount);
void BALL_Update(Ball * obj, Scenery * scenery); void BALL_Update(Ball * obj, Scenery * scenery);
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_ResetPosition(Paddle * obj); void PADDLE_ResetPosition(Paddle * obj);
void PADDLE_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index);
void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj); void PADDLE_Draw(SDL_Renderer * renderer, Paddle * obj);
bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray); bool KeyPressed(const Uint8 * keystate, Uint8 * keyArray);
void INT_Constrain(int * variable, int min, int max); void INT_Constrain(int * variable, int min, int max);
void DOUBLE_Constrain(double * variable, double min, double max); void DOUBLE_Constrain(double * variable, double min, double max);
void PADDLE_Update(Paddle * obj, const Uint8 * keystate); void PADDLE_MoveSmooth(Paddle * obj);
void PADDLE_AdaptSpeedGradient(Paddle * obj, int FrameCount);
void PADDLE_Update(Paddle * obj, Scenery * scenery, 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); void BLOCK_Initialize(SDL_Renderer * renderer);
Block BLOCK_CreateDefault() ; Block BLOCK_CreateDefault() ;
void BLOCK_DrawTexture(SDL_Renderer * renderer, SDL_Rect * dstRect, int index);
void BLOCK_Draw(SDL_Renderer * renderer, Block * obj); void BLOCK_Draw(SDL_Renderer * renderer, Block * obj);
void BLOCK_DealDamage(Block * obj, int dmg); void BLOCK_DealDamage(Block * obj, int dmg);
void BLOCK_Update(Block * obj); void BLOCK_Update(Block * obj);

78
font.c
View File

@ -1,51 +1,25 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <math.h> #include <string.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
#include "font.h" #include "font.h"
#define FONT_FontFile1 "assets/fonts/monofur.ttf"
#define FONT_FontFile2 "assets/fonts/ka1.ttf"
#define FONT_FontFile3 "assets/fonts/minecraft.ttf"
#define FONT_FontFile4 "assets/fonts/ae-bi.ttf"
extern int width, height;
int FONT_FontCount;
SDL_Color FONT_FontColor; SDL_Color FONT_FontColor;
TTF_Font ** FONT_FontFamily; TTF_Font * FONT_FontFamily = NULL;
bool FONT_IsInit = false;
void FONT_Initialize(){ void FONT_Initialize(){
if (!FONT_IsInit) {
printf("Initializing Font...\n"); printf("Initializing Font...\n");
FONT_FontColor = (SDL_Color) {255, 255, 255 }; FONT_FontColor = (SDL_Color) {255, 255, 255 };
FONT_FontCount = 4; FONT_FontFamily = TTF_OpenFont(FONT_FontFile, 48);
FONT_FontFamily = (TTF_Font **)malloc(FONT_FontCount * sizeof(TTF_Font *)); if (!FONT_FontFamily) printf("Font could not initialize! Error: %s\n", TTF_GetError());
FONT_FontFamily[0] = TTF_OpenFont(FONT_FontFile1, 48); else printf("Font was successfully initialized!\n");
if (!FONT_FontFamily) printf("Font 1 could not initialize! Error: %s\n", TTF_GetError()); FONT_PrintFontStyle(FONT_FontFamily);
else printf("Font 1 was successfully initialized!\n");
FONT_PrintFontStyle(FONT_FontFamily[0]);
FONT_FontFamily[1] = TTF_OpenFont(FONT_FontFile2, 48);
if (!FONT_FontFamily) printf("Font 2 could not initialize! Error: %s\n", TTF_GetError());
else printf("Font 2 was successfully initialized!\n");
FONT_PrintFontStyle(FONT_FontFamily[1]);
FONT_FontFamily[2] = TTF_OpenFont(FONT_FontFile3, 48);
if (!FONT_FontFamily) printf("Font 3 could not initialize! Error: %s\n", TTF_GetError());
else printf("Font 3 was successfully initialized!\n");
FONT_PrintFontStyle(FONT_FontFamily[2]);
FONT_FontFamily[3] = TTF_OpenFont(FONT_FontFile4, 48);
if (!FONT_FontFamily) printf("Font 4 could not initialize! Error: %s\n", TTF_GetError());
else printf("Font 4 was successfully initialized!\n");
FONT_PrintFontStyle(FONT_FontFamily[3]);
printf("Font initialized!\n"); printf("Font initialized!\n");
FONT_IsInit = true; }
} else printf("Font already initialized!\n");
} /* FONT_Initialize */
void FONT_PrintFontStyle(TTF_Font * ffont){ void FONT_PrintFontStyle(TTF_Font * ffont){
int style; int style;
@ -68,51 +42,31 @@ void FONT_PrintFontStyle(TTF_Font * ffont){
} }
void FONT_Deinitialize(){ void FONT_Deinitialize(){
if (FONT_IsInit) {
printf("De-initializing Font...\n"); printf("De-initializing Font...\n");
for (int i = 0; i < FONT_FontCount; i++) { TTF_CloseFont(FONT_FontFamily);
TTF_CloseFont(FONT_FontFamily[i]); FONT_FontFamily = NULL; // to be safe...
}
free(FONT_FontFamily);
printf("Font de-initialized!\n"); printf("Font de-initialized!\n");
FONT_IsInit = false;
} else printf("Font already de-initialized!\n");
} }
void FONT_RenderText(SDL_Renderer * renderer, char * text, SDL_Rect * dstRect, int index){ void FONT_RenderText(SDL_Renderer * renderer, char * text, SDL_Rect * dstRect){
SDL_Rect srcRect; SDL_Rect srcRect;
srcRect.x = 0; srcRect.x = 0;
srcRect.y = 0; srcRect.y = 0;
SDL_Texture * texture = FONT_GenerateTexture(renderer, text, &srcRect, index); SDL_Texture * texture = FONT_GenerateTexture(renderer, text, &srcRect);
SDL_RenderCopy(renderer, texture, &srcRect, dstRect); SDL_RenderCopy(renderer, texture, &srcRect, dstRect);
SDL_DestroyTexture(texture); SDL_DestroyTexture(texture);
} }
void FONT_RenderTextCentered(SDL_Renderer * renderer, char * text, float scale, int index){ SDL_Texture * FONT_GenerateTexture(SDL_Renderer * renderer, char * text, SDL_Rect * Message_rect){
SDL_Rect srcRect, dstRect; SDL_Surface * tmpSurface = FONT_GenerateSurface(text, Message_rect);
srcRect.x = 0;
srcRect.y = 0;
SDL_Texture * texture = FONT_GenerateTexture(renderer, text, &srcRect, index);
dstRect.w = (int)roundf((float)(srcRect.w) * scale);
dstRect.h = (int)roundf((float)(srcRect.h) * scale);
dstRect.x = (width - dstRect.w) / 2;
dstRect.y = (height - dstRect.h) / 2;
SDL_RenderCopy(renderer, texture, &srcRect, &dstRect);
SDL_DestroyTexture(texture);
}
SDL_Texture * FONT_GenerateTexture(SDL_Renderer * renderer, char * text, SDL_Rect * Message_rect, int index){
SDL_Surface * tmpSurface = FONT_GenerateSurface(text, Message_rect, index);
SDL_Texture * resultTexture = SDL_CreateTextureFromSurface(renderer, tmpSurface); SDL_Texture * resultTexture = SDL_CreateTextureFromSurface(renderer, tmpSurface);
SDL_FreeSurface(tmpSurface); SDL_FreeSurface(tmpSurface);
return resultTexture; return resultTexture;
} /* FONT_GenerateSurface */ } /* FONT_GenerateSurface */
SDL_Surface * FONT_GenerateSurface(char * text, SDL_Rect * Message_rect, int index){ SDL_Surface * FONT_GenerateSurface(char * text, SDL_Rect * Message_rect){
TTF_SizeText(FONT_FontFamily[index], text, &(Message_rect->w), &(Message_rect->h)); TTF_SizeText(FONT_FontFamily, text, &(Message_rect->w), &(Message_rect->h));
return TTF_RenderText_Solid(FONT_FontFamily[index], text, FONT_FontColor); return TTF_RenderText_Solid(FONT_FontFamily, text, FONT_FontColor);
} }

14
font.h
View File

@ -1,14 +1,20 @@
#ifndef __font_h__ #ifndef __font_h__
#define __font_h__ #define __font_h__
#define FONT_FontFile "assets/fonts/monofur.ttf"
// Externs
extern SDL_Color FONT_FontColor;
extern TTF_Font * FONT_FontFamily;
// End Externs
// Prototypes // Prototypes
void FONT_Initialize(); void FONT_Initialize();
void FONT_PrintFontStyle(TTF_Font * ffont); void FONT_PrintFontStyle(TTF_Font * ffont);
void FONT_Deinitialize(); void FONT_Deinitialize();
void FONT_RenderText(SDL_Renderer * renderer, char * text, SDL_Rect * dstRect, int index); void FONT_RenderText(SDL_Renderer * renderer, char * text, SDL_Rect * dstRect);
void FONT_RenderTextCentered(SDL_Renderer * renderer, char * text, float scale, int index); SDL_Texture * FONT_GenerateTexture(SDL_Renderer * renderer, char * text, SDL_Rect * Message_rect);
SDL_Texture * FONT_GenerateTexture(SDL_Renderer * renderer, char * text, SDL_Rect * Message_rect, int index); SDL_Surface * FONT_GenerateSurface(char * text, SDL_Rect * Message_rect);
SDL_Surface * FONT_GenerateSurface(char * text, SDL_Rect * Message_rect, int index);
// End Prototypes // End Prototypes
#endif // __font_h__ #endif // __font_h__

155
gameover.c Normal file
View File

@ -0,0 +1,155 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include "gameover.h"
#include "gamestate.h"
#include "main.h"
#define GAMEOVER_TexturePath "assets/images/gameover.png"
#define GAMEOVER_NumbersTexturePath "assets/images/numbers.png"
#define GAMEOVER_ScoreTexturePath "assets/images/yourscore.png"
#define GAMEOVER_HUDScale 16.0f
#define GAMEOVER_Scale 4.0f
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include "breakout.h"
#include "vector.h"
#include "background.h"
int GAMEOVER_HUDMargin = 5;
SDL_Texture * GAMEOVER_Texture;
SDL_Texture * GAMEOVER_Numbers;
SDL_Texture * GAMEOVER_ScoreTexture;
SDL_Rect * GAMEOVER_NumberRects;
SDL_Rect GAMEOVER_TargetRect;
SDL_Rect GAMEOVER_ScoreTargetRect;
SDL_Rect GAMEOVER_HUDScoreTargetRect;
int * GAMEOVER_Digits;
bool GAMEOVER_IsInit = false;
void GAMEOVER_Initialize(SDL_Renderer * renderer){
if (!GAMEOVER_IsInit) {
printf("Initializing Gameover...\n");
GAMEOVER_Texture = IMG_LoadTexture(renderer, GAMEOVER_TexturePath);
if (!GAMEOVER_Texture) printf("Gameover Texture couldn't be loaded!\n");
GAMEOVER_Numbers = IMG_LoadTexture(renderer, GAMEOVER_NumbersTexturePath);
if (!GAMEOVER_Numbers) printf("Gameover Numbers couldn't be loaded!\n");
GAMEOVER_ScoreTexture = IMG_LoadTexture(renderer, GAMEOVER_ScoreTexturePath);
if (!GAMEOVER_ScoreTexture) printf("Gameover Score Texture couldn't be loaded!\n");
int w, h;
SDL_QueryTexture(GAMEOVER_Texture, NULL, NULL, &w, &h);
w /= 2;
h /= 2;
GAMEOVER_TargetRect.x = ((1920 - w) / 2);
GAMEOVER_TargetRect.y = 50;
GAMEOVER_TargetRect.w = w;
GAMEOVER_TargetRect.h = h;
GAMEOVER_NumberRects = calloc(10, sizeof(SDL_Rect));
if (!GAMEOVER_NumberRects) printf("FATAL: Memory Allocation Failed!\n");
GAMEOVER_NumberRects[0] = (SDL_Rect) {.x = 446, .y = 668, .w = 442, .h = 665 };
GAMEOVER_NumberRects[1] = (SDL_Rect) {.x = 1299, .y = 1335, .w = 242, .h = 665 };
GAMEOVER_NumberRects[2] = (SDL_Rect) {.x = 1, .y = 1, .w = 443, .h = 665 };
GAMEOVER_NumberRects[3] = (SDL_Rect) {.x = 1, .y = 668, .w = 443, .h = 665 };
GAMEOVER_NumberRects[4] = (SDL_Rect) {.x = 1, .y = 1335, .w = 443, .h = 665 };
GAMEOVER_NumberRects[5] = (SDL_Rect) {.x = 446, .y = 1, .w = 443, .h = 665 };
GAMEOVER_NumberRects[6] = (SDL_Rect) {.x = 891, .y = 1, .w = 443, .h = 665 };
GAMEOVER_NumberRects[7] = (SDL_Rect) {.x = 890, .y = 1335, .w = 407, .h = 665 };
GAMEOVER_NumberRects[8] = (SDL_Rect) {.x = 446, .y = 1335, .w = 442, .h = 665 };
GAMEOVER_NumberRects[9] = (SDL_Rect) {.x = 890, .y = 668, .w = 442, .h = 665 };
GAMEOVER_ScoreTargetRect.y = 450;
GAMEOVER_ScoreTargetRect.h = 183;
GAMEOVER_ScoreTargetRect.w = 1000;
GAMEOVER_HUDScoreTargetRect = (SDL_Rect) {.x = GAMEOVER_HUDMargin, .y = GAMEOVER_HUDMargin, .w = 250, .h = 46 };
GAMEOVER_Digits = malloc(25 * sizeof(int));
printf("Gameover initialized!\n");
GAMEOVER_IsInit = true;
} else
printf("Gameover already initialized!\n");
} /* GAMEOVER_Initialize */
void GAMEOVER_Draw(SDL_Renderer * renderer, Scenery * scenery){
int i, count;
SDL_RenderCopy(renderer, GAMEOVER_Texture, NULL, &GAMEOVER_TargetRect);
GAMEOVER_GetDigits((scenery->Score), &count);
int totalWidth = GAMEOVER_ScoreTargetRect.w;
for (i = (count - 1); i >= 0; i--) {
totalWidth += (int)roundf((float)GAMEOVER_NumberRects[i].w / GAMEOVER_Scale);
}
GAMEOVER_ScoreTargetRect.x = ((1920 - totalWidth) / 2);
SDL_RenderCopy(renderer, GAMEOVER_ScoreTexture, NULL, &GAMEOVER_ScoreTargetRect);
int xOffset = GAMEOVER_ScoreTargetRect.x + GAMEOVER_ScoreTargetRect.w;
SDL_Rect target;
target.y = 450;
for (i = (count - 1); i >= 0; i--) {
target.x = xOffset;
target.h = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].h) / GAMEOVER_Scale);
target.w = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].w) / GAMEOVER_Scale);
SDL_RenderCopy(renderer, GAMEOVER_Numbers, (GAMEOVER_NumberRects + GAMEOVER_Digits[i]), &target);
xOffset += target.w;
}
} /* GAMEOVER_Draw */
void GAMEOVER_GetDigits(int input, int * digitCount){
int score = input;
int count = 0;
while (score != 0) {
GAMEOVER_Digits[(count++)] = (score % 10);
score /= 10;
}
if (count == 0) {
count = 1;
GAMEOVER_Digits[0] = 0;
}
*digitCount = count;
}
void SCORE_DrawHUD(SDL_Renderer * renderer, Scenery * scenery){
int i, count;
GAMEOVER_GetDigits((scenery->Score), &count);
int totalWidth = GAMEOVER_HUDScoreTargetRect.w;
for (i = (count - 1); i >= 0; i--) {
totalWidth += (int)roundf((float)GAMEOVER_NumberRects[i].w / GAMEOVER_HUDScale);
}
GAMEOVER_HUDScoreTargetRect.x = GAMEOVER_HUDMargin;
SDL_RenderCopy(renderer, GAMEOVER_ScoreTexture, NULL, &GAMEOVER_HUDScoreTargetRect);
int xOffset = GAMEOVER_HUDScoreTargetRect.x + GAMEOVER_HUDScoreTargetRect.w;
SDL_Rect target;
target.y = GAMEOVER_HUDMargin;
for (i = (count - 1); i >= 0; i--) {
target.x = xOffset;
target.h = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].h) / GAMEOVER_HUDScale);
target.w = (int)roundf((float)(GAMEOVER_NumberRects[GAMEOVER_Digits[i]].w) / GAMEOVER_HUDScale);
SDL_RenderCopy(renderer, GAMEOVER_Numbers, (GAMEOVER_NumberRects + GAMEOVER_Digits[i]), &target);
xOffset += target.w;
}
} /* SCORE_DrawHUD */
void GAMEOVER_Deinitialize(){
if (GAMEOVER_IsInit) {
printf("De-initializing Gameover...\n");
free(GAMEOVER_Digits);
SDL_DestroyTexture(GAMEOVER_Texture);
SDL_DestroyTexture(GAMEOVER_ScoreTexture);
SDL_DestroyTexture(GAMEOVER_Numbers);
printf("Gameover de-initialized!\n");
GAMEOVER_IsInit = false;
} else
printf("Gameover already de-initialized!\n");
}

25
gameover.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef __gameover_h__
#define __gameover_h__
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <math.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include "gameover.h"
#include "gamestate.h"
#include "main.h"
// Prototypes
void GAMEOVER_Initialize(SDL_Renderer * renderer);
void GAMEOVER_Draw(SDL_Renderer * renderer, Scenery * scenery);
void GAMEOVER_GetDigits(int input, int * digitCount);
void SCORE_DrawHUD(SDL_Renderer * renderer, Scenery * scenery);
void GAMEOVER_Deinitialize();
// End Prototypes
#endif // __gameover_h__

View File

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

View File

@ -7,25 +7,47 @@
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
#include "highscores.h" #include "highscores.h"
#include "font.h"
#define HIGHSCORES_FontFile "assets/fonts/monofur.ttf" #define HIGHSCORES_FontFile "assets/fonts/monofur.ttf"
int HIGHSCORES_EntriesGot = 0; int HIGHSCORES_EntriesGot = 0;
User * HIGHSCORES_UserList; User * HIGHSCORES_UserList;
SDL_Color HIGHSCORES_FontColor;
SDL_Texture * HIGHSCORES_TableTexture; SDL_Texture * HIGHSCORES_TableTexture;
SDL_Rect HIGHSCORES_TotalRect; SDL_Rect HIGHSCORES_TotalRect;
bool HIGHSCORES_IsInit = false; TTF_Font * HIGHSCORES_FontFamily = NULL;
SDL_Surface * tempSurface;
void HIGHSCORES_Initialize(){ void HIGHSCORES_Initialize(){
if (!HIGHSCORES_IsInit) {
printf("Initializing Highscores...\n"); printf("Initializing Highscores...\n");
FONT_Initialize(); HIGHSCORES_FontColor = (SDL_Color) {255, 255, 255 };
HIGHSCORES_UserList = malloc(10 * sizeof(User)); 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 }; HIGHSCORES_TotalRect = (SDL_Rect) {.x = 0, .y = 0, .w = 1920, .h = 1080 };
printf("Highscores initialized!\n"); printf("Highscores initialized!\n");
HIGHSCORES_IsInit = true; }
} else printf("Highscores already 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){ void HIGHSCORES_Draw(SDL_Renderer * renderer){
@ -33,35 +55,36 @@ void HIGHSCORES_Draw(SDL_Renderer * renderer){
} /* HIGHSCORES_Draw */ } /* HIGHSCORES_Draw */
void HIGHSCORES_Deinitialize(){ void HIGHSCORES_Deinitialize(){
if (HIGHSCORES_IsInit) {
printf("De-initializing Highscores...\n"); printf("De-initializing Highscores...\n");
FONT_Deinitialize(); TTF_CloseFont(HIGHSCORES_FontFamily);
HIGHSCORES_FontFamily = NULL; // to be safe...
SDL_DestroyTexture(HIGHSCORES_TableTexture); SDL_DestroyTexture(HIGHSCORES_TableTexture);
SDL_FreeSurface(tempSurface);
free(HIGHSCORES_UserList); free(HIGHSCORES_UserList);
printf("Highscores de-initialized!\n"); printf("Highscores de-initialized!\n");
HIGHSCORES_IsInit = false;
} else printf("Highscores already de-initialized!\n");
} }
void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer){ void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer){
char * buffer = calloc(100, sizeof(char)); char * buffer = calloc(100, sizeof(char));
int count = 0; int count = 0;
char format[25] = "| %-4d | %-52s | %-10s |"; char format[20] = "| %-54s | %-14s |";
SDL_Rect Message_rect; SDL_Rect Message_rect;
SDL_Surface * HIGHSCORES_TableSurface = SDL_CreateRGBSurface(0, 1920, 1080, 32, 0, 0, 0, 0); SDL_Surface * HIGHSCORES_TableSurface = SDL_CreateRGBSurface(0, 1920, 1080, 32, 0, 0, 0, 0);
if (!HIGHSCORES_TableSurface) { if (!HIGHSCORES_TableSurface) {
printf("Surface wasn't created!\n"); printf("Surface wasn't created!\n");
} }
sprintf(buffer, "| Rank | Username | Score |"); sprintf(buffer, format, "Username", "Score");
SDL_Surface * tempSurface = FONT_GenerateSurface(buffer, &Message_rect, 0); HIGHSCORES_DrawText(buffer, &Message_rect);
Message_rect.x = 50;
Message_rect.y = 70; 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_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect);
SDL_FreeSurface(tempSurface); SDL_FreeSurface(tempSurface);
while (count < HIGHSCORES_EntriesGot) { while (count < HIGHSCORES_EntriesGot) {
sprintf(buffer, format, (count + 1), HIGHSCORES_UserList[count].Username, HIGHSCORES_UserList[count].Score); sprintf(buffer, format, HIGHSCORES_UserList[count].Username, HIGHSCORES_UserList[count].Score);
tempSurface = FONT_GenerateSurface(buffer, &Message_rect, 0); HIGHSCORES_DrawText(buffer, &Message_rect);
Message_rect.y = ((Message_rect.h + 15) * (count + 1)) + 140; Message_rect.y = ((Message_rect.h + 15) * (count + 1)) + 140;
Message_rect.x = 50; Message_rect.x = 50;
SDL_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect); SDL_BlitSurface(tempSurface, NULL, HIGHSCORES_TableSurface, &Message_rect);
@ -75,6 +98,11 @@ void HIGHSCORES_GenerateTexture(SDL_Renderer * renderer){
SDL_FreeSurface(HIGHSCORES_TableSurface); SDL_FreeSurface(HIGHSCORES_TableSurface);
} /* HIGHSCORES_GenerateSurface */ } /* 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(){ void HIGHSCORES_ReloadList(){
printf("Call BHI interface:\n"); printf("Call BHI interface:\n");
system("bhi top output.txt"); system("bhi top output.txt");

49
main.c
View File

@ -12,9 +12,9 @@
#include "startmenu.h" #include "startmenu.h"
#include "gamestate.h" #include "gamestate.h"
#include "highscores.h" #include "highscores.h"
#include "gameover.h"
#include "settings.h" #include "settings.h"
#include "background.h" #include "background.h"
#include "font.h"
#include "main.h" #include "main.h"
@ -56,12 +56,14 @@ int main(int argc, char * args[]){
HIGHSCORES_Draw(renderer); HIGHSCORES_Draw(renderer);
break; break;
case Settings: case Settings:
Settings_Draw(renderer); Settings_Draw(renderer, &scenery);
case GameOver:
GAMEOVER_Draw(renderer, &scenery);
break; break;
default: default:
printf("Unknow state was updated: %d\n", gameState); printf("Unknow state was updated: %d\n", gameState);
break; break;
} } /* switch */
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
fps_frames++; fps_frames++;
if (fps_lasttime < SDL_GetTicks() - 1000) { if (fps_lasttime < SDL_GetTicks() - 1000) {
@ -106,6 +108,8 @@ void HandleSDLEvents(){
running = false; running = false;
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
// if (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE) running = false;
// else
keyPress(event.key); keyPress(event.key);
break; break;
case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONDOWN:
@ -120,26 +124,36 @@ void HandleSDLEvents(){
} /* HandleSDLEvents */ } /* 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) {
// printf("Left mouse pressed at %d, %d\n", b.x, b.y); printf("Left mouse pressed at %d, %d\n", b.x, b.y);
// } else if (b.button == SDL_BUTTON_RIGHT) { } else if (b.button == SDL_BUTTON_RIGHT) {
// printf("Right mouse pressed...\n"); printf("Right mouse pressed...\n");
// } else { } else {
// printf("Unknown mouse button pressed: %d\n", b.button); printf("Unknown mouse button pressed: %d\n", b.button);
// } }
} }
void keyPress(SDL_KeyboardEvent b){ // Debug prop void keyPress(SDL_KeyboardEvent b){ // Debug prop
// printf("Key pressed: ID is %d\n", b.keysym.scancode); printf("Key pressed: ID is %d\n", b.keysym.scancode);
if (b.keysym.scancode == SDL_SCANCODE_F11) if (b.keysym.scancode == SDL_SCANCODE_F11 || b.keysym.scancode == SDL_SCANCODE_5) {
toggleFullscreen(); toggleFullscreen();
} else {
switch (gameState) {
case Game:
BREAKOUT_KeyPressed(&scenery, &b);
break;
default:
break;
}
}
} }
void toggleFullscreen(){ void toggleFullscreen(){
if (fullscreen) if (fullscreen) {
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
else } else {
SDL_SetWindowFullscreen(window, 0); SDL_SetWindowFullscreen(window, 0);
}
fullscreen = !fullscreen; fullscreen = !fullscreen;
} }
@ -147,6 +161,7 @@ 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);
XScale = ((double)(event.window.data1) / (double)width); XScale = ((double)(event.window.data1) / (double)width);
YScale = ((double)(event.window.data2) / (double)height); YScale = ((double)(event.window.data2) / (double)height);
SDL_RenderSetScale(renderer, XScale, YScale); SDL_RenderSetScale(renderer, XScale, YScale);
@ -175,22 +190,22 @@ void INITIALIZE() {
printf("Window was created!\n"); printf("Window was created!\n");
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);
scenery = BREAKOUT_CreateDefault(); scenery = BREAKOUT_CreateDefault();
Load_Textures(renderer); Load_Textures(renderer);
FONT_Initialize();
HIGHSCORES_Initialize(); HIGHSCORES_Initialize();
BACKGROUND_Initialize(renderer, width, height); BACKGROUND_Initialize(renderer, width, height);
Settings_Initialize(renderer); Settings_Initialize(renderer);
GAMEOVER_Initialize(renderer);
printf("Initializing finished!\n"); printf("Initializing finished!\n");
} /* INITIALIZE */ } /* INITIALIZE */
void QUIT(){ void QUIT(){
printf("De-initializing started...\n"); printf("De-initializing started...\n");
GAMEOVER_Deinitialize();
BACKGROUND_Deinitialize(); BACKGROUND_Deinitialize();
Settings_Deinitialize(); Settings_Deinitialize();
HIGHSCORES_Deinitialize(); HIGHSCORES_Deinitialize();
FONT_Deinitialize();
BREAKOUT_DestroyObject(&scenery); BREAKOUT_DestroyObject(&scenery);
BREAKOUT_DEINITIALIZE(); BREAKOUT_DEINITIALIZE();
TTF_Quit(); TTF_Quit();

3
main.h
View File

@ -15,6 +15,9 @@
#include "startmenu.h" #include "startmenu.h"
#include "gamestate.h" #include "gamestate.h"
#include "highscores.h" #include "highscores.h"
#include "gameover.h"
#include "settings.h"
#include "background.h"
#ifndef __nullptr__ #ifndef __nullptr__
#define Nullptr(type) (type *)0 #define Nullptr(type) (type *)0

View File

@ -9,6 +9,7 @@
#define Slider_height 100 #define Slider_height 100
#define Scalar_width 20 #define Scalar_width 20
#define Bar_width 400 #define Bar_width 400
#define round(x) ((int) ((x) + .5))
SDL_Texture* Settings_Texture; SDL_Texture* Settings_Texture;
SDL_Texture* Settings_Ball_Texture; SDL_Texture* Settings_Ball_Texture;
@ -23,8 +24,8 @@ bool Settings_IsInit=false;
void Settings_Initialize (SDL_Renderer* renderer) { void Settings_Initialize (SDL_Renderer* renderer) {
Initialize_Slider(400,300,Scalar_width,Bar_width,Slider_height,1,2,&BV); Initialize_Slider(400,300,Scalar_width,Bar_width,Slider_height,1,2,&BV);
Initialize_Slider(400,500,Scalar_width,Bar_width,Slider_height,1,2,&BS); Initialize_Slider(400,500,Scalar_width,Bar_width,Slider_height,10.0f,20.0f,&BS);
Initialize_Slider(400,700,Scalar_width,Bar_width,Slider_height,1,2,&BT); Initialize_Slider(400,700,Scalar_width,Bar_width,Slider_height,0,1,&BT);
Settings_Texture = IMG_LoadTexture(renderer, "assets/images/settings_title.png"); Settings_Texture = IMG_LoadTexture(renderer, "assets/images/settings_title.png");
Settings_rect = (SDL_Rect){.x = 800, .y = 180, .w=313, .h=100}; Settings_rect = (SDL_Rect){.x = 800, .y = 180, .w=313, .h=100};
Settings_Ball_Texture = IMG_LoadTexture(renderer, "assets/images/ball.png"); Settings_Ball_Texture = IMG_LoadTexture(renderer, "assets/images/ball.png");
@ -32,14 +33,19 @@ void Settings_Initialize (SDL_Renderer* renderer) {
Settings_IsInit = true; Settings_IsInit = true;
} }
void Settings_Draw (SDL_Renderer* renderer) { void Settings_Draw (SDL_Renderer* renderer,Scenery* scenery) {
double x; double x;
SDL_RenderCopy(renderer, Settings_Texture, NULL, &Settings_rect); SDL_RenderCopy(renderer, Settings_Texture, NULL, &Settings_rect);
SDL_RenderCopy(renderer, Settings_Ball_Texture, NULL, &Settings_Ball_rect); SDL_RenderCopy(renderer, Settings_Ball_Texture, NULL, &Settings_Ball_rect);
Draw_Slider(renderer,&BV); Draw_Slider(renderer,&BV);
Draw_Slider(renderer,&BS); Draw_Slider(renderer,&BS);
Draw_Slider(renderer,&BT); Draw_Slider(renderer,&BT);
Draw_Ballstate(renderer,scenery);
mapping(&x,&BS);
scenery->ball.Speed=x;
mapping(&x,&BT); mapping(&x,&BT);
x=round(x);
scenery->ball.TextureIndex=x;
} }
void Settings_Deinitialize(){ void Settings_Deinitialize(){
@ -55,19 +61,19 @@ void Draw_Slider(SDL_Renderer* renderer,Slider* beta){
SDL_RenderDrawRect(renderer,&beta->Bar_rect); SDL_RenderDrawRect(renderer,&beta->Bar_rect);
int x,y; int x,y;
Uint32 Mousestate=SDL_GetMouseState(&x,&y); Uint32 Mousestate=SDL_GetMouseState(&x,&y);
if(y<=((beta->y)+(beta->h))&&y>=(beta->y)&&x<=(beta->bw+beta->x)&&x>=(beta->x)&&(Mousestate & SDL_BUTTON(SDL_BUTTON_LEFT))){ if(y<=((beta->Bar_rect.y)+(beta->Bar_rect.h))&&y>=(beta->Bar_rect.y)&&x<=(beta->Bar_rect.w+beta->Bar_rect.x)&&x>=(beta->Bar_rect.x)&&(Mousestate & SDL_BUTTON(SDL_BUTTON_LEFT))){
SDL_RenderFillRect(renderer,&beta->Scalar_rect); SDL_RenderFillRect(renderer,&beta->Scalar_rect);
SDL_RenderDrawRect(renderer,&beta->Scalar_rect); SDL_RenderDrawRect(renderer,&beta->Scalar_rect);
if(x>(beta->x+beta->bw-(beta->sw)/2)){ if(x>(beta->Bar_rect.x+beta->Bar_rect.w-(beta->Scalar_rect.w)/2)){
beta->Scalar_rect.x=(beta->x+beta->bw-(beta->sw)); beta->Scalar_rect.x=(beta->Bar_rect.x+beta->Bar_rect.w-(beta->Scalar_rect.w));
beta->Slider_value=(beta->x+beta->bw-(beta->sw)/2); beta->Slider_value=(beta->Bar_rect.x+beta->Bar_rect.w-(beta->Scalar_rect.w)/2);
} }
else if(x<beta->x+(beta->sw)/2){ else if(x<beta->Bar_rect.x+(beta->Scalar_rect.w)/2){
beta->Scalar_rect.x=beta->x; beta->Scalar_rect.x=beta->Bar_rect.x;
beta->Slider_value=beta->x+(beta->sw)/2; beta->Slider_value=beta->Bar_rect.x+(beta->Scalar_rect.w)/2;
} }
else{ else{
beta->Scalar_rect.x=x-(beta->sw/2); beta->Scalar_rect.x=x-(beta->Scalar_rect.w/2);
beta->Slider_value=x; beta->Slider_value=x;
} }
} }
@ -76,19 +82,18 @@ void Draw_Slider(SDL_Renderer* renderer,Slider* beta){
} }
} }
void Draw_Ballstate(SDL_Renderer* renderer,Scenery* scenery){
BALL_Draw(renderer, &(scenery->ball));
}
void mapping(double *x,Slider* beta){ void mapping(double *x,Slider* beta){
*x=((beta->max-beta->min)/(beta->bw-(beta->sw)))*(beta->Slider_value-beta->x-beta->sw/2)+beta->min; *x=((beta->max-beta->min)/(beta->Bar_rect.w-(beta->Scalar_rect.w)))*(beta->Slider_value-beta->Bar_rect.x-beta->Scalar_rect.w/2)+beta->min;
} }
void Initialize_Slider(int x,int y,int sw,int bw,int h,double min,double max,Slider* beta){ void Initialize_Slider(int x,int y,int sw,int bw,int h,double min,double max,Slider* beta){
beta->Scalar_rect = (SDL_Rect){.x=x,.y=y,.w=sw,.h=h}; beta->Scalar_rect = (SDL_Rect){.x=x,.y=y,.w=sw,.h=h};
beta->Bar_rect = (SDL_Rect){.x=x,.y=y,.w=bw,.h=h}; beta->Bar_rect = (SDL_Rect){.x=x,.y=y,.w=bw,.h=h};
beta->x=x;
beta->y=y;
beta->sw=sw;
beta->bw=bw;
beta->h=h;
beta->max=max; beta->max=max;
beta->min=min; beta->min=min;
beta->Slider_value=x+sw/2; beta->Slider_value=x+beta->Scalar_rect.w/2;
} }

View File

@ -7,24 +7,27 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
#include <stdbool.h> #include <stdbool.h>
#include "breakout.h"
typedef struct sliderstruct { typedef struct sliderstruct {
SDL_Rect Bar_rect; SDL_Rect Bar_rect;
SDL_Rect Scalar_rect; SDL_Rect Scalar_rect;
int x,y,bw,sw,h;
double Slider_value,min,max; double Slider_value,min,max;
} Slider; } Slider;
void Settings_Initialize (SDL_Renderer* renderer);
void Settings_Draw (SDL_Renderer* renderer); void Settings_Draw (SDL_Renderer* renderer,Scenery* scenery);
void Settings_Deinitialize();
void Draw_Slider(SDL_Renderer* renderer,Slider* beta); void Draw_Slider(SDL_Renderer* renderer,Slider* beta);
void mapping(double *x,Slider* beta); void Draw_Ballstate(SDL_Renderer* renderer,Scenery* scenery);
void Settings_Initialize (SDL_Renderer* renderer);
void Initialize_Slider(int x,int y,int sw,int bw,int h,double min,double max,Slider* beta); void Initialize_Slider(int x,int y,int sw,int bw,int h,double min,double max,Slider* beta);
void Settings_Deinitialize();
void mapping(double *x,Slider* beta);
#endif #endif

View File

@ -5,6 +5,7 @@
#include "gamestate.h" #include "gamestate.h"
#include "main.h" #include "main.h"
extern float XScale, YScale;
SDL_Texture * TITLE_Texture; SDL_Texture * TITLE_Texture;
SDL_Texture * PLAYBUTTON_Texture; SDL_Texture * PLAYBUTTON_Texture;
@ -23,7 +24,11 @@ SDL_Rect HIGHSCORESBUTTON_Rect;
SDL_Rect QUITBUTTON_Rect; SDL_Rect QUITBUTTON_Rect;
int clickInRect(SDL_MouseButtonEvent b, SDL_Rect * area_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)))); int clickx, clicky;
clickx = (int)roundf((float)b.x / XScale);
clicky = (int)roundf((float)b.y / YScale);
return ((clickx >= (area_rect->x)) && (clickx <= ((area_rect->x) + (area_rect->w))) && (clicky >= (area_rect->y)) && (clicky <= ((area_rect->y) + (area_rect->h))));
} }
void Load_Textures(SDL_Renderer * renderer) { void Load_Textures(SDL_Renderer * renderer) {