Ivan Barsukov 1 год назад
Родитель
Сommit
4b2a9d1542
3 измененных файлов с 46 добавлено и 143 удалено
  1. 3 0
      src/game.h
  2. 41 139
      src/levels/level_game/level_game.c
  3. 2 4
      src/levels/level_game/level_game.h

+ 3 - 0
src/game.h

@@ -4,6 +4,9 @@
 
 #include "engine/engine.h" // IWYU pragma: keep
 
+#define SCREEN_WIDTH 128
+#define SCREEN_HEIGHT 64
+
 #define GAME_NAME "Quadrastic"
 
 typedef enum

+ 41 - 139
src/levels/level_game/level_game.c

@@ -5,154 +5,62 @@
 #include <m-list.h>
 
 #include <dolphin/dolphin.h>
-#include <notification/notification_messages.h>
 
-#include "../../engine/vector.h"
-
-#include "../../game.h"
-#include "../../game_notifications.h"
+#include "src/game.h"
 
 #include "context_menu.h"
 
-#include "enemy_entity.h"
 #include "player_entity.h"
-
-#define TARGET_ANIMATION_DURATION 30.0f
-#define TARGET_SIZE 1
-#define TARGET_RADIUS 1
-#define TARGET_ANIMATION_RADIUS 10
-
-static Vector
-random_pos(void)
-{
-    return (Vector){ rand() % 120 + 4, rand() % 58 + 4 };
-}
-
-/****** Entities: Target ******/
-
-typedef struct
-{
-    Sprite* sprite;
-    float time;
-} TargetContext;
-
-static const EntityDescription target_description;
-
-static Entity*
-create_target(Level* level, GameManager* manager)
-{
-    Entity* target = level_add_entity(level, &target_description);
-
-    // Set target position
-    entity_pos_set(target, random_pos());
-
-    // Add collision circle to target entity
-    entity_collider_add_circle(target, TARGET_RADIUS);
-
-    // Load target sprite
-    TargetContext* target_context = entity_context_get(target);
-    target_context->sprite = game_manager_sprite_load(manager, "target.fxbm");
-
-    return target;
-}
+#include "target_entity.h"
 
 static void
-reset_target(Entity* target)
+on_resume_clicked(void* context, uint32_t index)
 {
-    // Set player position.
-    entity_pos_set(target, random_pos());
-
-    // Reset animation
-    TargetContext* target_context = entity_context_get(target);
-    target_context->time = 0.0f;
+    UNUSED(index);
+    resume_game(context);
 }
 
 static void
-target_update(Entity* self, GameManager* manager, void* context)
+on_menu_clicked(void* context, uint32_t index)
 {
-    UNUSED(self);
-    UNUSED(manager);
-
-    // Start level animation
-    TargetContext* target = context;
-    if (target->time >= TARGET_ANIMATION_DURATION) {
-        return;
-    }
-    target->time += 1.0f;
-}
-
-static void
-target_render(Entity* self, GameManager* manager, Canvas* canvas, void* context)
-{
-    UNUSED(context);
-    UNUSED(manager);
-
-    // Get target position
-    Vector pos = entity_pos_get(self);
-
-    TargetContext* target = context;
-    if (target->time < TARGET_ANIMATION_DURATION) {
-        float step = TARGET_ANIMATION_RADIUS / TARGET_ANIMATION_DURATION;
-        float radius = CLAMP(TARGET_ANIMATION_RADIUS - target->time * step,
-                             TARGET_ANIMATION_RADIUS,
-                             TARGET_RADIUS);
-        canvas_draw_circle(canvas, pos.x, pos.y, radius);
-        canvas_draw_dot(canvas, pos.x, pos.y);
-        return;
-    }
-
-    // Draw target
-    TargetContext* target_context = entity_context_get(self);
-    canvas_draw_sprite(canvas, target_context->sprite, pos.x - 1, pos.y - 1);
+    UNUSED(index);
+    GameManager* manager = context;
+    GameContext* game_context = game_manager_game_context_get(manager);
+    game_manager_next_level_set(manager, game_context->levels.menu);
 }
 
 static void
