From feab2ebb1fa1ba5b03b0bf96fe898b4488e70019 Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Sun, 23 Feb 2025 17:28:13 -0500 Subject: [PATCH 1/4] Fix different card colors --- card.c | 4 ++-- card.h | 2 +- game.c | 17 ++++++++++------- game.h | 2 +- main.c | 1 - 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/card.c b/card.c index 148b44c..1c417be 100644 --- a/card.c +++ b/card.c @@ -6,7 +6,7 @@ static Vector2 card_size = (Vector2) { CARD_WIDTH, CARD_HEIGHT }; static char *month_english_abbr[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; Color BRICKRED = (Color) { 136, 12, 2, 255 }; -void draw_card(Card *c, Texture2D **cards_texture, int index) { +void draw_card(Card *c, Texture2D *cards_texture, int index) { int i_vert = c->index % 4; int i_horiz = c->index / 4; int pos_vert = i_vert * CARD_HEIGHT; @@ -16,7 +16,7 @@ void draw_card(Card *c, Texture2D **cards_texture, int index) { if (c->visible) { DrawTexturePro( - *cards_texture[index ? 1 : 0], + *cards_texture, (Rectangle) { pos_horiz, pos_vert, CARD_WIDTH, CARD_HEIGHT }, (Rectangle) { c->position.x, c->position.y, card_size.x, card_size.y }, (Vector2) { 0, 0 }, diff --git a/card.h b/card.h index f57bfbf..23db92f 100644 --- a/card.h +++ b/card.h @@ -73,7 +73,7 @@ struct Hand { HandDisplayType display_type; }; -void draw_card(Card *c, Texture2D **cards_texture, int index); +void draw_card(Card *c, Texture2D *cards_texture, int index); bool point_within_card(Card *c, Vector2 v); void shuffle_hand(Hand *h); void deal(Hand *from, Hand *to, int count, bool up, float deal_speed); diff --git a/game.c b/game.c index 73ce60c..30dc347 100644 --- a/game.c +++ b/game.c @@ -15,13 +15,12 @@ Vector2 mouse_pos; char teyaku_calculation[400]; void initialize_game(Game *g) { - g->cards_texture = malloc(2 * sizeof(Texture)); Image cards_image_red = LoadImage("img/cards_red.png"); - g->cards_texture[0] = LoadTextureFromImage(cards_image_red); + g->cards_texture_red = LoadTextureFromImage(cards_image_red); UnloadImage(cards_image_red); Image cards_image_black = LoadImage("img/cards_black.png"); - g->cards_texture[1] = LoadTextureFromImage(cards_image_black); + g->cards_texture_black = LoadTextureFromImage(cards_image_black); UnloadImage(cards_image_black); g->deck.count = 0; @@ -840,13 +839,17 @@ void run_frame(Game *g) { } } +Texture *cards_texture(Game *g) { + return g->black_card_backs ? &g->cards_texture_black : &g->cards_texture_red; +} + void draw_player_cards(Game *g, Player *p) { for (int i = 0; i < p->hand.count; i++) { - draw_card(p->hand.cards[i], &g->cards_texture, g->black_card_backs); + draw_card(p->hand.cards[i], cards_texture(g), g->black_card_backs); } for (int i = 0; i < p->scored.count; i++) { - draw_card(p->scored.cards[i], &g->cards_texture, g->black_card_backs); + draw_card(p->scored.cards[i], cards_texture(g), g->black_card_backs); } } @@ -855,11 +858,11 @@ void draw_cards(Game *g) { draw_player_cards(g, &g->right); draw_player_cards(g, &g->left); for (int i = 0; i < g->field.count; i++) { - draw_card(g->field.cards[i], &g->cards_texture, g->black_card_backs); + draw_card(g->field.cards[i], cards_texture(g), g->black_card_backs); } for (int i = 0; i < g->deck.count; i++) { - draw_card(g->deck.cards[i], &g->cards_texture, g->black_card_backs); + draw_card(g->deck.cards[i], cards_texture(g), g->black_card_backs); } } diff --git a/game.h b/game.h index 44ccc15..0d6be42 100644 --- a/game.h +++ b/game.h @@ -41,7 +41,7 @@ struct Game { GameState state; bool should_close; Card cards[48]; - Texture2D *cards_texture; + Texture2D cards_texture_red, cards_texture_black; Hand deck, field; FieldMultiplier *field_multiplier; Card *current_play_from_hand, *current_play_target; diff --git a/main.c b/main.c index 69404e0..0d8d2a3 100644 --- a/main.c +++ b/main.c @@ -9,7 +9,6 @@ #include "game.h" char *text = "こんにちわ、 世界!"; -Texture2D cards_texture; int main(int argc, char** argv) { srand(time(NULL)); From d500962670adce2de3a885e46d9734b6d6a41982 Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Sun, 23 Feb 2025 18:07:57 -0500 Subject: [PATCH 2/4] Title screen --- game.c | 14 +++++++++++++- game.h | 2 ++ main.c | 2 -- options.c | 4 ++-- title.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ title.h | 19 +++++++++++++++++++ 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 title.c create mode 100644 title.h diff --git a/game.c b/game.c index 30dc347..347f301 100644 --- a/game.c +++ b/game.c @@ -36,6 +36,7 @@ void initialize_game(Game *g) { g->black_card_backs = true; g->deal_speed = 0.2; g->options = malloc(sizeof(Options)); + g->title = malloc(sizeof(Title)); load_options_from_game(g); init_dialogs(g); @@ -147,7 +148,7 @@ void initialize_game(Game *g) { } g->current_round = 0; - g->state = GAME_STATE_OPTIONS; + g->state = GAME_STATE_TITLE_SCREEN; } Player *current_player(Game *g) { @@ -172,6 +173,10 @@ void handle_input(Game *g) { return options_handle_input(g); } + if (g->state == GAME_STATE_TITLE_SCREEN) { + return title_handle_input(g); + } + if (g->dialog) { return dialog_handle_input(g->dialog); } @@ -835,6 +840,7 @@ void run_frame(Game *g) { run_frame_new_game(g); break; case GAME_STATE_OPTIONS: + case GAME_STATE_TITLE_SCREEN: break; } } @@ -878,6 +884,12 @@ void draw_frame(Game *g) { return; } + if (g->state == GAME_STATE_TITLE_SCREEN) { + title_draw(g); + EndDrawing(); + return; + } + if (g->state == GAME_STATE_DEALING) { DrawText("Dealing....", 60, 385, 40, BLACK); } else if (g->field_multiplier) { diff --git a/game.h b/game.h index 0d6be42..8cf0fcf 100644 --- a/game.h +++ b/game.h @@ -13,6 +13,7 @@ typedef struct Game Game; #include "player.h" #include "dialog.h" #include "options.h" +#include "title.h" typedef enum GameState { GAME_STATE_INITIALIZING, @@ -56,6 +57,7 @@ struct Game { bool black_card_backs; float deal_speed; Options *options; + Title *title; }; void initialize_game(Game *g); diff --git a/main.c b/main.c index 0d8d2a3..864cd2b 100644 --- a/main.c +++ b/main.c @@ -8,8 +8,6 @@ #include "game.h" -char *text = "こんにちわ、 世界!"; - int main(int argc, char** argv) { srand(time(NULL)); InitWindow(1400, 900, "Hanafuda Hachi-Hachi"); diff --git a/options.c b/options.c index 0cecc2a..4f0962c 100644 --- a/options.c +++ b/options.c @@ -29,12 +29,12 @@ void save_options_to_game(Game *g) { void handle_options_save(Game *g) { save_options_to_game(g); - g->state = GAME_STATE_INITIALIZING; + g->state = GAME_STATE_TITLE_SCREEN; } void handle_options_cancel(Game *g) { load_options_from_game(g); - g->state = GAME_STATE_INITIALIZING; + g->state = GAME_STATE_TITLE_SCREEN; } void handle_select_kan(Game *g, int index) { diff --git a/title.c b/title.c new file mode 100644 index 0000000..9fe8be8 --- /dev/null +++ b/title.c @@ -0,0 +1,55 @@ +#include "title.h" + +void title_handle_click_start(Game *g) { + g->state = GAME_STATE_INITIALIZING; +} + +void title_handle_click_options(Game *g) { + g->state = GAME_STATE_OPTIONS; +} + +void title_handle_click_quit(Game *g) { + g->should_close = true; +} + +Vector2 tmp; // stands for "title mouse position" +void title_handle_input(Game *g) { + tmp = GetMousePosition(); + Title *t = g->title; + t->hover_start = false; + t->hover_options = false; + t->hover_quit = false; + t->hover_credits = false; + t->hover_rules = false; + + int half_start_width = MeasureText("Start", 60) / 2; + if (tmp.x > 700-half_start_width && tmp.x < 700+half_start_width && tmp.y > 350 && tmp.y < 410) { + t->hover_start = true; + if (IsMouseButtonPressed(0)) title_handle_click_start(g); + } + int half_options_width = MeasureText("Options", 60) / 2; + if (tmp.x > 700-half_options_width && tmp.x < 700+half_options_width && tmp.y > 500 && tmp.y < 560) { + t->hover_options = true; + if (IsMouseButtonPressed(0)) title_handle_click_options(g); + } + int half_quit_width = MeasureText("Quit", 60) / 2; + if (tmp.x > 700-half_quit_width && tmp.x < 700+half_quit_width && tmp.y > 650 && tmp.y < 710) { + t->hover_quit = true; + if (IsMouseButtonPressed(0)) title_handle_click_quit(g); + } + int half_credits_width = MeasureText("Credits", 40) / 2; + if (tmp.x > 1100-half_credits_width && tmp.x < 1100+half_credits_width && tmp.y > 600 && tmp.y < 640) t->hover_credits = true; + int half_rules_width = MeasureText("Rules", 40) / 2; + if (tmp.x > 300-half_rules_width && tmp.x < 300+half_rules_width && tmp.y > 600 && tmp.y < 640) t->hover_rules = true; + +} + +void title_draw(Game *g) { + Title *t = g->title; + DrawTextCentered("Hanafuda Hachi-Hachi", 700, 100, 90, BLACK); + DrawTextCentered("Start", 700, 350, 60, t->hover_start ? RED : BLACK); + DrawTextCentered("Options", 700, 500, 60, t->hover_options ? RED : BLACK); + DrawTextCentered("Quit", 700, 650, 60, t->hover_quit ? RED : BLACK); + DrawTextCentered("Credits", 1100, 600, 40, t->hover_credits ? RED : BLACK); + DrawTextCentered("Rules", 300, 600, 40, t->hover_rules ? RED : BLACK); +} diff --git a/title.h b/title.h new file mode 100644 index 0000000..97a1e41 --- /dev/null +++ b/title.h @@ -0,0 +1,19 @@ +#ifndef _HF_TITLE_ +#define _HF_TITLE_ + +typedef struct Title Title; + +#include "game.h" + +struct Title { + bool hover_start; + bool hover_options; + bool hover_quit; + bool hover_credits; + bool hover_rules; +}; + +void title_handle_input(Game *g); +void title_draw(Game *g); + +#endif From 6b609b3144b4e9a2a8284afd5e34daa12f4f8963 Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Sun, 23 Feb 2025 18:35:11 -0500 Subject: [PATCH 3/4] Add credits and rules to title screen --- game.c | 2 +- img/rules_qr.png | Bin 0 -> 406 bytes title.c | 26 ++++++++++++++++++++++++-- title.h | 2 ++ 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 img/rules_qr.png diff --git a/game.c b/game.c index 347f301..b7f8096 100644 --- a/game.c +++ b/game.c @@ -36,7 +36,7 @@ void initialize_game(Game *g) { g->black_card_backs = true; g->deal_speed = 0.2; g->options = malloc(sizeof(Options)); - g->title = malloc(sizeof(Title)); + initialize_title(g); load_options_from_game(g); init_dialogs(g); diff --git a/img/rules_qr.png b/img/rules_qr.png new file mode 100644 index 0000000000000000000000000000000000000000..df39fdc6db8ceac3d097b5d69a39f8abac2cfcf0 GIT binary patch literal 406 zcmV;H0crk;P)* z)Ul0)FboFZA5o;^Ef6Vdq{~WS0Uj*Ct&}cnJShv1E=7dT@FeuEiP1HuizxUa0k&fU z`myjoxB*Wx8#G`07*qoM6N<$f-&~4 Ax&QzG literal 0 HcmV?d00001 diff --git a/title.c b/title.c index 9fe8be8..25d1df8 100644 --- a/title.c +++ b/title.c @@ -1,5 +1,12 @@ #include "title.h" +void initialize_title(Game *g) { + g->title = malloc(sizeof(Title)); + Image rules_qr_img = LoadImage("img/rules_qr.png"); + g->title->rules_qr = LoadTextureFromImage(rules_qr_img); + UnloadImage(rules_qr_img); +} + void title_handle_click_start(Game *g) { g->state = GAME_STATE_INITIALIZING; } @@ -50,6 +57,21 @@ void title_draw(Game *g) { DrawTextCentered("Start", 700, 350, 60, t->hover_start ? RED : BLACK); DrawTextCentered("Options", 700, 500, 60, t->hover_options ? RED : BLACK); DrawTextCentered("Quit", 700, 650, 60, t->hover_quit ? RED : BLACK); - DrawTextCentered("Credits", 1100, 600, 40, t->hover_credits ? RED : BLACK); - DrawTextCentered("Rules", 300, 600, 40, t->hover_rules ? RED : BLACK); + DrawTextCentered("Credits", 1100, 600, 40, BLACK); + DrawTextCentered("Rules", 300, 600, 40, BLACK); + + if (t->hover_rules) DrawTextureEx(t->rules_qr, (Vector2) { 135, 250 }, 0., 3., WHITE); + + if (t->hover_credits) { + DrawRectangle(870, 200, 460, 380, BLACK); + DrawRectangle(873, 203, 454, 374, WHITE); + DrawTextCentered("Programmed by bassguitarbill", 1100, 210, 25, BLACK); + DrawTextCentered("https://bassguitarbill.rocks", 1100, 240, 25, BLACK); + DrawTextCentered("Running on raylib", 1100, 310, 25, BLACK); + DrawTextCentered("https://www.raylib.com", 1100, 340, 25, BLACK); + DrawTextCentered("Drawn with Aseprite", 1100, 410, 25, BLACK); + DrawTextCentered("https://www.aseprite.org", 1100, 440, 25, BLACK); + DrawTextCentered("Art adapted from Louiemantia", 1100, 510, 25, BLACK); + DrawTextCentered("https://commons.wikimedia.org/wiki/User:Louiemantia", 1100, 540, 18, BLACK); + } } diff --git a/title.h b/title.h index 97a1e41..6bc73f3 100644 --- a/title.h +++ b/title.h @@ -11,9 +11,11 @@ struct Title { bool hover_quit; bool hover_credits; bool hover_rules; + Texture2D rules_qr; }; void title_handle_input(Game *g); void title_draw(Game *g); +void initialize_title(Game *g); #endif From af3f180fa849c27c324e92cd84d0d71207fdd77b Mon Sep 17 00:00:00 2001 From: Bill Rossi Date: Sun, 23 Feb 2025 21:26:22 -0500 Subject: [PATCH 4/4] The title screen is now unusable --- card.c | 1 + game.c | 36 ++++++++++++++---------- title.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ title.h | 1 + 4 files changed, 110 insertions(+), 14 deletions(-) diff --git a/card.c b/card.c index 1c417be..f2cf3d3 100644 --- a/card.c +++ b/card.c @@ -15,6 +15,7 @@ void draw_card(Card *c, Texture2D *cards_texture, int index) { Color color = index == 1 ? BLACK : BRICKRED; if (c->visible) { + printf("draw card %p\n", cards_texture); fflush(stdout); DrawTexturePro( *cards_texture, (Rectangle) { pos_horiz, pos_vert, CARD_WIDTH, CARD_HEIGHT }, diff --git a/game.c b/game.c index b7f8096..12b2ebf 100644 --- a/game.c +++ b/game.c @@ -23,6 +23,8 @@ void initialize_game(Game *g) { g->cards_texture_black = LoadTextureFromImage(cards_image_black); UnloadImage(cards_image_black); + printf("%p %p\n", &g->cards_texture_black, &g->cards_texture_red); + g->deck.count = 0; g->deck.position = (Vector2) { 500, 300 }; g->deck.display_type = HAND_DISPLAY_DECK; @@ -76,14 +78,18 @@ void initialize_game(Game *g) { case 41: t = ANIMAL; break; } - g->cards[i] = (Card) { i, t, rt, month, { 500, 300 }, false }; + g->cards[i] = (Card) { i, t, rt, month, { -500, -300 }, false }; g->cards[i].move.end_time = 0.; g->cards[i].move.position = &g->cards[i].position; - g->cards[i].move.destination = (Vector2) { 500, 300 }; + g->cards[i].move.destination = (Vector2) { -500, -300 }; g->cards[i].order = i; g->cards[i].selected = false; + g->cards[i].visible = false; + g->deck.count++; } + printf("DONE CARDS\n"); + g->player.points = 100 * g->kan_value; g->right.points = 100 * g->kan_value; g->left.points = 100 * g->kan_value; @@ -782,6 +788,7 @@ void run_frame(Game *g) { if (g->dialog) return; move_cards(g); + if (g->state == GAME_STATE_TITLE_SCREEN) run_frame_title(g); if (!done_moving(g)) return; switch (g->state) { @@ -839,23 +846,24 @@ void run_frame(Game *g) { case GAME_STATE_NEW_GAME: run_frame_new_game(g); break; - case GAME_STATE_OPTIONS: case GAME_STATE_TITLE_SCREEN: break; + case GAME_STATE_OPTIONS: + break; } } -Texture *cards_texture(Game *g) { +Texture *cards_texture_fun(Game *g) { return g->black_card_backs ? &g->cards_texture_black : &g->cards_texture_red; } void draw_player_cards(Game *g, Player *p) { for (int i = 0; i < p->hand.count; i++) { - draw_card(p->hand.cards[i], cards_texture(g), g->black_card_backs); + draw_card(p->hand.cards[i], cards_texture_fun(g), g->black_card_backs); } for (int i = 0; i < p->scored.count; i++) { - draw_card(p->scored.cards[i], cards_texture(g), g->black_card_backs); + draw_card(p->scored.cards[i], cards_texture_fun(g), g->black_card_backs); } } @@ -864,11 +872,11 @@ void draw_cards(Game *g) { draw_player_cards(g, &g->right); draw_player_cards(g, &g->left); for (int i = 0; i < g->field.count; i++) { - draw_card(g->field.cards[i], cards_texture(g), g->black_card_backs); + draw_card(g->field.cards[i], cards_texture_fun(g), g->black_card_backs); } for (int i = 0; i < g->deck.count; i++) { - draw_card(g->deck.cards[i], cards_texture(g), g->black_card_backs); + draw_card(g->deck.cards[i], cards_texture_fun(g), g->black_card_backs); } } @@ -876,16 +884,16 @@ void draw_frame(Game *g) { BeginDrawing(); ClearBackground(RAYWHITE); - draw_cards(g); - - if (g->state == GAME_STATE_OPTIONS) { - options_draw(g); + if (g->state == GAME_STATE_TITLE_SCREEN) { + title_draw(g); EndDrawing(); return; } - if (g->state == GAME_STATE_TITLE_SCREEN) { - title_draw(g); + draw_cards(g); + + if (g->state == GAME_STATE_OPTIONS) { + options_draw(g); EndDrawing(); return; } diff --git a/title.c b/title.c index 25d1df8..2d0fab8 100644 --- a/title.c +++ b/title.c @@ -1,3 +1,5 @@ +#include +#include #include "title.h" void initialize_title(Game *g) { @@ -48,10 +50,94 @@ void title_handle_input(Game *g) { if (tmp.x > 1100-half_credits_width && tmp.x < 1100+half_credits_width && tmp.y > 600 && tmp.y < 640) t->hover_credits = true; int half_rules_width = MeasureText("Rules", 40) / 2; if (tmp.x > 300-half_rules_width && tmp.x < 300+half_rules_width && tmp.y > 600 && tmp.y < 640) t->hover_rules = true; +} +void title_fly_card(Game *g, Card *card) { + int x, y; + switch ((int) rand() % 4) { + case 0: + x = (rand() % 1600) - 100; + y = -100; + break; + case 1: + x = (rand() % 1600) - 100; + y = 1000; + break; + case 2: + x = -100; + y = (rand() % 1100) - 100;; + break; + case 3: + x = 1500; + y = (rand() % 1100) - 100;; + break; + } + + card->position.x = x; + card->position.y = y; + Move *move = &card->move; + move->position->x = x; + move->position->y = y; + move->origin.x = x; + move->origin.y = y; + + + switch ((int) rand() % 4) { + case 0: + x = (rand() % 1600) - 100; + y = -100; + break; + case 1: + x = (rand() % 1600) - 100; + y = 1000; + break; + case 2: + x = -100; + y = (rand() % 1100) - 100;; + break; + case 3: + x = 1500; + y = (rand() % 1100) - 100;; + break; + } + + move->destination.x = x; + move->destination.y = y; + + move->curve = CURVE_LINEAR; + + move->current_time = 0.; + move->end_time = (rand() % 5) + 1; + printf("current: %f, end: %f\n", card->move.current_time, card->move.end_time); +} + +void run_frame_title(Game *g) { + if (rand() % 20 > 3) return; + + Card *card = NULL; + for (int i = 0; i < 48; i++) { + int index = rand() % 48; + if (g->cards[index].move.current_time > g->cards[index].move.end_time) { + card = &g->cards[index]; + break; + } + } + + if (!card) return; + + title_fly_card(g, card); +} + +Texture *cards_texture_fun2(Game *g) { + return g->black_card_backs ? &g->cards_texture_black : &g->cards_texture_red; } void title_draw(Game *g) { + for (int i = 0; i < 48; i++) { + g->cards[i].visible = true; + draw_card(&g->cards[i], cards_texture_fun2(g), g->black_card_backs); + } + Title *t = g->title; DrawTextCentered("Hanafuda Hachi-Hachi", 700, 100, 90, BLACK); DrawTextCentered("Start", 700, 350, 60, t->hover_start ? RED : BLACK); diff --git a/title.h b/title.h index 6bc73f3..4930ec2 100644 --- a/title.h +++ b/title.h @@ -17,5 +17,6 @@ struct Title { void title_handle_input(Game *g); void title_draw(Game *g); void initialize_title(Game *g); +void run_frame_title(Game *g); #endif