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){
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)) {
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)
if ((obj->Location).y > BREAKOUT_BoxHeight) // Collide with box boundaries
(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;
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");

60
main.c
View File

@ -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_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;