-target_collision(Entity* self,
-                 Entity* other,
-                 GameManager* manager,
-                 void* context)
+on_quit_clicked(void* context, uint32_t index)
 {
-    UNUSED(context);
-
-    if (entity_description_get(other) != &player_description) {
-        return;
-    }
-
-    // Increase score
-    GameContext* game_context = game_manager_game_context_get(manager);
-    ++game_context->score;
-
-    // Move target to new random position
-    reset_target(self);
-    spawn_enemy(manager);
-
-    // Notify
-    game_notify(game_context, &sequence_earn_point);
+    UNUSED(index);
+    GameManager* manager = context;
+    game_manager_game_stop(manager);
 }
 
-static const EntityDescription target_description = {
-    .start = NULL,
-    .stop = NULL,
-    .update = target_update,
-    .render = target_render,
-    .collision = target_collision,
-    .event = NULL,
-    .context_size = sizeof(TargetContext),
-};
-
-/***** Level *****/
-
 static void
-level_game_alloc(Level* level, GameManager* manager, void* context)
+level_game_alloc(Level* level, GameManager* manager, void* _level_context)
 {
-    GameLevelContext* level_context = context;
+    GameLevelContext* level_context = _level_context;
 
     // Add entities to the level
     level_context->player = player_spawn(level, manager);
     level_context->target = create_target(level, manager);
     EntityList_init(level_context->enemies);
+
+    // Pause menu initialization
     level_context->is_paused = false;
-    level_context->pause_menu = NULL;
+    level_context->pause_menu =
+      level_add_entity(level, &context_menu_description);
+
+    context_menu_add_item(
+      level_context->pause_menu, "Resume", 0, on_resume_clicked, level);
+    context_menu_add_item(
+      level_context->pause_menu, "Menu", 1, on_menu_clicked, manager);
+    context_menu_add_item(
+      level_context->pause_menu, "Quit", 2, on_quit_clicked, manager);
+
+    context_menu_back_callback_set(
+      level_context->pause_menu, (ContextMenuBackCallback)resume_game, level);
 }
 
 static void
@@ -167,21 +75,24 @@ level_game_start(Level* level, GameManager* manager, void* context)
 
     GameLevelContext* level_context = context;
     player_respawn(level_context->player);
-    reset_target(level_context->target);
+    target_reset(level_context->target, manager);
 
     FURI_LOG_D(GAME_NAME, "Game level started");
 }
 
 static void
-level_game_stop(Level* level, GameManager* manager, void* context)
+level_game_stop(Level* level, GameManager* manager, void* _level_context)
 {
     UNUSED(manager);
 
-    GameLevelContext* level_context = context;
-    FOREACH(item, level_context->enemies)
-    {
-        level_remove_entity(level, *item);
-    }
+    GameLevelContext* level_context = _level_context;
+
+    // Clear enemies
+    for
+        M_EACH(item, level_context->enemies, EntityList_t)
+        {
+            level_remove_entity(level, *item);
+        }
     EntityList_clear(level_context->enemies);
 
     resume_game(level);
@@ -196,23 +107,14 @@ pause_game(Level* level)
     }
 
     level_context->is_paused = true;
-    level_context->pause_menu =
-      level_add_entity(level, &context_menu_description);
-    context_menu_back_callback_set(
-      level_context->pause_menu, (ContextMenuBackCallback)resume_game, level);
+    context_menu_reset_state(level_context->pause_menu);
 }
 
 void
 resume_game(Level* level)
 {
     GameLevelContext* level_context = level_context_get(level);
-    if (!level_context->is_paused) {
-        return;
-    }
-
     level_context->is_paused = false;
-    level_remove_entity(level, level_context->pause_menu);
-    level_context->pause_menu = NULL;
 }
 
 const LevelBehaviour level_game = {

+ 2 - 4
src/levels/level_game/level_game.h

@@ -2,21 +2,19 @@
 
 #include <m-list.h>
 
-#include "../../engine/level.h"
+#include "src/engine/level.h"
 
 LIST_DEF(EntityList, Entity*, M_POD_OPLIST);
 #define M_OPL_EntityList_t() LIST_OPLIST(EntityList)
-#define FOREACH(name, list) for                                                \
-    M_EACH(name, list, EntityList_t)
 
 typedef struct
 {
+    Entity* pause_menu;
     Entity* player;
     Entity* target;
     EntityList_t enemies;
 
     bool is_paused;
-    Entity* pause_menu;
 
 } GameLevelContext;