From 8dd9f2e02da230f8667c5150dc81af3867bcf4a6 Mon Sep 17 00:00:00 2001 From: Michael Chen Date: Mon, 15 Jan 2018 13:54:17 +0100 Subject: [PATCH] Menu screen --- breakout.c | 73 ++++++++++++++++++++++++++++++++++++------------------ main.c | 62 +++++++++++++++++++++++++++------------------- 2 files changed, 85 insertions(+), 50 deletions(-) diff --git a/breakout.c b/breakout.c index 948a0af..97b832e 100644 --- a/breakout.c +++ b/breakout.c @@ -136,26 +136,46 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ 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; - } + 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 = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) }; + Vector corner = (Vector) {0, 0 }; // Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt! - // BUG: Ball glitches through blocks after being pushed by another collision - if ((ballCenter.x) < (rect->x) || (ballCenter.x) > (rect->x) + (rect->w)) { - (obj->Momentum).x = -(obj->Momentum).x; - } - if ((ballCenter.y) < (rect->y) || (ballCenter.y) > (rect->y) + (rect->h)) { - (obj->Momentum).y = -(obj->Momentum).y; + 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; + if (!(yMid || xMid)) { // Ball collides with corner + perpendicular = vectorRotation(vectorSub(center, corner)); + angle = fabs(perpendicular - oldMomentum); + if (oldMomentum < perpendicular) + (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum + (2 * angle)), BALL_Speed); + else + (obj->Momentum) = getScaledDirectionalUnitVector((oldMomentum - (2 * angle)), BALL_Speed); + } else { // Ball collides with Edge + if (yMid) + (obj->Momentum).y = -(obj->Momentum).y; + else + (obj->Momentum).x = -(obj->Momentum).x; } return true; } /* BALL_CollideWithRect */ @@ -217,23 +237,26 @@ void BALL_Update(Ball * obj, Paddle * paddle){ 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) = vectorSub((obj->Location), oldMomentum); // Maybe remove this - (obj->Location) = vectorAdd((obj->Location), (obj->Momentum)); + (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 + 300, .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; RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); } /* BALL_Update */ + void BALL_DestroyObject(Ball * obj){ } + void BALL_Deinitialize(){ if (BALL_IsInit) { printf("De-initializing Ball...\n"); @@ -309,6 +332,7 @@ void PADDLE_Update(Paddle * obj, Uint8 * keystate){ void PADDLE_DestroyObject(Paddle * obj){ } + void PADDLE_Deinitialize(){ if (PADDLE_IsInit) { printf("De-initializing Paddle...\n"); @@ -360,6 +384,7 @@ void BLOCK_Update(Block * obj){ } void BLOCK_DestroyObject(Block * obj){ } + void BLOCK_Deinitialize(){ if (BLOCK_IsInit) { printf("De-initializing Block...\n"); diff --git a/main.c b/main.c index df2a93e..16ac6bf 100644 --- a/main.c +++ b/main.c @@ -15,18 +15,22 @@ #define Nullptr(type) (type *)0 #endif // __nullptr__ -void DrawFrame(); +typedef enum gameStateEnum { MainMenu, Game, LevelSelect, Settings, Highscores } GameState; + void INITIALIZE(); void QUIT(); -void GAMELOOP(); +void DrawText(SDL_Renderer * renderer, const char * text); +void DrawBackground(SDL_Renderer * renderer); void printFontStyle(TTF_Font * ffont); void mousePress(SDL_MouseButtonEvent b); void keyPress(SDL_KeyboardEvent b); void windowChanged(SDL_WindowEvent b); void toggleFullscreen(); -const int width = 1600; // TODO: Fullscreen -const int height = 900; +const int width = 1920; +const int height = 1080; + +float XScale = 1.0f, YScale = 1.0f; Uint8 * keystate; // TODO: export all this into scenery and enemy waves SDL_Window * window; @@ -34,6 +38,7 @@ SDL_Renderer * renderer; SDL_Event event; bool running = true, fullscreen = false; TTF_Font * font = NULL; +GameState gameState = MainMenu; Ball ball; @@ -58,18 +63,26 @@ int main(int argc, char * args[]){ break; } } - GAMELOOP(); - DrawFrame(); + keystate = SDL_GetKeyboardState(NULL); + DrawBackground(renderer); + switch (gameState) { + case Game: + BREAKOUT_Update(keystate); + BREAKOUT_Draw(renderer); + break; + case MainMenu: + Startmenu_Draw(renderer); + break; + default: + printf("Unknow state was updated: %d\n", gameState); + } + DrawText(renderer, "FICK DICH"); + SDL_RenderPresent(renderer); } QUIT(); return 0; } /* main */ -void GAMELOOP() { - keystate = SDL_GetKeyboardState(NULL); - BREAKOUT_Update(keystate); -} /* GAMELOOP */ - void mousePress(SDL_MouseButtonEvent b){ // Debug prop if (b.button == SDL_BUTTON_LEFT) { printf("Left mouse pressed at %d, %d\n", b.x, b.y); @@ -100,38 +113,35 @@ 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); +} /* DrawFrame */ +void DrawText(SDL_Renderer * renderer, const char * text){ int w, h; - if (TTF_SizeText(font, "put your text here", &w, &h)) { + + if (TTF_SizeText(font, text, &w, &h)) { // perhaps print the current TTF_GetError(), the string can't be rendered... } else { printf("width=%d height=%d\n", w, h); } - SDL_Color White = { 255, 255, 255 }; // this is the color in rgb format, maxing out all would give you the color white, and it will be your text's color - - SDL_Surface * surfaceMessage = TTF_RenderText_Solid(font, "put your text here", White); // as TTF_RenderText_Solid could only be used on SDL_Surface then you have to create the surface first - + SDL_Color White = { 255, 255, 255 }; // this is the color in rgb format, maxing out all would give you the color white, and it will be your text's color + SDL_Surface * surfaceMessage = TTF_RenderText_Solid(font, text, White); // as TTF_RenderText_Solid could only be used on SDL_Surface then you have to create the surface first SDL_Texture * Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); // now you can convert it into a texture - SDL_Rect Message_rect = (SDL_Rect) {.x = 0, .y = 0, .w = w, .h = h }; // create a rect SDL_RenderCopy(renderer, Message, NULL, &Message_rect); // you put the renderer's name first, the Message, the crop size(you can ignore this if you don't want to dabble with cropping), and the rect which is the size and coordinate of your texture - SDL_FreeSurface(surfaceMessage); - Startmenu_Draw(renderer); - SDL_DestroyTexture(Message); - SDL_RenderPresent(renderer); - -} /* DrawFrame */ +} void printFontStyle(TTF_Font * ffont){ int style;