Menu screen
This commit is contained in:
parent
e7d5d2be45
commit
8dd9f2e02d
73
breakout.c
73
breakout.c
@ -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);
|
||||||
(obj->Momentum).y = -(obj->Momentum).y;
|
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;
|
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");
|
||||||
|
62
main.c
62
main.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user