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

Add FlipSocial's icon as the character

jblanked 1 год назад
Родитель
Сommit
12b730dbf5
9 измененных файлов с 54 добавлено и 17 удалено
  1. BIN
      assets/sprites/player_left.fxbm
  2. 0 0
      assets/sprites/player_right.fxbm
  3. 1 1
      game/draw.c
  4. 29 5
      game/game.c
  5. 10 5
      game/game.h
  6. 12 6
      game/icon.c
  7. 2 0
      game/icon.h
  8. BIN
      sprites/player_left.png
  9. 0 0
      sprites/player_right.png

BIN
assets/sprites/player_left.fxbm


+ 0 - 0
assets/sprites/player.fxbm → assets/sprites/player_right.fxbm


+ 1 - 1
game/draw.c

@@ -73,7 +73,7 @@ void spawn_icon(Level *level, const Icon *icon, float x, float y, uint8_t width,
     icon_ctx->width = width;
     icon_ctx->height = height;
     // Set the entity position to the center of the icon
-    entity_pos_set(e, (Vector){x + 8, y + 8});
+    entity_pos_set(e, (Vector){x + (width / 2), y + (height / 2)});
 }
 // Draw a line of icons at a specific position (with collision detection)
 void spawn_icon_line(Level *level, const Icon *icon, float x, float y, uint8_t width, uint8_t height, uint8_t amount, bool horizontal)

+ 29 - 5
game/game.c

@@ -14,13 +14,15 @@ static void player_spawn(Level *level, GameManager *manager)
 
     // Add collision box to player entity
     // Box is centered in player x and y, and it's size is 10x10
-    entity_collider_add_rect(player, 10, 10);
+    entity_collider_add_rect(player, 10 + PLAYER_COLLISION_HORIZONTAL, 10 + PLAYER_COLLISION_VERTICAL);
 
     // Get player context
     PlayerContext *player_context = entity_context_get(player);
 
     // Load player sprite
-    player_context->sprite = game_manager_sprite_load(manager, "player.fxbm");
+    player_context->sprite_right = game_manager_sprite_load(manager, "player_right.fxbm");
+    player_context->sprite_left = game_manager_sprite_load(manager, "player_left.fxbm");
+    player_context->is_looking_left = false; // player starts looking right
 }
 
 // Modify player_update to track direction
@@ -30,10 +32,15 @@ static void player_update(Entity *self, GameManager *manager, void *context)
     InputState input = game_manager_input_get(manager);
     Vector pos = entity_pos_get(self);
 
-    // Reset direction each frame
+    // Store previous direction
+    int prev_dx = player->dx;
+    int prev_dy = player->dy;
+
+    // Reset movement deltas each frame
     player->dx = 0;
     player->dy = 0;
 
