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

in-game menu + new controls

HOLD OK for menu, PRESS BACK to close the menu, and HOLD BACK to leave the game
jblanked 1 год назад
Родитель
Сommit
8ad58acdac
5 измененных файлов с 89 добавлено и 27 удалено
  1. 3 0
      flip_world.h
  2. 12 1
      game/enemy.c
  3. 0 2
      game/game.c
  4. 68 23
      game/player.c
  5. 6 1
      game/player.h

+ 3 - 0
flip_world.h

@@ -6,6 +6,9 @@
 // added by Derek Jamison to lower memory usage
 // added by Derek Jamison to lower memory usage
 #undef FURI_LOG_E
 #undef FURI_LOG_E
 #define FURI_LOG_E(tag, msg, ...)
 #define FURI_LOG_E(tag, msg, ...)
+
+// #undef FURI_LOG_I
+// #define FURI_LOG_I(tag, msg, ...)
 //
 //
 
 
 #define TAG "FlipWorld"
 #define TAG "FlipWorld"

+ 12 - 1
game/enemy.c

@@ -156,6 +156,16 @@ static void enemy_render(Entity *self, GameManager *manager, Canvas *canvas, voi
             0,
             0,
             &I_icon_world_change_128x64px);
             &I_icon_world_change_128x64px);
     }
     }
+
+    if (game_context->is_menu_open)
+    {
+        // draw menu icon
+        canvas_draw_icon(
+            canvas,
+            0,
+            0,
+            &I_icon_menu_128x64px);
+    }
 }
 }
 
 
 static void send_attack_notification(GameContext *game_context, EnemyContext *enemy_context, bool player_attacked)
 static void send_attack_notification(GameContext *game_context, EnemyContext *enemy_context, bool player_attacked)
