diff --git a/bin/assets/images/paused.png b/bin/assets/images/paused.png new file mode 100644 index 0000000..265edbf Binary files /dev/null and b/bin/assets/images/paused.png differ diff --git a/breakout.c b/breakout.c index 63044eb..4b800d2 100644 --- a/breakout.c +++ b/breakout.c @@ -20,9 +20,13 @@ extern int width, height; #define PADDLE_TexturePath "assets/images/paddle.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 50.0f -#define BALL_AccelerationTime 18000 +#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 @@ -39,6 +43,7 @@ SDL_Texture * BALL_Texture; SDL_Texture * GAME_CountdownTexture; SDL_Texture * PADDLE_Texture; SDL_Texture * BLOCK_Texture; +SDL_Texture * GAME_PausedTexture; SDL_Rect * BALL_SourceRects; SDL_Rect * GAME_CountdownSourceRects; SDL_Rect * PADDLE_SourceRects; @@ -57,7 +62,9 @@ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer){ PADDLE_Initialize(renderer); BLOCK_Initialize(renderer); GAME_CountdownTexture = IMG_LoadTexture(renderer, BRAEKOUT_CountdownTexturePath); - if (!GAME_CountdownTexture) printf("Coutndown texture failed to load!\n"); + if (!GAME_CountdownTexture) printf("Countdown texture failed to load!\n"); + GAME_PausedTexture = IMG_LoadTexture(renderer, BRAEKOUT_PausedTexturePath); + if (!GAME_PausedTexture) printf("Paused texture failed to load!\n"); GAME_CountdownTextureCount = 4; GAME_CountdownSourceRects = (SDL_Rect *)malloc(GAME_CountdownTextureCount * sizeof(SDL_Rect)); if (!GAME_CountdownSourceRects) printf("FATAL! Memory allocation failed!\n"); @@ -70,6 +77,18 @@ void BREAKOUT_INITIALIZE(SDL_Renderer * renderer){ } else printf("Game is already initialized!\n"); } /* 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 scenery; @@ -101,21 +120,31 @@ void BREAKOUT_IncreaseScoreBy(Scenery * scenery, int scoreInc){ (scenery->Score) += scoreInc; } -// int BREAKOUT_RefreshScore(Scenery * scenery){ -// (scenery->Score) = (int)round(((scenery->ball).Speed) * (double)(scenery->DestroyedBlocks)); -// printf("Score: %d\n", (scenery->Score)); -// return (scenery->Score); -// } +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){ - if (scenery->IsPaused) { - // Render "Paused" - return; - } - if ((scenery->StartCountdown)-- > 0) { - // SDL_WarpMouse(960, 540); Doesn't exist - return; - } + if (scenery->IsPaused) return; + if ((scenery->StartCountdown)-- > 0) return; (scenery->Frames)++; if (scenery->IsGameOver) { BALL_ResetPosition(&(scenery->ball)); @@ -129,7 +158,7 @@ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){ printf("Oh oh, only %d lives left!\n", scenery->Lives); 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); for (int i = 0; i < (scenery->BlockCount); i++) { BLOCK_Update((scenery->blocks) + i); @@ -142,15 +171,13 @@ void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){ } BALL_Draw(renderer, &(scenery->ball)); PADDLE_Draw(renderer, &(scenery->paddle)); - if ((scenery->StartCountdown) > 0) { // ! Render Z-Layer ! - SDL_Rect * rect = GAME_CountdownSourceRects + (((scenery->StartCountdown) - 1) / 60); - SDL_Rect target = *rect; - target.x = ((width - (rect->w)) / 2); - target.y = ((height - (rect->h)) / 2); - SDL_RenderCopy(renderer, GAME_CountdownTexture, rect, &target); - } SCORE_DrawHUD(renderer, scenery); BREAKOUT_DrawLivesHUD(renderer, scenery); + if (scenery->IsPaused) { + TEXTURE_RenderCentered(renderer, GAME_PausedTexture, 0.5f); + } else if ((scenery->StartCountdown) > 0) { // ! Render Z-Layer ! + TEXTURE_RenderCenteredSpriteSheet(renderer, GAME_CountdownTexture, (GAME_CountdownSourceRects + (((scenery->StartCountdown) - 1) / 60)), 1.0f); + } } void BREAKOUT_DrawLivesHUD(SDL_Renderer * renderer, Scenery * scenery){ @@ -171,6 +198,7 @@ void BREAKOUT_DEINITIALIZE(){ if (BREAKOUT_IsInit) { printf("De-initializing Game...\n"); SDL_DestroyTexture(GAME_CountdownTexture); + SDL_DestroyTexture(GAME_PausedTexture); free(PADDLE_MoveLeftKeys); free(PADDLE_MoveRightKeys); free(BALL_SourceRects); @@ -440,10 +468,8 @@ void PADDLE_Initialize(SDL_Renderer * renderer){ } /* PADDLE_Initialize */ Paddle PADDLE_CreateDefault(){ - int defaultpaddlewidth = 300; - return (Paddle) { - .TargetRect = (SDL_Rect) {.x = (width - defaultpaddlewidth) / 2, .y = height - 100, .w = defaultpaddlewidth, .h = 30 }, + .TargetRect = (SDL_Rect) {.x = (width - PADDLE_MaxSize) / 2, .y = height - 100, .w = PADDLE_MaxSize, .h = 30 }, .TextureIndex = 0, .Speed = 10, .SteeringAngle = 40.0f, @@ -499,7 +525,15 @@ void PADDLE_MoveSmooth(Paddle * obj){ (obj->TargetRect).x = paddleXMid - (int)roundf((float)(paddleXMid - mouseX) * PADDLE_SmoothFactor) - halfPaddle; } -void PADDLE_Update(Paddle * obj, const Uint8 * keystate){ +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) { diff --git a/breakout.h b/breakout.h index 16133a9..bd3eade 100644 --- a/breakout.h +++ b/breakout.h @@ -46,8 +46,12 @@ typedef struct sceneryStruct { // Prototypes void BREAKOUT_INITIALIZE(SDL_Renderer * renderer); +void BREAKOUT_TogglePause(Scenery * scenery); +void BREAKOUT_KeyPressed(Scenery * scenery, SDL_KeyboardEvent * b); Scenery BREAKOUT_CreateDefault(); -int BREAKOUT_RefreshScore(Scenery * scenery); +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_Draw(Scenery * scenery, SDL_Renderer * renderer); void BREAKOUT_DrawLivesHUD(SDL_Renderer * renderer, Scenery * scenery); @@ -79,7 +83,8 @@ 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_MoveSmooth(Paddle * obj); -void PADDLE_Update(Paddle * obj, const Uint8 * keystate); +void PADDLE_AdaptSpeedGradient(Paddle * obj, int FrameCount); +void PADDLE_Update(Paddle * obj, Scenery * scenery, const Uint8 * keystate); void PADDLE_DestroyObject(Paddle * obj); void PADDLE_Deinitialize(); void BLOCK_Initialize(SDL_Renderer * renderer); diff --git a/main.c b/main.c index 209b984..596545b 100644 --- a/main.c +++ b/main.c @@ -137,6 +137,14 @@ void keyPress(SDL_KeyboardEvent b){ // Debug prop printf("Key pressed: ID is %d\n", b.keysym.scancode); if (b.keysym.scancode == SDL_SCANCODE_F11 || b.keysym.scancode == SDL_SCANCODE_5) { toggleFullscreen(); + } else { + switch (gameState) { + case Game: + BREAKOUT_KeyPressed(&scenery, &b); + break; + default: + break; + } } }