Просмотр исходного кода

create/use sprite creation, update town world

jblanked 1 год назад
Родитель
Сommit
90ee17ffae
9 измененных файлов с 118 добавлено и 72 удалено
  1. 1 8
      game/draw.c
  2. 12 33
      game/enemy.c
  3. 1 2
      game/enemy.h
  4. 2 2
      game/icon.c
  5. 1 1
      game/icon.h
  6. 4 4
      game/level.c
  7. 64 0
      game/player.c
  8. 12 1
      game/player.h
  9. 21 21
      game/world.c

+ 1 - 8
game/draw.c

@@ -108,14 +108,7 @@ void spawn_icon(Level *level, const char *icon_id, float x, float y)
 {
     snprintf(g_temp_spawn_name, sizeof(g_temp_spawn_name), "%s", icon_id);
     Entity *e = level_add_entity(level, &icon_desc);
-    IconContext *icon_ctx = get_icon_context(icon_id);
-    if (!icon_ctx)
-    {
-        FURI_LOG_E("Game", "Failed to get icon context");
-        return;
-    }
-    // Set the entity position to the center of the icon
-    entity_pos_set(e, (Vector){x + (icon_ctx->width / 2), y + (icon_ctx->height / 2)});
+    entity_pos_set(e, (Vector){x, y});
 }
 // Draw a line of icons at a specific position (with collision detection)
 void spawn_icon_line(Level *level, const char *icon_id, float x, float y, uint8_t amount, bool horizontal)

+ 12 - 33
game/enemy.c