@@ -234,6 +244,7 @@ static void enemy_collision(Entity *self, Entity *other, GameManager *manager, v
         // Retrieve enemy context
         // Retrieve enemy context
         EnemyContext *enemy_context = (EnemyContext *)context;
         EnemyContext *enemy_context = (EnemyContext *)context;
         GameContext *game_context = game_manager_game_context_get(manager);
         GameContext *game_context = game_manager_game_context_get(manager);
+        // InputState input = game_manager_input_get(manager);
         if (!enemy_context)
         if (!enemy_context)
         {
         {
             FURI_LOG_E("Game", "Enemy collision: EnemyContext is NULL");
             FURI_LOG_E("Game", "Enemy collision: EnemyContext is NULL");
@@ -272,7 +283,7 @@ static void enemy_collision(Entity *self, Entity *other, GameManager *manager, v
         }
         }
 
 
         // Handle Player Attacking Enemy (Press OK, facing enemy, and enemy not facing player)
         // Handle Player Attacking Enemy (Press OK, facing enemy, and enemy not facing player)
-        if (player_is_facing_enemy && game_context->user_input == GameKeyOk && !enemy_is_facing_player)
+        if (player_is_facing_enemy && game_context->last_button == GameKeyOk && !enemy_is_facing_player)
         {
         {
             if (game_context->player_context->elapsed_attack_timer >= game_context->player_context->attack_timer)
             if (game_context->player_context->elapsed_attack_timer >= game_context->player_context->attack_timer)
             {
             {

+ 0 - 2
game/game.c

@@ -30,12 +30,10 @@ static void game_start(GameManager *game_manager, void *ctx)
         {
         {
             if (i == 0)
             if (i == 0)
             {
             {
-                FURI_LOG_E("Game", "Failed to allocate level %d, loading default level", i);
                 game_context->levels[0] = game_manager_add_level(game_manager, generic_level("town_world_v2", 0));
                 game_context->levels[0] = game_manager_add_level(game_manager, generic_level("town_world_v2", 0));
                 game_context->level_count = 1;
                 game_context->level_count = 1;
                 break;
                 break;
             }
             }
-            FURI_LOG_E("Game", "No more levels to load");
             break;
             break;
         }
         }
         game_context->level_count++;
         game_context->level_count++;

+ 68 - 23
game/player.c

@@ -255,43 +255,61 @@ static void player_update(Entity *self, GameManager *manager, void *context)
     // Handle movement input
     // Handle movement input
     if (input.held & GameKeyUp)
     if (input.held & GameKeyUp)
     {
     {
+        if (game_context->last_button == GameKeyUp)
+            game_context->elapsed_button_timer += 1;
+        else
+            game_context->elapsed_button_timer = 0;
+
         pos.y -= 2;
         pos.y -= 2;
         player->dy = -1;
         player->dy = -1;
         player->direction = PLAYER_UP;
         player->direction = PLAYER_UP;
-        game_context->user_input = GameKeyUp;
+        game_context->last_button = GameKeyUp;
     }
     }
     if (input.held & GameKeyDown)
     if (input.held & GameKeyDown)
     {
     {
+        if (game_context->last_button == GameKeyDown)
+            game_context->elapsed_button_timer += 1;
+        else
+            game_context->elapsed_button_timer = 0;
+
         pos.y += 2;
         pos.y += 2;
         player->dy = 1;
         player->dy = 1;
         player->direction = PLAYER_DOWN;
         player->direction = PLAYER_DOWN;
-        game_context->user_input = GameKeyDown;
+        game_context->last_button = GameKeyDown;
     }
     }
     if (input.held & GameKeyLeft)
     if (input.held & GameKeyLeft)
     {
     {
+        if (game_context->last_button == GameKeyLeft)
+            game_context->elapsed_button_timer += 1;
+        else
+            game_context->elapsed_button_timer = 0;
+
         pos.x -= 2;
         pos.x -= 2;
         player->dx = -1;
         player->dx = -1;
         player->direction = PLAYER_LEFT;
         player->direction = PLAYER_LEFT;
-        game_context->user_input = GameKeyLeft;
+        game_context->last_button = GameKeyLeft;
     }
     }
     if (input.held & GameKeyRight)
     if (input.held & GameKeyRight)
     {
     {
+        if (game_context->last_button == GameKeyRight)
+            game_context->elapsed_button_timer += 1;
+        else
+            game_context->elapsed_button_timer = 0;
+
         pos.x += 2;
         pos.x += 2;
         player->dx = 1;
         player->dx = 1;
         player->direction = PLAYER_RIGHT;
         player->direction = PLAYER_RIGHT;
-        game_context->user_input = GameKeyRight;
+        game_context->last_button = GameKeyRight;
     }
     }
+    if (input.held & GameKeyOk)
+    {
+        if (game_context->last_button == GameKeyOk)
+            game_context->elapsed_button_timer += 1;
+        else
+            game_context->elapsed_button_timer = 0;
 
 
-    // Clamp the player's position to stay within world bounds
-    pos.x = CLAMP(pos.x, WORLD_WIDTH - 5, 5);
-    pos.y = CLAMP(pos.y, WORLD_HEIGHT - 5, 5);
+        game_context->last_button = GameKeyOk;
 
 
-    // Update player position
-    entity_pos_set(self, pos);
-
-    // switch levels if holding OK
-    if (input.pressed & GameKeyOk)
-    {
         // if all enemies are dead, allow the "OK" button to switch levels
         // if all enemies are dead, allow the "OK" button to switch levels
         // otherwise the "OK" button will be used to attack
         // otherwise the "OK" button will be used to attack
         if (game_context->enemy_count == 0 && !game_context->is_switching_level)
         if (game_context->enemy_count == 0 && !game_context->is_switching_level)
@@ -301,31 +319,58 @@ static void player_update(Entity *self, GameManager *manager, void *context)
             game_manager_next_level_set(manager, get_next_level(manager));
             game_manager_next_level_set(manager, get_next_level(manager));
             return;
             return;
         }
         }
-        else if (game_context->enemy_count > 0)
+
+        // if the OK button is held for 1 seconds,show the menu
+        if (game_context->elapsed_button_timer > (1 * game_context->fps))
+        {
+            game_context->is_menu_open = true;
+            FURI_LOG_I(TAG, "Menu opened");
+        }
+    }
+    if (input.held & GameKeyBack)
+    {
+        if (game_context->last_button == GameKeyBack)
+            game_context->elapsed_button_timer += 1;
+        else
+            game_context->elapsed_button_timer = 0;
+
+        game_context->last_button = GameKeyBack;
+
+        if (game_context->is_menu_open)
+        {
+            game_context->is_menu_open = false;
+            FURI_LOG_I(TAG, "Menu closed");
+        }
+
+        // if the back button is held for 2 seconds, stop the game
+        if (game_context->elapsed_button_timer > (2 * game_context->fps))
         {
         {
-            game_context->user_input = GameKeyOk;
-            // furi_delay_ms(100);
+            if (!game_context->is_menu_open)
+            {
+                game_manager_game_stop(manager);
+                return;
+            }
         }
         }
     }
     }
 
 
+    // Clamp the player's position to stay within world bounds
+    pos.x = CLAMP(pos.x, WORLD_WIDTH - 5, 5);
+    pos.y = CLAMP(pos.y, WORLD_HEIGHT - 5, 5);
+
+    // Update player position
+    entity_pos_set(self, pos);
+
     // If the player is not moving, retain the last movement direction
     // If the player is not moving, retain the last movement direction
     if (player->dx == 0 && player->dy == 0)
     if (player->dx == 0 && player->dy == 0)
     {
     {
         player->dx = prev_dx;
         player->dx = prev_dx;
         player->dy = prev_dy;
         player->dy = prev_dy;
         player->state = PLAYER_IDLE;
         player->state = PLAYER_IDLE;
-        game_context->user_input = -1; // reset user input
     }
     }
     else
     else
     {
     {
         player->state = PLAYER_MOVING;
         player->state = PLAYER_MOVING;
     }
     }
-
-    // Handle back button to stop the game
-    if (input.pressed & GameKeyBack)
-    {
-        game_manager_game_stop(manager);
-    }
 }
 }
 
 
 static void player_render(Entity *self, GameManager *manager, Canvas *canvas, void *context)
 static void player_render(Entity *self, GameManager *manager, Canvas *canvas, void *context)

+ 6 - 1
game/player.h

@@ -52,7 +52,6 @@ typedef struct
     Level *levels[MAX_LEVELS];
     Level *levels[MAX_LEVELS];
     Entity *enemies[MAX_ENEMIES];
     Entity *enemies[MAX_ENEMIES];
     Entity *player;
     Entity *player;
-    GameKey user_input;
     float fps;
     float fps;
     int level_count;
     int level_count;
     int enemy_count;
     int enemy_count;
@@ -60,7 +59,13 @@ typedef struct
     bool ended_early;
     bool ended_early;
     Imu *imu;
     Imu *imu;
     bool imu_present;
     bool imu_present;
+    //
     bool is_switching_level;
     bool is_switching_level;
+    bool is_menu_open;
+    //
+    uint32_t elapsed_button_timer;
+    uint32_t last_button;
+    uint32_t button_cooldown;
 } GameContext;
 } GameContext;
 
 
 typedef struct
 typedef struct