+    // Handle movement input
     if (input.held & GameKeyUp)
     {
         pos.y -= 2;
@@ -48,18 +55,30 @@ static void player_update(Entity *self, GameManager *manager, void *context)
     {
         pos.x -= 2;
         player->dx = -1;
+        player->is_looking_left = true;
     }
     if (input.held & GameKeyRight)
     {
         pos.x += 2;
         player->dx = 1;
+        player->is_looking_left = false;
     }
 
+    // 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 (player->dx == 0 && player->dy == 0)
+    {
+        player->dx = prev_dx;
+        player->dy = prev_dy;
+    }
+
+    // Handle back button to stop the game
     if (input.pressed & GameKeyBack)
     {
         game_manager_game_stop(manager);
@@ -78,8 +97,13 @@ static void player_render(Entity *self, GameManager *manager, Canvas *canvas, vo
     // Draw background (updates camera_x and camera_y)
     draw_background(canvas, pos);
 
-    // Draw player sprite relative to camera
-    canvas_draw_sprite(canvas, player->sprite, pos.x - camera_x - 5, pos.y - camera_y - 5);
+    // Draw player sprite relative to camera, centered on the player's position
+    canvas_draw_sprite(
+        canvas,
+        player->is_looking_left ? player->sprite_left : player->sprite_right,
+        pos.x - camera_x - 5, // Center the sprite horizontally
+        pos.y - camera_y - 5  // Center the sprite vertically
+    );
 }
 
 const EntityDescription player_desc = {

+ 10 - 5
game/game.h

@@ -4,6 +4,9 @@
 #include "flip_world.h"
 #include "flip_storage/storage.h"
 
+#define PLAYER_COLLISION_VERTICAL 5
+#define PLAYER_COLLISION_HORIZONTAL 5
+
 typedef struct
 {
     uint32_t score;
@@ -11,11 +14,13 @@ typedef struct
 
 typedef struct
 {
-    Vector trajectory; // Direction player would like to move.
-    float radius;      // collision radius
-    int8_t dx;         // x direction
-    int8_t dy;         // y direction
-    Sprite *sprite;    // player sprite
+    Vector trajectory;    // Direction player would like to move.
+    float radius;         // collision radius
+    int8_t dx;            // x direction
+    int8_t dy;            // y direction
+    Sprite *sprite_right; // player sprite
+    Sprite *sprite_left;  // player sprite looking left
+    bool is_looking_left; // player is looking left
 } PlayerContext;
 
 extern const EntityDescription player_desc;

+ 12 - 6
game/icon.c

@@ -39,16 +39,22 @@ static void icon_collision(Entity *self, Entity *other, GameManager *manager, vo
     UNUSED(self);
     IconContext *icon = (IconContext *)context;
     UNUSED(icon);
+
     if (entity_description_get(other) == &player_desc)
     {
         PlayerContext *player = (PlayerContext *)entity_context_get(other);
         if (player)
         {
             Vector pos = entity_pos_get(other);
-            // Bounce the player back by 3 units opposite their last movement direction
-            pos.x -= player->dx * 3;
-            pos.y -= player->dy * 3;
+
+            // Bounce the player back by 2 units opposite their last movement direction
+            pos.x -= player->dx * 2;
+            pos.y -= player->dy * 2;
             entity_pos_set(other, pos);
+
+            // Reset player's movement direction to prevent immediate re-collision
+            player->dx = 0;
+            player->dy = 0;
         }
     }
 }
@@ -58,15 +64,15 @@ static void icon_render(Entity *self, GameManager *manager, Canvas *canvas, void
     UNUSED(manager);
     IconContext *icon_ctx = (IconContext *)context;
     Vector pos = entity_pos_get(self);
-    canvas_draw_icon(canvas, pos.x - camera_x - 8, pos.y - camera_y - 8, icon_ctx->icon);
+    canvas_draw_icon(canvas, pos.x - camera_x - icon_ctx->width / 2, pos.y - camera_y - icon_ctx->height / 2, icon_ctx->icon);
 }
 
 static void icon_start(Entity *self, GameManager *manager, void *context)
 {
     UNUSED(manager);
-    UNUSED(context);
+    IconContext *icon_ctx = (IconContext *)context;
     // Just add the collision rectangle for 16x16 icon
-    entity_collider_add_rect(self, 16, 16);
+    entity_collider_add_rect(self, icon_ctx->width + COLLISION_BOX_PADDING_HORIZONTAL, icon_ctx->height + COLLISION_BOX_PADDING_VERTICAL);
 }
 
 const EntityDescription icon_desc = {

+ 2 - 0
game/icon.h

@@ -1,6 +1,8 @@
 #pragma once
 #include "flip_world_icons.h"
 #include "game.h"
+#define COLLISION_BOX_PADDING_HORIZONTAL 10
+#define COLLISION_BOX_PADDING_VERTICAL 12
 
 typedef struct
 {

BIN
sprites/player_left.png


+ 0 - 0
sprites/player.png → sprites/player_right.png