From 629f3f94a8df541ef8d425c9e6c2cb2366025cde Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Fri, 26 Jan 2018 10:40:19 +0100 Subject: [PATCH] Push new Blocks with animation --- breakout.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++------- breakout.h | 4 ++-- 2 files changed, 49 insertions(+), 9 deletions(-) diff --git a/breakout.c b/breakout.c index a7b9f98..0115e7b 100644 --- a/breakout.c +++ b/breakout.c @@ -29,12 +29,15 @@ extern int width, height; #define PADDLE_AccelerationTime 18000 #define BREAKOUT_LiveHUDSize 35 #define BREAKOUT_LiveHUDMargin 8 +#define BREAKOUT_PushIntervale 1800 #ifndef __nullptr__ #define Nullptr(type) (type *)0 #endif // __nullptr__ float PADDLE_SmoothFactor = 0.1f; +float BLOCK_SmoothFactor = 0.05f; +float BREAKOUT_LifePenalty = 0.75f; int BLOCK_TextureCount = 24; int BALL_TextureCount = 9; int BREAKOUT_CountdownTextureCount = 4; @@ -93,24 +96,28 @@ Scenery BREAKOUT_CreateDefault(){ Scenery scenery; scenery.StartCountdown = 240; + scenery.TopLeftBlockColor = 0; scenery.IsGameOver = false; scenery.BlockCount = 135; scenery.ball = BALL_CreateDefault(); scenery.paddle = PADDLE_CreateDefault(); scenery.blocks = malloc(scenery.BlockCount * sizeof(Block)); scenery.Frames = 0; + scenery.YBlocks = 9; + scenery.XBlocks = 15; scenery.Score = 0; if (!(scenery.blocks)) printf("FATAL! Memory allocation failed!\n"); scenery.IsPaused = false; scenery.Lives = 3; scenery.DestroyedBlocks = 0; int index; - for (int y = 0; y < 9; y++) { - index = 15 * y; - for (int x = 0; x < 15; x++) { + for (int y = 0; y < scenery.YBlocks; y++) { + index = (scenery.XBlocks) * y; + for (int x = 0; x < scenery.XBlocks; x++) { scenery.blocks[x + index] = BLOCK_CreateDefault(); scenery.blocks[x + index].TargetRect = (SDL_Rect) {.x = ((128 * x) + 2), .y = ((64 * y) + 1), .w = 124, .h = 62 }; scenery.blocks[x + index].TextureIndex = y + x; + scenery.blocks[x + index].DestYValue = ((64 * y) + 1); } } return scenery; @@ -142,6 +149,28 @@ void TEXTURE_RenderCentered(SDL_Renderer * renderer, SDL_Texture * texture, floa SDL_RenderCopy(renderer, texture, NULL, &target); } +void BREAKOUT_PushNewRow(Scenery * scenery){ + printf("Pushing new line...\n"); + (scenery->TopLeftBlockColor)--; + // Rotate through textures + if ((scenery->TopLeftBlockColor) < 0) (scenery->TopLeftBlockColor) = (BLOCK_TextureCount - 1); + else if ((scenery->TopLeftBlockColor) >= 24) (scenery->TopLeftBlockColor) = 0; + int oldBlockCount = (scenery->BlockCount); + (scenery->BlockCount) += (scenery->XBlocks); + (scenery->YBlocks)++; + scenery->blocks = realloc((scenery->blocks), (scenery->BlockCount) * sizeof(Block)); + for (size_t i = 0; i < oldBlockCount; i++) { + (scenery->blocks)[i].DestYValue += 64; + } + for (size_t x = 0; x < (scenery->XBlocks); x++) { + (scenery->blocks)[x + oldBlockCount] = BLOCK_CreateDefault(); + (scenery->blocks)[x + oldBlockCount].TargetRect = (SDL_Rect) {.x = ((128 * x) + 2), .y = 1, .w = 124, .h = 62 }; + (scenery->blocks)[x + oldBlockCount].TextureIndex = (((scenery->TopLeftBlockColor) + x) % BLOCK_TextureCount); + (scenery->blocks)[x + oldBlockCount].DestYValue = 1; + } + printf("New line was pushed!\n"); +} /* BREAKOUT_PushNewRow */ + void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){ if (scenery->IsPaused) return; if ((scenery->StartCountdown)-- > 0) return; @@ -153,15 +182,21 @@ void BREAKOUT_Update(Scenery * scenery, const Uint8 * keystate){ scenery->IsGameOver = false; if (--(scenery->Lives) <= 0) GAME_ChangeState(GameOver); - else + else { + // Reduce score when there is a life left + scenery->Score = (int)roundf((float)(scenery->Score) * BREAKOUT_LifePenalty); printf("Oh oh, only %d lives left!\n", scenery->Lives); + } return; } + if ((scenery->Frames) % BREAKOUT_PushIntervale == 0) { + BREAKOUT_PushNewRow(scenery); + } 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); } + BALL_Update(&(scenery->ball), scenery); } /* BREAKOUT_Update */ void BREAKOUT_Draw(Scenery * scenery, SDL_Renderer * renderer){ @@ -610,7 +645,8 @@ Block BLOCK_CreateDefault() { return (Block) { .TargetRect = (SDL_Rect) {.x = 0, .y = 0, .w = 100, .h = 50 }, .TextureIndex = (rand() % BLOCK_TextureCount), - .HP = 1 + .HP = 1, + .DestYValue = 0 }; // Objekt für die Eigenschaften des Balls } @@ -633,8 +669,12 @@ void BLOCK_DealDamage(Block * obj, int dmg){ if (((obj->HP) -= dmg) <= 0) printf("Block was destroyed!\n"); } +void BLOCK_MoveSmooth(Block * obj){ + ((obj->TargetRect).y) -= (int)roundf((float)(((obj->TargetRect).y) - (obj->DestYValue)) * BLOCK_SmoothFactor); +} + void BLOCK_Update(Block * obj){ -// Do nothing currently + BLOCK_MoveSmooth(obj); } void BLOCK_DestroyObject(Block * obj){ } diff --git a/breakout.h b/breakout.h index bd3eade..b5dcd5c 100644 --- a/breakout.h +++ b/breakout.h @@ -32,14 +32,14 @@ typedef struct paddleStruct { typedef struct blockStruct { SDL_Rect TargetRect; - int TextureIndex, HP; + int TextureIndex, HP, DestYValue; } Block; // Objekt für die Eigenschaften des Paddles typedef struct sceneryStruct { Ball ball; Paddle paddle; Block * blocks; - int BlockCount, Lives, StartCountdown, Frames, Score, DestroyedBlocks; + int BlockCount, Lives, StartCountdown, Frames, Score, DestroyedBlocks, TopLeftBlockColor, XBlocks, YBlocks; bool IsPaused, IsGameOver; } Scenery; // Objekt für die Objekte und Eigenschaften einer Szenerie // End Structs