#include #include #include #include #include #include #include #include #include "types.h" #include "game.h" #include "draw.h" #include "ui.h" #include "config.h" char _ver_str[256]; char *VERSION_STR = _ver_str; GUIInfo gui_info; #define color_main_brown (Color){247, 239, 206, 255} #define color_main_brown1 (Color){161, 151, 112, 255} void draw_text_centered(char *str, int y, int font_size, Color color){ int width = MeasureText(str, font_size); DrawText(str, 640-width/2, y, font_size, color); } void draw_buttons(Widget *widget){ for(int i = 0; i < widget->button_n; i++){ Button *butt = &widget->buttons[i]; DrawRectangleRounded(butt->box, 0.1, 3, butt->color_0); Color outline_color = butt->curr_select ? SKYBLUE : butt->color_1; DrawRectangleRoundedLines(butt->box, 0.1, 3, 2, outline_color); int font_size = 0.75*butt->box.height; int width = MeasureText(butt->txt, font_size); int text_x = butt->box.x + butt->box.width/2 - width/2; int text_y = butt->box.y + butt->box.height/5; DrawText(butt->txt, text_x, text_y, font_size, butt->color_txt); } } void buttons_do_event(Widget *widget, Game *game, MTEvent event){ if(event.type != EV_Mouse || event.click != MOUSE_BUTTON_LEFT) return; for(int i = 0; i < widget->button_n; i++){ Button *butt = &widget->buttons[i]; if(CheckCollisionPointRec(event.pos, butt->box) && butt->handler) butt->handler(game); } } void main_menu_draw(Widget *widget, Game *game){ ClearBackground(color_main_brown); draw_text_centered("Mineur Tycoon", 50, 100, BLACK); draw_text_centered(VERSION_STR, 160, 30, BLACK); DrawRectangleRounded((Rectangle){500, 200, 280, 260}, 0.1, 3, color_main_brown1); draw_buttons(widget); } void widget_draw_game(Widget *widget, Game *game){ draw_game(game); } void game_exit(Game *game){ game->exit = true; } void main_menu_new_game(Game *game){ gui_info.widget_active[0] = true; gui_info.widget_active[1] = false; game->paused = false; } Widget main_menu = { .box = {.x = 0, .y = 0, .width = -1, .height = -1}, .draw = main_menu_draw, .do_event = buttons_do_event, .capt_flags = CF_Mouse | CF_Keyb, .buttons = { {.box = {520,220,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = BLACK, .txt = "New game", .handler = main_menu_new_game }, {.box = {520,270,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = GRAY, .txt = "Load game", .handler = NULL }, {.box = {520,320,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = GRAY, .txt = "Settings", .handler = NULL }, {.box = {520,400,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = BLACK, .txt = "Exit", .handler = game_exit }, }, .button_n = 4 }; void pause_menu_draw(Widget *widget, Game *game){ DrawRectangleRounded((Rectangle){500, 150, 280, 380}, 0.1, 3, color_main_brown1); draw_buttons(widget); } void pause_menu_resume(Game *game){ gui_info.widget_active[4] = false; gui_info.widget_active[0] = true; game->paused = false; } void pause_menu_new_game(Game *game){ clean_game(game); init_game(game); pause_menu_resume(game); } Widget pause_menu = { .box = {.x = 0, .y = 0, .width = -1, .height = -1}, .draw = pause_menu_draw, .do_event = buttons_do_event, .capt_flags = CF_Mouse | CF_Keyb, .buttons = { {.box = {520,170,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = BLACK, .txt = "Resume", .handler = pause_menu_resume }, {.box = {520,240,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = BLACK, .txt = "New game", .handler = pause_menu_new_game }, {.box = {520,290,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = GRAY, .txt = "Save game", .handler = NULL }, {.box = {520,340,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = GRAY, .txt = "Load game", .handler = NULL }, {.box = {520,390,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = GRAY, .txt = "Settings", .handler = NULL }, {.box = {520,470,240,40}, .color_0 = WHITE, .color_1 = BLACK, .color_txt = BLACK, .txt = "Exit", .handler = game_exit } }, .button_n = 6 }; void worker_widget_draw(Widget *widget, Game *game){ DrawRectangleRounded(widget->box, 0.1, 3, color_main_brown); } void worker_widget_do_event(Widget *widget, Game *game, MTEvent event){ if(event.click == MOUSE_BUTTON_LEFT) gui_info.widget_active[2] = false; } Widget worker_widget = { .box = {.x = 40, .y = 40, .width = 300, .height = 600}, .draw = worker_widget_draw, .do_event = worker_widget_do_event, .capt_flags = CF_Mouse, .buttons = { }, .button_n = 0 }; Widget machine_widget = { }; Widget game_widget = { .box = {0,0,0,0}, .draw = widget_draw_game, .do_event = NULL, .capt_flags = 0, .buttons = {}, .button_n = 0 }; void init_ui(){ snprintf(_ver_str, 256, "v%d.%d-%d", VERSION_MAJ, VERSION_MIN, VERSION_PATCH); // Android exclusive key -> no exit key SetExitKey(KEY_MENU); gui_info = (GUIInfo){{&game_widget, &main_menu, &worker_widget, &machine_widget, &pause_menu}, {false, true, false, false, false}, NULL}; } void draw_widgets(Game *game){ for(int i = 0; i < WIDGET_N; i++){ if(!gui_info.widget_active[i]) continue; Widget *w = gui_info.widgets[i]; if(w->draw) w->draw(w, game); } } bool widget_coll(Rectangle widget, V2d point){ if(widget.width < 0) widget.width = SCREEN_W; if(widget.height < 0) widget.height = SCREEN_H; return CheckCollisionPointRec(point, widget); } bool widgets_treat_event(Game *game, MTEvent event){ bool treated = true; for(int i = WIDGET_N-1; i >= 0 && treated; i--){ if(!gui_info.widget_active[i]) continue; Widget *w = gui_info.widgets[i]; if(!w || !w->do_event) continue; if(!widget_coll(w->box, event.pos)) continue; // Only actually call do_key if the event type matches event flags switch(event.type){ default: continue; case EV_Mouse: if(w->capt_flags & CF_Mouse) break; continue; case EV_Keyb: if(w->capt_flags & CF_Keyb) break; continue; } treated = false; w->do_event(w, game, event); } return treated; } bool ui_do_key(Game *game, int key){ MTEvent event = {.type = EV_Keyb, {.key = key}}; return widgets_treat_event(game, event); } bool ui_do_mouse(Game *game, V2d pos, int click){ MTEvent event = {.type = EV_Mouse, {.click = click}, .pos = pos}; return widgets_treat_event(game, event); } void try_interface(Game *game, V2d pos){ DrawRectangleV(pos, (V2d){16,16},PINK); Machine *mach = get_machine_from_pos(&game->machines, pos); if(mach){ printf("found machine %d\n",mach->id); return; } Worker *work = get_worker_from_pos(&game->workers, pos); if(!work) return; printf("found worker\n"); gui_info.widget_active[2] = true; return; } bool keydown(int key){ return IsKeyDown(key); } void goto_pause_menu(Game *game){ if(gui_info.widget_active[1]) return; memset(gui_info.widget_active, false, sizeof(bool)*WIDGET_N); gui_info.widget_active[4] = true; game->paused = true; } int get_mouse(){ for(int i = 0; i < MOUSE_BUTTON_NULL; i++){ if(IsMouseButtonPressed(i)) return i; } return MOUSE_BUTTON_NULL; } void get_keys(Game *game){ V2d mouse_pos = GetMousePosition(); int mouse_click = get_mouse(); if(ui_do_mouse(game, mouse_pos, mouse_click)){ if(mouse_click == MOUSE_BUTTON_LEFT) try_interface(game, GetScreenToWorld2D(mouse_pos,game->camera)); } if(keydown(KEY_W)) game->camera.target.y -= 3; if(keydown(KEY_S)) game->camera.target.y += 3; if(keydown(KEY_A)) game->camera.target.x -= 3; if(keydown(KEY_D)) game->camera.target.x += 3; if(keydown(KEY_UP)) game->camera.zoom *= 1.025; if(keydown(KEY_DOWN)) game->camera.zoom *= 1/1.025; if(IsKeyPressed(KEY_P)) game->paused = !game->paused; if(IsKeyPressed(KEY_ESCAPE)) goto_pause_menu(game); }