Menu screen

This commit is contained in:
Michael Chen 2018-01-15 13:54:17 +01:00
parent e7d5d2be45
commit 8dd9f2e02d
2 changed files with 85 additions and 50 deletions

View File

@ -136,26 +136,46 @@ void BALL_Draw(SDL_Renderer * renderer, Ball * obj){
bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){ bool BALL_CollideWithRect(Ball * obj, SDL_Rect * rect){
SDL_Point ballCenter = BALL_GetCenter(obj); 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) + ((obj->TargetRect).w) < (rect->x)) { if (((obj->TargetRect).x) > (rect->x) + (rect->w)) return false;
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) > (rect->x) + (rect->w)) { // Already returned with false if square ball hitbox didnt collide with rect
return false; Vector center = (Vector) {.x = ((obj->TargetRect).x) + (obj->Size), .y = ((obj->TargetRect).y) + (obj->Size) };
} Vector corner = (Vector) {0, 0 };
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 im rechteck liegt! // Folgender Algorithmus ist gefickt, wenn der Ballmittelpunkt im rechteck liegt!
// BUG: Ball glitches through blocks after being pushed by another collision double perpendicular, oldMomentum, angle;
if ((ballCenter.x) < (rect->x) || (ballCenter.x) > (rect->x) + (rect->w)) { oldMomentum = fmod((double)(vectorRotation(obj->Momentum) + 180), 360.0f);
(obj->Momentum).x = -(obj->Momentum).x;
} bool left, right, top, bottom, yMid = false, xMid = false;
if ((ballCenter.y) < (rect->y) || (ballCenter.y) > (rect->y) + (rect->h)) { 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; (obj->Momentum).y = -(obj->Momentum).y;
else
(obj->Momentum).x = -(obj->Momentum).x;
} }
return true; return true;
} /* BALL_CollideWithRect */ } /* BALL_CollideWithRect */
@ -217,23 +237,26 @@ void BALL_Update(Ball * obj, Paddle * paddle){
for (size_t i = 0; i < BlockCount; i++) { for (size_t i = 0; i < BlockCount; i++) {
if (blocks[i].HP <= 0) continue; if (blocks[i].HP <= 0) continue;
oldMomentum = obj->Momentum; oldMomentum = obj->Momentum;
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);
(obj->Location) = vectorSub((obj->Location), oldMomentum); // Maybe remove this (obj->Location) = vectorAdd(oldLocation, (obj->Momentum));
(obj->Location) = vectorAdd((obj->Location), (obj->Momentum)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} }
} }
if ((obj->Location).y > BREAKOUT_BoxHeight) if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
(obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead (obj->Location) = (Vector) {.x = BREAKOUT_BoxWidth / 2 + 300, .y = BREAKOUT_BoxHeight / 2 }; // Dead
if ((obj->Location).y < 0.0f) else 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 > BREAKOUT_BoxWidth - (2 * (obj->Size)))
(obj->Momentum).x = -(obj->Momentum).x; (obj->Momentum).x = -(obj->Momentum).x;
RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location)); RECT_SetTargetPos(&(obj->TargetRect), &(obj->Location));
} /* BALL_Update */ } /* BALL_Update */
void BALL_DestroyObject(Ball * obj){ void BALL_DestroyObject(Ball * obj){
} }
void BALL_Deinitialize(){ void BALL_Deinitialize(){
if (BALL_IsInit) { if (BALL_IsInit) {
printf("De-initializing Ball...\n"); printf("De-initializing Ball...\n");
@ -309,6 +332,7 @@ void PADDLE_Update(Paddle * obj, Uint8 * keystate){
void PADDLE_DestroyObject(Paddle * obj){ void PADDLE_DestroyObject(Paddle * obj){
} }
void PADDLE_Deinitialize(){ void PADDLE_Deinitialize(){
if (PADDLE_IsInit) { if (PADDLE_IsInit) {
printf("De-initializing Paddle...\n"); printf("De-initializing Paddle...\n");
@ -360,6 +384,7 @@ void BLOCK_Update(Block * obj){
} }
void BLOCK_DestroyObject(Block * obj){ void BLOCK_DestroyObject(Block * obj){
} }
void BLOCK_Deinitialize(){ void BLOCK_Deinitialize(){
if (BLOCK_IsInit) { if (BLOCK_IsInit) {
printf("De-initializing Block...\n"); printf("De-initializing Block...\n");

60
main.c
View File

@ -15,18 +15,22 @@
#define Nullptr(type) (type *)0 #define Nullptr(type) (type *)0
#endif // __nullptr__ #endif // __nullptr__
void DrawFrame(); typedef enum gameStateEnum { MainMenu, Game, LevelSelect, Settings, Highscores } GameState;
void INITIALIZE(); void INITIALIZE();
void QUIT(); void QUIT();
void GAMELOOP(); void DrawText(SDL_Renderer * renderer, const char * text);
void DrawBackground(SDL_Renderer * renderer);
void printFontStyle(TTF_Font * ffont); void printFontStyle(TTF_Font * ffont);
void mousePress(SDL_MouseButtonEvent b); void mousePress(SDL_MouseButtonEvent b);
void keyPress(SDL_KeyboardEvent b); void keyPress(SDL_KeyboardEvent b);
void windowChanged(SDL_WindowEvent b); void windowChanged(SDL_WindowEvent b);
void toggleFullscreen(); void toggleFullscreen();
const int width = 1600; // TODO: Fullscreen const int width = 1920;
const int height = 900; const int height = 1080;
float XScale = 1.0f, YScale = 1.0f;
Uint8 * keystate; // TODO: export all this into scenery and enemy waves Uint8 * keystate; // TODO: export all this into scenery and enemy waves
SDL_Window * window; SDL_Window * window;
@ -34,6 +38,7 @@ SDL_Renderer * renderer;
SDL_Event event; SDL_Event event;
bool running = true, fullscreen = false; bool running = true, fullscreen = false;
TTF_Font * font = NULL; TTF_Font * font = NULL;
GameState gameState = MainMenu;
Ball ball; Ball ball;
@ -58,18 +63,26 @@ int main(int argc, char * args[]){
break; break;
} }
} }
GAMELOOP(); keystate = SDL_GetKeyboardState(NULL);
DrawFrame(); 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(); QUIT();
return 0; return 0;
} /* main */ } /* main */
void GAMELOOP() {
keystate = SDL_GetKeyboardState(NULL);
BREAKOUT_Update(keystate);
} /* GAMELOOP */
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);
@ -100,38 +113,35 @@ 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); // 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; break;
} }
} }
void DrawFrame(){ void DrawBackground(SDL_Renderer * renderer){
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
BREAKOUT_Draw(renderer); } /* DrawFrame */
void DrawText(SDL_Renderer * renderer, const char * text){
int w, h; 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... // perhaps print the current TTF_GetError(), the string can't be rendered...
} else { } else {
printf("width=%d height=%d\n", w, h); 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_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_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_Texture * Message = SDL_CreateTextureFromSurface(renderer, surfaceMessage); // now you can convert it into a texture 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_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_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); SDL_FreeSurface(surfaceMessage);
Startmenu_Draw(renderer);
SDL_DestroyTexture(Message); SDL_DestroyTexture(Message);
SDL_RenderPresent(renderer); }
} /* DrawFrame */
void printFontStyle(TTF_Font * ffont){ void printFontStyle(TTF_Font * ffont){
int style; int style;