From f9a24a52c28ace557411a09850344965db21173d Mon Sep 17 00:00:00 2001 From: Jan Date: Sat, 4 Feb 2023 16:49:57 +0100 Subject: [PATCH] =?UTF-8?q?Screens=20hinzugef=C3=BCgt,=20Selectable=20/=20?= =?UTF-8?q?Button=20erstellen=20ist=20jetzt=20einfacher,=20Selectable=20un?= =?UTF-8?q?d=20Button=20Texturen=20sind=20jetzt=20auch=20im=20TextureAtlas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Input/inputHandler.c | 10 ++-- IsometricMap/isometricMap.c | 2 - Makefile | 5 +- README.md | 8 --- Screen/screen.c | 102 ++++++++++++++++++++++++++++++++++++ Screen/screen.h | 24 +++++++++ Sprite/sprite.c | 2 +- Textures/textureatlas.c | 20 +++++++ Textures/textureatlas.h | 2 + Ui/button.c | 17 +++--- Ui/button.h | 6 +-- Ui/debug.c | 2 +- Ui/onClickFunctions.c | 6 +-- Ui/selectable.c | 29 +++++----- Ui/selectable.h | 7 +-- Ui/uiContainer.c | 90 ++++++++++++++----------------- Ui/uiContainer.h | 2 +- definitions.h | 9 +++- game.c | 9 ++-- game.h | 6 +-- main.c | 97 +++++----------------------------- 21 files changed, 257 insertions(+), 198 deletions(-) create mode 100644 Screen/screen.c create mode 100644 Screen/screen.h diff --git a/Input/inputHandler.c b/Input/inputHandler.c index 4faf175..68222ff 100644 --- a/Input/inputHandler.c +++ b/Input/inputHandler.c @@ -19,7 +19,7 @@ void DrawRect(Vector2 rectStart, Vector2 mousePosition){ DrawRectangleLines(rectStart.x, rectStart.y, width, height, GREEN); } -// RETURNS UPPER LEFT CORNER OF THE RECTANGLE USING CURRENT MOUSE POS +// RETURNS UPPER LEFT CORNER OF THE RECTANGLE USING CURRENT MOUSE POS AND RECT START Vector2 GetRectangle(Vector2 rectStart, Vector2 mousePos){ float width = mousePos.x - rectStart.x; float height = mousePos.y - rectStart.y; @@ -42,7 +42,7 @@ Vector2 GetRectangle(Vector2 rectStart, Vector2 mousePos){ } static void SelectEntitiesInsideSelectionRect(Game *game){ - // UNSELECTING EVERY ENTITY FIRST, IF NOT HOLDING SHIFT + // Vorher werden alle Entities abgewählt, außer User hält SHIFT Entity *current = game->entities->head; if(!IsKeyDown(KEY_LEFT_SHIFT)){ while (current != 0){ @@ -58,7 +58,7 @@ static void SelectEntitiesInsideSelectionRect(Game *game){ current = game->entities->head; float deltaX; float deltaY; - // THEN SELECTING ENTITIES + // Jetzt neu anwählen while (current != 0){ Vector2 currPos = {current->sprite->x + current->sprite->texture->width, current->sprite->y + current->sprite->texture->height/2}; IsometricMapUnproject(game->map, game->camera, currPos.x, currPos.y, &currPos); @@ -179,13 +179,13 @@ void keyboardInput(Game *game){ game->camera->zoom -= 0.2f; } } - // Temp code for testing HOLZHACKERLEUTE, weil ich net versteh wie die iButtons hmmpf. früher bescheid wisse! + // Temp code for testing HOLZHACKERLEUTE, weil ich net versteh wie die iButtons hmmpf. früher bescheid wisse! (Jan: "noob") if(IsKeyPressed(KEY_G)){ //Baum StaticObject *tree = StaticObjectInit(game, SO_PINETREE, game->inputHandler->cursorWorldPos.x, game->inputHandler->cursorWorldPos.y); StaticObjectListInsert(game->objects, tree); } if(IsKeyPressed(KEY_P)){ - game->screen = SCREEN_PAUSE; + game->currentScreen = SCREEN_PAUSE; } } diff --git a/IsometricMap/isometricMap.c b/IsometricMap/isometricMap.c index 6b90840..b7c6efc 100644 --- a/IsometricMap/isometricMap.c +++ b/IsometricMap/isometricMap.c @@ -7,7 +7,6 @@ #include "../Sprite/sprite.h" #include "../game.h" -// returns pointer to IsometricMap Instance IsometricMap * IsometricMapInit(){ IsometricMap* map = malloc(sizeof(IsometricMap)); @@ -42,7 +41,6 @@ IsometricMap * IsometricMapInit(){ tmp->y = j; Vector2 *offset = IsometricMapCalcOffsetForTileAt(i,j, halfTextureSize, quarterTextureSize); - // the higher the layer the higher it needs to be drawed tmp->offsetX = offset->x; tmp->offsetY = offset->y; free(offset); diff --git a/Makefile b/Makefile index 2964d2c..e9479bf 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc FLAGS = -lraylib -lGL -lm -lpthread -ldl -lrt -lX11 -g -OBJS = main.o sprite.o inputHandler.o isometricMap.o game.o textureatlas.o animation.o animationHandler.o button.o uiContainer.o debug.o building.o entity.o selectable.o task.o entityacts.o onClickFunctions.o staticobjects.o +OBJS = main.o sprite.o inputHandler.o isometricMap.o game.o textureatlas.o animation.o animationHandler.o button.o uiContainer.o debug.o building.o entity.o selectable.o task.o entityacts.o onClickFunctions.o staticobjects.o screen.o spiel: $(OBJS) $(CC) -o spiel $(OBJS) $(FLAGS) @@ -59,5 +59,8 @@ onClickFunctions.o: Ui/onClickFunctions.c staticobjects.o: MapObject/staticobjects.c $(CC) -c MapObject/staticobjects.c $(FLAGS) +screen.o: Screen/screen.c + $(CC) -c Screen/screen.c $(FLAGS) + clean: rm *.o spiel diff --git a/README.md b/README.md index ce4d3a4..5c347e7 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,7 @@ KI Gegner ist erstmal zu aufwändig, ein wenig Ackern muss man aber immer! ## TODO -Zu Function Pointern: -+ Wir können zwar eZ Function Pointer speichern in den Buttons, wir können die Funktionen aber nicht sinnvoll im Code erzeugen und im Speicher speichern -+ Wir können die einzelnen Funktionen maximal als static(?) Funktionen im Button speichern und den einzelnen Buttons pointer auf ihre OnClick Funktionen geben -+ Die Frage ist, ob das wirklich sinnvoller ist als es einfach im Switch Case zu haben... - Allgemein: -+ LinkedList erweitern + Das Map Rendering sollte den Zoom auch noch beachten, wenn man rauszoomt wird nicht die ganzen map gedrawed, sondern nur die mit den default values + Das Auswahl Rect beachtet den Zoom der Kamera auch noch nicht + Vielleicht kann man auch einbauen dass die Kamera zentral zoomt und nicht in die linke obere Ecke @@ -35,8 +29,6 @@ Allgemein: + Parser für Map-Dateien + MapEditor - - ## Anleitungen ### Button einfügen: diff --git a/Screen/screen.c b/Screen/screen.c new file mode 100644 index 0000000..e0e1139 --- /dev/null +++ b/Screen/screen.c @@ -0,0 +1,102 @@ +#include "screen.h" +#include +#include +#include "../definitions.h" +#include "raylib.h" +#include "../Sprite/sprite.h" +#include "../Input/inputHandler.h" +#include "../Entity/entity.h" +#include "../IsometricMap/isometricMap.h" +#include "../game.h" +#include "../Ui/uiContainer.h" + +void ScreenRenderEmptyScreen(Game *game){ + printf("\n\n\n\n\n\n Wir haben ein problematisches Problem! Die Screen-ID [%d] ist nicht definiert. Hmmpf... früher bescheid wisse!\n\n\n\n\n\n", game->currentScreen); +} + +void ScreenRenderExitScreen(Game *game){ + printf("EXIT \n"); +} + +void ScreenRenderGameScreen(Game *game){ + game->screens[game->currentScreen]->frameCounter += GetFrameTime(); + if(game->screens[game->currentScreen]->frameCounter >= ACT_TIME){ + EntityListActAllEntities(game); + game->screens[game->currentScreen]->frameCounter = 0; + } + // Drawing IsometricMap + BeginMode2D(*(game->camera)); // Sorgt dafür, dass die Kameraposition beachtet wird + IsometricMapDraw(game); + + SpriteListDrawAllSprites(game->sprites, game->map, game->camera); + EndMode2D(); + + // User Input Handling + mouseInput(game); + keyboardInput(game); +} + +void ScreenRenderMainMenuScreen(Game *game){ + // hmmmmm +} + +void ScreenRenderPauseScreen(Game *game){ + int halfScreenHeight = GetScreenHeight()/2; + + // Still drawing isometric map, which is not updated atm + BeginMode2D(*(game->camera)); // Sorgt dafür, dass die Kameraposition beachtet wird + IsometricMapDraw(game); + SpriteListDrawAllSprites(game->sprites, game->map, game->camera); + EndMode2D(); + UiContainerDrawUiContainer(game->screens[game->currentScreen]->uiContainer); + // darkened background + "Paused" Text + DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), (Color){0, 0, 0, 150}); + int textWidthHalf = (MeasureText("Paused", 28)/2); + DrawText("Paused", GetScreenWidth()/2 - textWidthHalf, (halfScreenHeight/2) - 14, 28, WHITE); + + // Controls lol + DrawText("I: Zoom in", 5, halfScreenHeight, 16, WHITE); + DrawText("K: Zoom out", 5, halfScreenHeight + 16, 16, WHITE); + DrawText("P: Pause", 5, halfScreenHeight + 32, 16, WHITE); + DrawText("WASD: Move Camera", 5, halfScreenHeight + 48, 16, WHITE); + DrawText("ESC: Exit Game", 5, halfScreenHeight + 64, 16, WHITE); + + if(IsKeyPressed(KEY_P)){ + game->currentScreen = SCREEN_GAME; + } +} + + + +Screen * InitScreen(Game *game, int id){ + Screen *screen = malloc(sizeof(Screen)); + + screen->id = id; + screen->frameCounter = 0; + + screen->uiContainer = UiContainerInitUiContainerForScreenID(game, id); + + switch(id){ + case SCREEN_EXIT: + screen->render = &ScreenRenderExitScreen; + break; + case SCREEN_MAINMENU: + screen->render = &ScreenRenderMainMenuScreen; + break; + case SCREEN_OPTIONS: + screen->render = &ScreenRenderEmptyScreen; + break; + case SCREEN_GAME: + screen->render = &ScreenRenderGameScreen; + break; + case SCREEN_PAUSE: + screen->render = &ScreenRenderPauseScreen; + break; + default: + printf("WARNING: Creating Screen of ID %d (NOT SUPPORTED) \n", id); + screen->render = &ScreenRenderEmptyScreen; + break; + } + + return screen; +} \ No newline at end of file diff --git a/Screen/screen.h b/Screen/screen.h new file mode 100644 index 0000000..8a67d48 --- /dev/null +++ b/Screen/screen.h @@ -0,0 +1,24 @@ +#ifndef SCREEN_H_ +#define SCREEN_H_ +#include "raylib.h" +#include "../Ui/uiContainer.h" +#include "../game.h" + +typedef struct Screen { + int id; + UiContainer *uiContainer; + + float frameCounter; + + void (*render)(Game *game); // Funktioneen in screen.c +} Screen; + +Screen *InitScreen(Game *game, int id); + +void ScreenRenderEmptyScreen(Game *game); +void ScreenRenderGameScreen(Game *game); +void ScreenRenderMainMenuScreen(Game *game); +void ScreenRenderPauseScreen(Game *game); +void ScreenRenderOptionsScreen(Game *game); + +#endif diff --git a/Sprite/sprite.c b/Sprite/sprite.c index 51ad07c..10c2c3f 100644 --- a/Sprite/sprite.c +++ b/Sprite/sprite.c @@ -203,7 +203,7 @@ void SpriteListDrawAllSprites(SpriteList *list, IsometricMap *map, Camera2D *cam maxJ = (int)(botleft.y) + extraPixels; while(current != 0){ // drawing some extra corner pixels - // if extraPixels == 0 you can see flickering in the corners + // if extraPixels == 0 you might be able to see flickering in the corners // Only drawing the Sprites which are within Camera view if( current->x > itmp && current->y > jtmp && diff --git a/Textures/textureatlas.c b/Textures/textureatlas.c index 6150562..e5bae35 100644 --- a/Textures/textureatlas.c +++ b/Textures/textureatlas.c @@ -42,6 +42,14 @@ void TextureAtlasLoadTextures(Texture2D **textures){ textures[TE_LUMBERJACK] = malloc(TE_ENTITY_LENGTH * sizeof(Texture2D)); LoadEntityTextures(textures[TE_LUMBERJACK], "lumberjack"); break; + case TE_SELECTABLE_BACKGROUND: + textures[TE_SELECTABLE_BACKGROUND] = malloc(TE_SELECTABLE_BACKGROUND_LENGTH * sizeof(Texture2D)); + LoadSelectableBackgroundTextures(textures[TE_SELECTABLE_BACKGROUND]); + break; + case TE_BUTTON: + textures[TE_BUTTON] = malloc(TE_BUTTON_LENGTH * sizeof(Texture2D)); + LoadButtonTextures(textures[TE_BUTTON]); + break; default: printf("WARNING: TEXTUREATLAS TRIED LOADING NON DEFINED TEXTUREID!!\n"); } @@ -149,6 +157,18 @@ void LoadMapObjectTextures(Texture2D *atlasrow, char *directoryPrefix){ atlasrow[0] = LoadTexture(filename); } +void LoadSelectableBackgroundTextures(Texture2D *atlasrow){ + atlasrow[0] = LoadTexture("assets/selectable_background.png"); + atlasrow[1] = LoadTexture("assets/selectable_background_hovered.png"); + atlasrow[2] = LoadTexture("assets/selectable_background_selected.png"); +} +void LoadButtonTextures(Texture2D *atlasrow){ + atlasrow[0] = LoadTexture("assets/button.png"); + atlasrow[1] = LoadTexture("assets/button_hovered.png"); + atlasrow[2] = LoadTexture("assets/button_pressed.png"); +} + + void LoadCursorTextures(Texture2D *cursorTextures){ cursorTextures[0] = LoadTexture("assets/cursor.gif"); diff --git a/Textures/textureatlas.h b/Textures/textureatlas.h index 90c8960..44cb916 100644 --- a/Textures/textureatlas.h +++ b/Textures/textureatlas.h @@ -21,6 +21,8 @@ void TextureAtlasLoadTextures(Texture2D **textures); void LoadCursorTextures(Texture2D *cursorTextures); void LoadEntityTextures(Texture2D *atlasrow, char *directoryPrefix); void LoadMapObjectTextures(Texture2D *atlasrow, char *directoryPrefix); +void LoadSelectableBackgroundTextures(Texture2D *atlasrow); +void LoadButtonTextures(Texture2D *atlasrow); void LoadWorkerAnimations(Animation **workerAnimations, Texture2D *workerTextures); void TextureAtlasLoadAnimations(Animation ****animations, Texture2D **textures); diff --git a/Ui/button.c b/Ui/button.c index 4319924..6c5e48d 100644 --- a/Ui/button.c +++ b/Ui/button.c @@ -6,16 +6,13 @@ #include "string.h" #include "onClickFunctions.h" -Button * ButtonInitButton(Texture2D textures[4], Vector2 *position, char *text, int textLEN, int fontSize, int id){ +Button * ButtonInitButton(Texture2D **textures, Vector2 *position, char *text, int textLEN, int fontSize, int id){ Button *button = malloc(sizeof(Button)); - button->textures[0] = textures[0]; - button->textures[1] = textures[1]; - button->textures[2] = textures[2]; - button->textures[3] = textures[3]; + button->textures = textures; button->position = (Vector2){position->x, position->y}; - button->centerPosition = (Vector2){position->x + textures[0].width/2, position->y + textures[0].height/2}; + button->centerPosition = (Vector2){position->x + (*textures)[0].width/2, position->y + (*textures)[0].height/2}; strncpy(button->text, text, textLEN); button->state = BUTTON_STATE_DEFAULT; @@ -49,7 +46,9 @@ void ButtonExecuteButton(Button *button, Game *game){ void ButtonDrawButton(Button * button){ // erst Button Texture, dann Text zentriert drauf - DrawTexture(button->textures[button->state], button->position.x, button->position.y, WHITE); + int state = button->state; + if(state > 3){state = 3;} + DrawTexture((*button->textures)[state], button->position.x, button->position.y, WHITE); DrawText(button->text, button->centerPosition.x - MeasureText(button->text, button->fontSize)/2, button->centerPosition.y - button->fontSize/2, button->fontSize, BLACK); } @@ -60,9 +59,9 @@ int ButtonUpdateButtonState(Button * button, Game *game){ return button->state; } else if(GetMouseX() > button->position.x && - GetMouseX() < button->position.x + button->textures[button->state].width && + GetMouseX() < button->position.x + (*button->textures)[button->state].width && GetMouseY() > button->position.y && - GetMouseY() < button->position.y + button->textures[button->state].height + GetMouseY() < button->position.y + (*button->textures)[button->state].height ){ game->mouseOnUI = 1; if(IsMouseButtonDown(MOUSE_BUTTON_LEFT)){ diff --git a/Ui/button.h b/Ui/button.h index 8e2b289..fa10cf5 100644 --- a/Ui/button.h +++ b/Ui/button.h @@ -7,7 +7,7 @@ typedef struct Button Button; typedef struct Button{ - Texture2D textures[4]; // [0]: Normal [1]: Hovered [2]: Pressed [3]: Released + Texture2D **textures; // [0]: Normal [1]: Hovered [2]: Pressed Vector2 position; // Linke obere Ecke des Buttons Vector2 centerPosition; // Die Mitte des Buttons char text[20]; // Text, den der Button zentriert anzeigt, aktuell max. 19 Zeichen @@ -15,13 +15,13 @@ typedef struct Button{ int id; // Durch die ID wird dem Button eine Funktion zugeordnet int fontSize; // FontSize kann für jeden Button individuell festgelegt werden + void (*onClick)(Game *game, Button *button); } Button; // Textures: [0]: Normal [1]: Hovered [2]: Pressed [3]: Released -Button * ButtonInitButton(Texture2D textures[4], Vector2 *position, char *text, int textLEN, int fontSize, int id); +Button * ButtonInitButton(Texture2D **textures, Vector2 *position, char *text, int textLEN, int fontSize, int id); -// executes the logic of one button of certain id - huge switch? void ButtonExecuteButton(Button *button, Game * game); int ButtonUpdateButtonState(Button * button, Game *game); diff --git a/Ui/debug.c b/Ui/debug.c index 7b6cefc..c06b8e2 100644 --- a/Ui/debug.c +++ b/Ui/debug.c @@ -14,7 +14,7 @@ void DebugDraw(Game *game){ // Hier die Debug Information in den Strings Array einfügen // im Endeffekt einfach im Array an der Stelle lineamount++ die Elemente einfügen sprintf(strings[lineamount++], "FPS: %d", GetFPS()); - sprintf(strings[lineamount++], "Screen: %d", game->screen); + sprintf(strings[lineamount++], "Screen: %d", game->currentScreen); sprintf(strings[lineamount++], "MouseScreenX: %d", GetMouseX()); sprintf(strings[lineamount++], "MouseScreenY: %d", GetMouseY()); sprintf(strings[lineamount++], "MouseWorldX: %d", (int)game->inputHandler->cursorWorldPos.x); diff --git a/Ui/onClickFunctions.c b/Ui/onClickFunctions.c index 86498dc..cdbcde7 100644 --- a/Ui/onClickFunctions.c +++ b/Ui/onClickFunctions.c @@ -14,13 +14,13 @@ void OnClickButton(Game *game, Button *button){ return; } void OnClickContinueButton(Game *game, Button *button){ - game->screen = SCREEN_GAME; + game->currentScreen = SCREEN_GAME; } void OnClickExitButton(Game *game, Button *button){ - game->screen = SCREEN_EXIT; + game->currentScreen = SCREEN_EXIT; } void OnClickStartButton(Game *game, Button *button){ - game->screen = SCREEN_GAME; + game->currentScreen = SCREEN_GAME; } // RETURNS 1 IF COORDS INSIDE MAP diff --git a/Ui/selectable.c b/Ui/selectable.c index b2863f1..d037abb 100644 --- a/Ui/selectable.c +++ b/Ui/selectable.c @@ -9,18 +9,14 @@ #include "../Entity/entity.h" #include "onClickFunctions.h" -Selectable * SelectableInit(Texture2D textures[3], Texture2D backgroundTextures[3], int hasBackground, Vector2 *position, char *description, +Selectable * SelectableInit(Texture2D *texture, Texture2D **backgroundTextures, int hasBackground, Vector2 *position, char *description, int showDescripton, int descriptionLEN, int fontSize, int id, int groupID, int unselectAfterExecute){ Selectable *selectable = malloc(sizeof(Selectable)); - selectable->texture[0] = textures[0]; - selectable->texture[1] = textures[1]; - selectable->texture[2] = textures[2]; + selectable->texture = texture; selectable->hasBackground = hasBackground; if(selectable->hasBackground == 1){ - selectable->backgroundTexture[0] = backgroundTextures[0]; - selectable->backgroundTexture[1] = backgroundTextures[1]; - selectable->backgroundTexture[2] = backgroundTextures[2]; + selectable->backgroundTexture = backgroundTextures; } //else{ // selectable->backgroundTexture[0] = 0; @@ -33,7 +29,7 @@ Selectable * SelectableInit(Texture2D textures[3], Texture2D backgroundTextures[ selectable->showDescription = showDescripton; selectable->fontSize = fontSize; selectable->id = id; - selectable->state = 0; + selectable->state = SELECTABLE_STATE_DEFAULT; selectable->groupID = groupID; selectable->unselectAfterExecute = unselectAfterExecute; @@ -64,21 +60,24 @@ void SelectableExecuteSelectable(Selectable *selectable, Game * game){ int SelectableUpdateSelectableState(Selectable * selectable, Game *game){ int mouseOnElement = 0; if(GetMouseX() > selectable->position.x && - GetMouseX() < selectable->position.x + selectable->backgroundTexture[selectable->state].width && + GetMouseX() < selectable->position.x + (*selectable->backgroundTexture)[selectable->state].width && GetMouseY() > selectable->position.y && - GetMouseY() < selectable->position.y + selectable->backgroundTexture[selectable->state].height + GetMouseY() < selectable->position.y + (*selectable->backgroundTexture)[selectable->state].height ){ mouseOnElement = 1; game->mouseOnUI = 1; } if(selectable->state == SELECTABLE_STATE_SELECTED){ - if(IsMouseButtonDown(MOUSE_BUTTON_RIGHT)){ + if(IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)){ + return selectable->state = SELECTABLE_STATE_DEFAULT; + } + if(UNSELECT_SELECTABLE_ON_SELECT && mouseOnElement && IsMouseButtonPressed(MOUSE_BUTTON_LEFT)){ return selectable->state = SELECTABLE_STATE_DEFAULT; } return SELECTABLE_STATE_SELECTED; } if(mouseOnElement == 1){ - if(IsMouseButtonDown(MOUSE_BUTTON_LEFT)){ + if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)){ return selectable->state = SELECTABLE_STATE_SELECTED; } return selectable->state = SELECTABLE_STATE_HOVERED; @@ -96,12 +95,12 @@ int SelectableUnselectSelectable(Selectable * selectable){ void SelectableDrawSelectable(Selectable * selectable){ int targetWidth = 0; if(selectable->hasBackground == 1) { - targetWidth = selectable->backgroundTexture[selectable->state].width; - DrawTexture(selectable->backgroundTexture[selectable->state], selectable->position.x, selectable->position.y, WHITE); + targetWidth = selectable->backgroundTexture[selectable->state]->width; + DrawTexture((*(selectable->backgroundTexture))[selectable->state], selectable->position.x, selectable->position.y, WHITE); } //DrawTextureEx(selectable->texture[selectable->state], selectable->position, targetWidth / selectable->texture[selectable->state].width, 2, WHITE); - DrawTexture(selectable->texture[selectable->state], selectable->position.x, selectable->position.y, WHITE); + DrawTexture(*selectable->texture, selectable->position.x, selectable->position.y, WHITE); if(selectable->showDescription == 1){ DrawText(selectable->description, selectable->position.x, selectable->position.y, selectable->fontSize, WHITE); } diff --git a/Ui/selectable.h b/Ui/selectable.h index 393e7f8..b912891 100644 --- a/Ui/selectable.h +++ b/Ui/selectable.h @@ -8,8 +8,8 @@ typedef struct Selectable Selectable; typedef struct Selectable{ Vector2 position; // Linke obere Ecke Vector2 centerPosition; // Die Mitte des Selectables - Texture2D texture[3];// [0]: Normal | [1]: Hovered | [2]: Selected - Texture2D backgroundTexture[3]; // [0]: Normal | [1]: Hovered | [2]: Selected + Texture2D *texture;// Single Texture + Texture2D **backgroundTexture; // [0]: Normal | [1]: Hovered | [2]: Selected int hasBackground; // 0: hat keine Background Textur | 1: hat Background Textur char description[20]; //Text der unter dem selectable angezeigt werden kann int showDescription; //0: zeigt Description nicht | 1: zeigt Description @@ -27,8 +27,9 @@ typedef struct Selectable{ // Textures+backgroundTextures: [0]: Normal | [1]: Hovered | [2]: Selected // hasBackground: 0: hat keine Background Textur | 1: hat Background Textur // showDescription 0: zeigt Description nicht | 1: zeigt Description +// unselectAfterExecute 0: wird abgewählt | 1: bleibt ausgewählt // Max Description LEN 20 -Selectable * SelectableInit(Texture2D textures[3], Texture2D backgroundTextures[3], int hasBackground, Vector2 *position, char *description, int showDescripton, int descriptionLEN, int fontSize, int id, int groupID, int unselectAfterExecute); +Selectable * SelectableInit(Texture2D *texture, Texture2D **backgroundTextures, int hasBackground, Vector2 *position, char *description, int showDescripton, int descriptionLEN, int fontSize, int id, int groupID, int unselectAfterExecute); void SelectableExecuteSelectable(Selectable *selectable, Game * game); diff --git a/Ui/uiContainer.c b/Ui/uiContainer.c index 67260fc..5877a74 100644 --- a/Ui/uiContainer.c +++ b/Ui/uiContainer.c @@ -1,5 +1,6 @@ #include "uiContainer.h" #include "../game.h" +#include "../Textures/textureatlas.h" #include "button.h" #include "raylib.h" #include "stdlib.h" @@ -15,23 +16,20 @@ static UiContainer * UiContainerInitEmptyUiContainer(){ } // Only for use in UiContainer -static UiContainer * UiContainerInitPauseUiContainer(){ - UiContainer *uiContainer = malloc(sizeof(UiContainer)); - uiContainer->buttonCounter = 0; - uiContainer->selectableCounter = 0; - - Texture2D textures[4] = { LoadTexture("assets/button.png"), //DEFAULT - LoadTexture("assets/button_hovered.png"), //HOVERED - LoadTexture("assets/button_pressed.png"), //PRESSED - LoadTexture("assets/button_pressed.png")}; //RELEASED +static UiContainer * UiContainerInitPauseUiContainer(Game *game){ + UiContainer *uiContainer = UiContainerInitEmptyUiContainer(); - Vector2 position = (Vector2){GetScreenWidth()/2 - textures[0].width/2, GetScreenHeight()/2 - 50}; + // predefined stuff + Texture2D **textures = &(game->textures->textures[TE_BUTTON]); + Vector2 position = (Vector2){GetScreenWidth()/2 - (*textures)[0].width/2, GetScreenHeight()/2 - 50}; int buttonFontSize = 36; + // creating the ui elements Button *continuebutton = ButtonInitButton(textures, &position, "Continue", 9/*String len*/, buttonFontSize, BUTTON_ID_CONTINUE); position.y += 250; Button *exitButton = ButtonInitButton(textures, &position, "EXIT", 5/*String len*/, buttonFontSize, BUTTON_ID_EXIT); + // adding the ui elements UiContainerAddButton(uiContainer, continuebutton); UiContainerAddButton(uiContainer, exitButton); @@ -39,23 +37,20 @@ static UiContainer * UiContainerInitPauseUiContainer(){ } // Only for use in UiContainer -static UiContainer * UiContainerInitMainMenuUiContainer(){ - UiContainer *uiContainer = malloc(sizeof(UiContainer)); - uiContainer->buttonCounter = 0; - uiContainer->selectableCounter = 0; - - Texture2D textures[4] = { LoadTexture("assets/button.png"), //DEFAULT - LoadTexture("assets/button_hovered.png"), //HOVERED - LoadTexture("assets/button_pressed.png"), //PRESSED - LoadTexture("assets/button_pressed.png")}; //RELEASED +static UiContainer * UiContainerInitMainMenuUiContainer(Game *game){ + UiContainer *uiContainer = UiContainerInitEmptyUiContainer(); - Vector2 position = (Vector2){GetScreenWidth()/2 - textures[0].width/2, GetScreenHeight()/2 - 50}; + // predefined stuff + Texture2D **textures = &(game->textures->textures[TE_BUTTON]); + Vector2 position = (Vector2){GetScreenWidth()/2 -( *textures)[0].width/2, GetScreenHeight()/2 - 50}; int buttonFontSize = 36; + // creating the ui elements Button *continuebutton = ButtonInitButton(textures, &position, "Start Game", 11/*String len*/, buttonFontSize, BUTTON_ID_START_GAME); position.y += 250; Button *exitbutton = ButtonInitButton(textures, &position, "EXIT", 5/*String len*/, buttonFontSize, BUTTON_ID_EXIT); + // adding the ui elements UiContainerAddButton(uiContainer, continuebutton); UiContainerAddButton(uiContainer, exitbutton); @@ -63,56 +58,51 @@ static UiContainer * UiContainerInitMainMenuUiContainer(){ } // Only for use in UiContainer -static UiContainer * UiContainerInitGameUiContainer(){ - UiContainer *uiContainer = malloc(sizeof(UiContainer)); - - uiContainer->buttonCounter = 0; - uiContainer->selectableCounter = 0; - - Texture2D textures[3] = { LoadTexture("assets/selectable.png"), //DEFAULT - LoadTexture("assets/selectable.png"), //HOVERED - LoadTexture("assets/selectable.png") //SELECTED - }; - Texture2D textures2[3] = { LoadTexture("assets/entities/worker/arbeiten-4.png"), //DEFAULT - LoadTexture("assets/entities/worker/arbeiten-4.png"), //HOVERED - LoadTexture("assets/entities/worker/arbeiten-4.png") //SELECTED - }; - Texture2D backgroundTextures[3] = { LoadTexture("assets/selectable_background.png"), //DEFAULT - LoadTexture("assets/selectable_background_hovered.png"), //HOVERED - LoadTexture("assets/selectable_background_selected.png") //SELECTED - }; - +static UiContainer * UiContainerInitGameUiContainer(Game *game){ + UiContainer *uiContainer = UiContainerInitEmptyUiContainer(); + + // predefined stuff + Texture2D *texture1 = game->textures->textures[TE_BUILDING]; + Texture2D *texture2 = game->textures->textures[TE_WORKER] ; + Texture2D *texture3 = game->textures->textures[TE_LUMBERJACK] ; + Texture2D **backgroundTextures = &(game->textures->textures[TE_SELECTABLE_BACKGROUND]); Vector2 position = (Vector2){20, 300}; int showDescription = 1; int hasBackground = 1; int groupOne = 0; int groupTwo = 1; int fontSize = 16; - Selectable *selectable1 = SelectableInit(textures, backgroundTextures, hasBackground , &position, "Building", - showDescription, 9/*String len*/, fontSize, SELECTABLE_ID_SPAWN_BUILDING, groupOne, 1); + int unselectAfterExecute = 1; + + // creating the ui elements + Selectable *selectable1 = SelectableInit(texture1, backgroundTextures, hasBackground , &position, "Building", + showDescription, 9/*String len*/, fontSize, SELECTABLE_ID_SPAWN_BUILDING, + groupOne, unselectAfterExecute); position.y += 100; - Selectable *selectable2 = SelectableInit(textures2, backgroundTextures, hasBackground,&position, "Worker", - showDescription, 7/*String len*/, fontSize, SELECTABLE_ID_SPAWN_WORKER, groupOne, 1); + Selectable *selectable2 = SelectableInit(texture2, backgroundTextures, hasBackground,&position, "Worker", + showDescription, 7/*String len*/, fontSize, SELECTABLE_ID_SPAWN_WORKER, groupOne, + unselectAfterExecute); position.y += 100; - Selectable *selectable3 = SelectableInit(textures2, backgroundTextures, hasBackground,&position, "Lumberjack", - showDescription, 11/*String len*/, fontSize, SELECTABLE_ID_SPAWN_LUMBERJACK, groupOne, 1); + Selectable *selectable3 = SelectableInit(texture3, backgroundTextures, hasBackground,&position, "Lumberjack", + showDescription, 11/*String len*/, fontSize, SELECTABLE_ID_SPAWN_LUMBERJACK, groupOne, + unselectAfterExecute); + // adding the ui elements UiContainerAddSelectable(uiContainer, selectable1); UiContainerAddSelectable(uiContainer, selectable2); UiContainerAddSelectable(uiContainer, selectable3); - UiContainerAddSelectable(uiContainer, selectable4); return uiContainer; } -UiContainer * UiContainerInitUiContainerForScreenID(int id){ +UiContainer * UiContainerInitUiContainerForScreenID(Game *game, int id){ switch(id){ case SCREEN_MAINMENU: - return UiContainerInitMainMenuUiContainer(); + return UiContainerInitMainMenuUiContainer(game); case SCREEN_GAME: - return UiContainerInitGameUiContainer(); + return UiContainerInitGameUiContainer(game); case SCREEN_PAUSE: - return UiContainerInitPauseUiContainer(); + return UiContainerInitPauseUiContainer(game); default: printf("WARNING: Creating UiContainer for Screen ID %d (not implemented)\n", id); return UiContainerInitEmptyUiContainer(); diff --git a/Ui/uiContainer.h b/Ui/uiContainer.h index d1c6e59..47adb0c 100644 --- a/Ui/uiContainer.h +++ b/Ui/uiContainer.h @@ -16,7 +16,7 @@ typedef struct UiContainer{ void UiContainerUpdateUiContainer(UiContainer *uiContainer, Game *game); void UiContainerDrawUiContainer(UiContainer *uiContainer); -UiContainer * UiContainerInitUiContainerForScreenID(int id); +UiContainer * UiContainerInitUiContainerForScreenID(Game *game, int id); void UiContainerAddButton(UiContainer *uiContainer, Button *button); void UiContainerAddSelectable(UiContainer *uiContainer, Selectable *selectable); diff --git a/definitions.h b/definitions.h index e1724d2..7bf3aaf 100644 --- a/definitions.h +++ b/definitions.h @@ -24,11 +24,14 @@ #define TE_BAUSTELLE 3 #define TE_PINETREE 4 #define TE_LUMBERJACK 5 +#define TE_SELECTABLE_BACKGROUND 6 +#define TE_BUTTON 7 -#define TE_AMOUNT 6 +#define TE_AMOUNT 8 #define TE_ENTITY_LENGTH 104 #define TE_MAPOBJECT_LENGTH 1 - +#define TE_SELECTABLE_BACKGROUND_LENGTH 3 +#define TE_BUTTON_LENGTH 3 // Definitions for animations #define AN_WORKER 0 @@ -83,6 +86,8 @@ #define SELECTABLE_ID_SPAWN_WORKER 1 #define SELECTABLE_ID_SPAWN_LUMBERJACK 2 +#define UNSELECT_SELECTABLE_ON_SELECT 1 + #endif diff --git a/game.c b/game.c index ccb040a..8fb4eb4 100644 --- a/game.c +++ b/game.c @@ -10,8 +10,8 @@ #include "MapObject/building.h" #include "Ui/uiContainer.h" #include "MapObject/staticobjects.h" +#include "Screen/screen.h" -// returns pointer to new Game instance Game *GameInit() { Game *game = malloc(sizeof(Game)); @@ -28,10 +28,8 @@ Game *GameInit() game->inputHandler->cursorWorldPos.y = 0; game->inputHandler->cursorWorldTile.x = 0; game->inputHandler->cursorWorldTile.y = 0; - game->screen = SCREEN_MAINMENU; game->mouseOnUI = 0; - game->mouseFrameLock = 0; game->camera = malloc(sizeof(Camera2D)); game->camera->target.x = 0; @@ -57,10 +55,11 @@ Game *GameInit() IsometricMapChangeTextureIdOfTile(game->map, i, j, 0); } } - // ------- + for(i = 0; i < SCREEN_AMOUNT; i++){ - game->UiContainers[i] = UiContainerInitUiContainerForScreenID(i); + game->screens[i] = InitScreen(game, i); } + game->currentScreen = SCREEN_MAINMENU; return game; } diff --git a/game.h b/game.h index 534b7a8..a2b6e6c 100644 --- a/game.h +++ b/game.h @@ -16,14 +16,12 @@ typedef struct Game{ struct BuildingList *buildings; struct StaticObjectList *objects; struct EntityList *entities; - struct UiContainer *UiContainers[SCREEN_AMOUNT]; - int screen; + struct Screen *screens[SCREEN_AMOUNT]; + int currentScreen; int mouseOnUI ; // 0:not on UI 1:on UI - int mouseFrameLock ; // Sollten wir nicht brauchen wenn wir unsere Inputs gut definieren } Game; -// returns pointer to new Game instance Game * GameInit(); #endif diff --git a/main.c b/main.c index 7ce9bd9..f07ad54 100644 --- a/main.c +++ b/main.c @@ -12,11 +12,7 @@ #include "Ui/uiContainer.h" #include "Ui/debug.h" #include "definitions.h" - - // TODO: Variable die den Maus Input freigibt solange nichts mit der Maus gemacht wurde - // Sobald ein Button gedrückt wurde in diesem Frame oder rect gezogen wird oder so ist sind Maus Funktionen gesperrt - // verhindert Spawnen von entities wenn man UI Elemente Drückt etc - // Alternativ: Flag MouseOnHUD, aber nicht so universal einsetzbar, löst nur meine Probleme mit dem Spawnen bei klicks aufs HUD +#include "Screen/screen.h" int main(){ @@ -27,98 +23,29 @@ int main(){ // Hides the operating systems own cursor HideCursor(); - //SetTargetFPS(50); - + //SetTargetFPS(60); - double frame = 0; while(!WindowShouldClose()){ - // Drawen wir einfach immer den UI Container vom aktuellen Screen? Aktuell hat ja jeder Screen einen, es sollte also keine Probleme geben - // Kann man natürlich auch noch oben in die einzelnen Cases schieben falls es mal Probleme machen sollte - game->mouseOnUI = 0; - UiContainerUpdateUiContainer(game->UiContainers[game->screen], game); - - // Moving cursor Sprite to Mouse Pos - game->cursorSprite->x = GetMousePosition().x; - game->cursorSprite->y = GetMousePosition().y; - BeginDrawing(); // Drawing ist grundsätzlich immer aktiviert ClearBackground(RAYWHITE); // Screen wird in jedem Frame gecleared - switch(game->screen){ // Screenspecific Code - case SCREEN_EXIT: - printf("EXIT \n"); - return 0; - case SCREEN_MAINMENU: - // MainMenu hat aktuell nur paar Buttons, die unten gedrawed werden - break; - case SCREEN_OPTIONS: - printf("OPTIONS \n"); - return 0; - case SCREEN_GAME: - // Updating Entities - frame += GetFrameTime(); - if(frame >= ACT_TIME){ - EntityListActAllEntities(game); - frame = 0; - } - - // Drawing IsometricMap - BeginMode2D(*(game->camera)); // Sorgt dafür, dass die Kameraposition beachtet wird - IsometricMapDraw(game); - - SpriteListDrawAllSprites(game->sprites, game->map, game->camera); - EndMode2D(); - - // User Input Handling - mouseInput(game); - keyboardInput(game); - - break; - case SCREEN_PAUSE: - int halfScreenHeight = GetScreenHeight()/2; - - // Still drawing isometric map, which is not updated atm - BeginMode2D(*(game->camera)); // Sorgt dafür, dass die Kameraposition beachtet wird - IsometricMapDraw(game); - SpriteListDrawAllSprites(game->sprites, game->map, game->camera); - EndMode2D(); - UiContainerDrawUiContainer(game->UiContainers[SCREEN_GAME]); - // darkened background + "Paused" Text - DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), (Color){0, 0, 0, 150}); - int textWidthHalf = (MeasureText("Paused", 28)/2); - DrawText("Paused", GetScreenWidth()/2 - textWidthHalf, (halfScreenHeight/2) - 14, 28, WHITE); - // Controls lol - DrawText("I: Zoom in", 5, halfScreenHeight, 16, WHITE); - DrawText("K: Zoom out", 5, halfScreenHeight + 16, 16, WHITE); - DrawText("P: Pause", 5, halfScreenHeight + 32, 16, WHITE); - DrawText("WASD: Move Camera", 5, halfScreenHeight + 48, 16, WHITE); - DrawText("ESC: Exit Game", 5, halfScreenHeight + 64, 16, WHITE); - - if(IsKeyPressed(KEY_P)){ - game->screen = SCREEN_GAME; - } - break; - default: - printf("\n\n\n\n\n\n Wir haben ein problematisches Problem! Die Screen-ID [%d] ist nicht definiert. Hmmpf... früher bescheid wisse!\n\n\n\n\n\n", game->screen); - return 1; - break; - } - - // Drawen wir einfach immer den UI Container vom aktuellen Screen? Aktuell hat ja jeder Screen einen, es sollte also keine Probleme geben - // Kann man natürlich auch noch oben in die einzelnen Cases schieben falls es mal Probleme machen sollte - UiContainerDrawUiContainer(game->UiContainers[game->screen]); + game->mouseOnUI = 0; + game->cursorSprite->x = GetMousePosition().x; + game->cursorSprite->y = GetMousePosition().y; + UiContainerUpdateUiContainer(game->screens[game->currentScreen]->uiContainer, game); + game->screens[game->currentScreen]->render(game); // Die ganze Game Logik ist hier drin + UiContainerDrawUiContainer(game->screens[game->currentScreen]->uiContainer); - // Dinge die grundsätzlich immer gedrawed werden sollen - // Debug Menu, FPS anzeige, Cursor DebugDraw(game); DrawSpriteToScreen(game->cursorSprite); - EndDrawing(); + EndDrawing(); + if(game->currentScreen == SCREEN_EXIT){ + break; + } } CloseWindow(); - return 0; - }