@@ -512,7 +512,6 @@ const EntityDescription *enemy(
     GameManager *manager,
     const char *id,
     int index,
-    Vector size,
     Vector start_position,
     Vector end_position,
     float move_timer, // Wait duration before moving again
@@ -521,11 +520,18 @@ const EntityDescription *enemy(
     float strength,
     float health)
 {
+    SpriteContext *sprite_context = get_sprite_context(id);
+    if (!sprite_context)
+    {
+        FURI_LOG_E("Game", "Failed to get SpriteContext");
+        return NULL;
+    }
+
     // Allocate a new EnemyContext with provided parameters
     enemy_context_generic = enemy_generic_alloc(
         id,
         index,
-        size,
+        (Vector){sprite_context->width, sprite_context->height},
         start_position,
         end_position,
         move_timer, // Set wait duration
@@ -538,19 +544,9 @@ const EntityDescription *enemy(
         FURI_LOG_E("Game", "Failed to allocate EnemyContext");
         return NULL;
     }
-    char right_edited[128];
-    char left_edited[128];
 
-    // Convert the float values to integers and use them in the filename
-    int size_x_int = (int)size.x;
-    int size_y_int = (int)size.y;
-
-    // Format the strings without the decimal points
-    snprintf(right_edited, sizeof(right_edited), "player_right_%s_%dx%dpx.fxbm", id, size_x_int, size_y_int);
-    snprintf(left_edited, sizeof(left_edited), "player_left_%s_%dx%dpx.fxbm", id, size_x_int, size_y_int);
-
-    enemy_context_generic->sprite_right = game_manager_sprite_load(manager, right_edited);
-    enemy_context_generic->sprite_left = game_manager_sprite_load(manager, left_edited);
+    enemy_context_generic->sprite_right = game_manager_sprite_load(manager, sprite_context->right_file_name);
+    enemy_context_generic->sprite_left = game_manager_sprite_load(manager, sprite_context->left_file_name);
 
     // Set initial direction based on start and end positions
     if (start_position.x < end_position.x)
@@ -592,14 +588,9 @@ void spawn_enemy_json(Level *level, GameManager *manager, char *json)
         FURI_LOG_E("Game", "GameManager is NULL");
         return;
     }
-    // parameters: id, index, size.x, size.y, start_position.x, start_position.y, end_position.x, end_position.y, move_timer, speed, attack_timer, strength, health
     char *id = get_json_value("id", json);
     char *_index = get_json_value("index", json);
     //
-    char *size = get_json_value("size", json);
-    char *size_x = get_json_value("width", size);
-    char *size_y = get_json_value("height", size);
-    //
     char *start_position = get_json_value("start_position", json);
     char *start_position_x = get_json_value("x", start_position);
     char *start_position_y = get_json_value("y", start_position);
@@ -615,7 +606,7 @@ void spawn_enemy_json(Level *level, GameManager *manager, char *json)
     char *health = get_json_value("health", json);
     //
 
-    if (!id || !_index || !size_x || !size_y || !start_position_x || !start_position_y || !end_position_x || !end_position_y || !move_timer || !speed || !attack_timer || !strength || !health)
+    if (!id || !_index || !start_position || !start_position_x || !start_position_y || !end_position || !end_position_x || !end_position_y || !move_timer || !speed || !attack_timer || !strength || !health)
     {
         FURI_LOG_E("Game", "Failed to parse JSON values");
         return;
@@ -628,7 +619,6 @@ void spawn_enemy_json(Level *level, GameManager *manager, char *json)
                                                                                        manager,
                                                                                        id,
                                                                                        atoi(_index),
-                                                                                       (Vector){strtod(size_x, NULL), strtod(size_y, NULL)},
                                                                                        (Vector){strtod(start_position_x, NULL), strtod(start_position_y, NULL)},
                                                                                        (Vector){strtod(end_position_x, NULL), strtod(end_position_y, NULL)},
                                                                                        strtod(move_timer, NULL),
@@ -641,9 +631,6 @@ void spawn_enemy_json(Level *level, GameManager *manager, char *json)
 
     free(id);
     free(_index);
-    free(size);
-    free(size_x);
-    free(size_y);
     free(start_position);
     free(start_position_x);
     free(start_position_y);
@@ -678,10 +665,6 @@ void spawn_enemy_json_furi(Level *level, GameManager *manager, FuriString *json)
     FuriString *id = get_json_value_furi("id", json);
     FuriString *_index = get_json_value_furi("index", json);
     //
-    FuriString *size = get_json_value_furi("size", json);
-    FuriString *size_x = get_json_value_furi("width", size);
-    FuriString *size_y = get_json_value_furi("height", size);
-    //
     FuriString *start_position = get_json_value_furi("start_position", json);
     FuriString *start_position_x = get_json_value_furi("x", start_position);
     FuriString *start_position_y = get_json_value_furi("y", start_position);
@@ -697,7 +680,7 @@ void spawn_enemy_json_furi(Level *level, GameManager *manager, FuriString *json)
     FuriString *health = get_json_value_furi("health", json);
     //
 
-    if (!id || !_index || !size_x || !size_y || !start_position_x || !start_position_y || !end_position_x || !end_position_y || !move_timer || !speed || !attack_timer || !strength || !health)
+    if (!id || !_index || !start_position || !start_position_x || !start_position_y || !end_position || !end_position_x || !end_position_y || !move_timer || !speed || !attack_timer || !strength || !health)
     {
         FURI_LOG_E("Game", "Failed to parse JSON values");
         return;
@@ -710,7 +693,6 @@ void spawn_enemy_json_furi(Level *level, GameManager *manager, FuriString *json)
                                                                                        manager,
                                                                                        furi_string_get_cstr(id),
                                                                                        atoi(furi_string_get_cstr(_index)),
-                                                                                       (Vector){strtod(furi_string_get_cstr(size_x), NULL), strtod(furi_string_get_cstr(size_y), NULL)},
                                                                                        (Vector){strtod(furi_string_get_cstr(start_position_x), NULL), strtod(furi_string_get_cstr(start_position_y), NULL)},
                                                                                        (Vector){strtod(furi_string_get_cstr(end_position_x), NULL), strtod(furi_string_get_cstr(end_position_y), NULL)},
                                                                                        strtod(furi_string_get_cstr(move_timer), NULL),
@@ -723,9 +705,6 @@ void spawn_enemy_json_furi(Level *level, GameManager *manager, FuriString *json)
 
     furi_string_free(id);
     furi_string_free(_index);
-    furi_string_free(size);
-    furi_string_free(size_x);
-    furi_string_free(size_y);
     furi_string_free(start_position);
     furi_string_free(start_position_x);
     furi_string_free(start_position_y);

+ 1 - 2
game/enemy.h

@@ -47,10 +47,9 @@ const EntityDescription *enemy(
     GameManager *manager,
     const char *id,
     int index,
-    Vector size,
     Vector start_position,
     Vector end_position,
-    float move_timer,
+    float move_timer, // Wait duration before moving again
     float speed,
     float attack_timer,
     float strength,

+ 2 - 2
game/icon.c

@@ -114,7 +114,7 @@ const EntityDescription icon_desc = {
     .context_size = sizeof(IconContext),
 };
 
-IconContext *icon_generic_alloc(const char *id, const Icon *icon, uint8_t width, uint8_t height)
+static IconContext *icon_generic_alloc(const char *id, const Icon *icon, uint8_t width, uint8_t height)
 {
     IconContext *ctx = malloc(sizeof(IconContext));
     if (!ctx)
@@ -262,7 +262,7 @@ IconContext *get_icon_context(const char *name)
     return NULL;
 }
 
-IconContext *get_icon_context_furi(FuriString *name)
+IconContext *get_icon_context_furi(const FuriString *name)
 {
     if (furi_string_cmp(name, "earth") == 0)
     {

+ 1 - 1
game/icon.h

@@ -12,5 +12,5 @@ typedef struct
 
 extern const EntityDescription icon_desc;
 IconContext *get_icon_context(const char *name);
-IconContext *get_icon_context_furi(FuriString *name);
+IconContext *get_icon_context_furi(const FuriString *name);
 const char *icon_get_id(const Icon *icon);

+ 4 - 4
game/level.c

@@ -12,14 +12,14 @@ void set_world(Level *level, GameManager *manager, char *id)
     if (!json_data_str || furi_string_empty(json_data_str))
     {
         FURI_LOG_E("Game", "Failed to load json data from file");
-        draw_tree_world(level);
+        draw_town_world(level);
         return;
     }
 
     if (!draw_json_world_furi(level, json_data_str))
     {
         FURI_LOG_E("Game", "Failed to draw world");
-        draw_tree_world(level);
+        draw_town_world(level);
         furi_string_free(json_data_str);
     }
     else
@@ -33,7 +33,7 @@ void set_world(Level *level, GameManager *manager, char *id)
         if (!enemy_data_str || furi_string_empty(enemy_data_str))
         {
             FURI_LOG_E("Game", "Failed to get enemy data");
-            draw_tree_world(level);
+            draw_town_world(level);
             return;
         }
         // Loop through the array
@@ -73,7 +73,7 @@ static void level_start(Level *level, GameManager *manager, void *context)
         if (!world_data)
         {
             FURI_LOG_E("Game", "Failed to fetch world data");
-            draw_tree_world(level);
+            draw_town_world(level);
             return;
         }
         furi_string_free(world_data);

+ 64 - 0
game/player.c

@@ -207,3 +207,67 @@ const EntityDescription player_desc = {
     .event = NULL,                         // called when entity receives an event
     .context_size = sizeof(PlayerContext), // size of entity context, will be automatically allocated and freed
 };
+
+static SpriteContext *sprite_generic_alloc(const char *id, uint8_t width, uint8_t height)
+{
+    SpriteContext *ctx = malloc(sizeof(SpriteContext));
+    if (!ctx)
+    {
+        FURI_LOG_E("Game", "Failed to allocate SpriteContext");
+        return NULL;
+    }
+    snprintf(ctx->id, sizeof(ctx->id), "%s", id);
+    ctx->width = width;
+    ctx->height = height;
+    snprintf(ctx->right_file_name, sizeof(ctx->right_file_name), "player_right_%s_%dx%dpx.fxbm", id, width, height);
+    snprintf(ctx->left_file_name, sizeof(ctx->left_file_name), "player_left_%s_%dx%dpx.fxbm", id, width, height);
+    return ctx;
+}
+
+SpriteContext *get_sprite_context(const char *name)
+{
+    if (strcmp(name, "axe") == 0)
+    {
+        return sprite_generic_alloc("axe", 15, 11);
+    }
+    else if (strcmp(name, "bow") == 0)
+    {
+        return sprite_generic_alloc("bow", 13, 11);
+    }
+    else if (strcmp(name, "naked") == 0)
+    {
+        return sprite_generic_alloc("naked", 10, 10);
+    }
+    else if (strcmp(name, "sword") == 0)
+    {
+        return sprite_generic_alloc("sword", 15, 11);
+    }
+
+    // If no match is found
+    FURI_LOG_E("Game", "Sprite not found: %s", name);
+    return NULL;
+}
+
+SpriteContext *get_sprite_context_furi(const FuriString *name)
+{
+    if (furi_string_cmp(name, "axe") == 0)
+    {
+        return sprite_generic_alloc("axe", 15, 11);
+    }
+    else if (furi_string_cmp(name, "bow") == 0)
+    {
+        return sprite_generic_alloc("bow", 13, 11);
+    }
+    else if (furi_string_cmp(name, "naked") == 0)
+    {
+        return sprite_generic_alloc("naked", 10, 10);
+    }
+    else if (furi_string_cmp(name, "sword") == 0)
+    {
+        return sprite_generic_alloc("sword", 15, 11);
+    }
+
+    // If no match is found
+    FURI_LOG_E("Game", "Sprite not found: %s", furi_string_get_cstr(name));
+    return NULL;
+}

+ 12 - 1
game/player.h

@@ -60,5 +60,16 @@ typedef struct
     int current_level;
 } GameContext;
 
+typedef struct
+{
+    char id[16];
+    char left_file_name[64];
+    char right_file_name[64];
+    uint8_t width;
+    uint8_t height;
+} SpriteContext;
+
 extern const EntityDescription player_desc;
-void player_spawn(Level *level, GameManager *manager);
+void player_spawn(Level *level, GameManager *manager);
+SpriteContext *get_sprite_context(const char *name);
+SpriteContext *get_sprite_context_furi(const FuriString *name);

+ 21 - 21
game/world.c

@@ -214,25 +214,25 @@ void draw_town_world(Level *level)
 {
 
     // house-fence group 1
-    spawn_icon(level, "house", 148, 36);
-    spawn_icon(level, "fence", 148, 72);
-    spawn_icon(level, "fence", 164, 72);
-    spawn_icon(level, "fence_end", 180, 72);
+    spawn_icon(level, "house", 164, 40);
+    spawn_icon(level, "fence", 148, 64);
+    spawn_icon(level, "fence", 164, 64);
+    spawn_icon(level, "fence_end", 180, 64);
 
     // house-fence group 4 (the left of group 1)
-    spawn_icon(level, "house", 96, 36);
-    spawn_icon(level, "fence", 96, 72);
-    spawn_icon(level, "fence", 110, 72);
-    spawn_icon(level, "fence_end", 126, 72);
+    spawn_icon(level, "house", 110, 40);
+    spawn_icon(level, "fence", 96, 64);
+    spawn_icon(level, "fence", 110, 64);
+    spawn_icon(level, "fence_end", 126, 64);
 
     // house-fence group 5 (the left of group 4)
-    spawn_icon(level, "house", 40, 36);
-    spawn_icon(level, "fence", 40, 72);
-    spawn_icon(level, "fence", 56, 72);
-    spawn_icon(level, "fence_end", 72, 72);
+    spawn_icon(level, "house", 56, 40);
+    spawn_icon(level, "fence", 40, 64);
+    spawn_icon(level, "fence", 56, 64);
+    spawn_icon(level, "fence_end", 72, 64);
 
     // line of fences on the 8th row (using spawn_icon_line)
-    spawn_icon_line(level, "fence", 8, 100, 10, true);
+    spawn_icon_line(level, "fence", 8, 96, 10, true);
 
     // plants spaced out underneath the fences
     spawn_icon_line(level, "plant", 40, 110, 6, true);
@@ -244,18 +244,18 @@ void draw_town_world(Level *level)
 
     // lake
     // Top row
-    spawn_icon(level, "lake_top_left", 240, 52);
-    spawn_icon(level, "lake_top", 264, 52);
-    spawn_icon(level, "lake_top_right", 295, 52);
+    spawn_icon(level, "lake_top_left", 240, 62);
+    spawn_icon(level, "lake_top", 264, 57);
+    spawn_icon(level, "lake_top_right", 295, 62);
 
     // Middle row
-    spawn_icon(level, "lake_left", 231, 74);
-    spawn_icon(level, "lake_right", 317, 74);
+    spawn_icon(level, "lake_left", 231, 84);
+    spawn_icon(level, "lake_right", 304, 84);
 
     // Bottom row
-    spawn_icon(level, "lake_bottom_left", 240, 105);
-    spawn_icon(level, "lake_bottom", 264, 124);
-    spawn_icon(level, "lake_bottom_right", 295, 105);
+    spawn_icon(level, "lake_bottom_left", 240, 115);
+    spawn_icon(level, "lake_bottom", 264, 120);
+    spawn_icon(level, "lake_bottom_right", 295, 115);
 
     // Spawn two full left/up tree lines
     for (int i = 0; i < 2; i++)