diff options
| author | BoredGuy <osome3717@gmail.com> | 2026-03-23 17:11:28 +0300 |
|---|---|---|
| committer | BoredGuy <osome3717@gmail.com> | 2026-03-23 17:11:28 +0300 |
| commit | 7c438c2a0e25d22323b5def545f32e97eee689f0 (patch) | |
| tree | a9e2cf29a967c88d022ea8e6c20a522a9c482610 | |
| parent | 6dbd16cd920b51bc24b60d0561bd707ff8862cc5 (diff) | |
Asset system
- Multiple entity updates
| -rw-r--r-- | CMakeLists.txt | 4 | ||||
| -rw-r--r-- | src/assets.c | 15 | ||||
| -rw-r--r-- | src/assets.h | 7 | ||||
| -rw-r--r-- | src/constants.h | 6 | ||||
| -rw-r--r-- | src/entity.c | 52 | ||||
| -rw-r--r-- | src/entity.h | 5 | ||||
| -rw-r--r-- | src/main.c | 16 | ||||
| -rw-r--r-- | src/player.c | 172 | ||||
| -rw-r--r-- | src/player.h | 11 | ||||
| -rw-r--r-- | src/utils.c | 14 | ||||
| -rw-r--r-- | src/utils.h | 6 | ||||
| -rw-r--r-- | src/wall.c | 33 | ||||
| -rw-r--r-- | src/wall.h | 3 |
13 files changed, 258 insertions, 86 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c31b68..69e8131 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,8 @@ add_executable(game "src/game.h" "src/player.h" "src/wall.h" + "src/utils.h" + "src/assets.h" #===========SOURCES=============== "src/settings.c" "src/main.c" @@ -20,6 +22,8 @@ add_executable(game "src/game.c" "src/player.c" "src/wall.c" + "src/utils.c" + "src/assets.c" ) target_link_libraries(game PRIVATE raylib) diff --git a/src/assets.c b/src/assets.c new file mode 100644 index 0000000..d1402bd --- /dev/null +++ b/src/assets.c @@ -0,0 +1,15 @@ +#include <raylib.h> +#include "assets.h" + +Texture character_spritesheet; +Texture wall_texture; + +void load_assets() { + character_spritesheet = LoadTexture("assets/Graphics/spritesheet-characters-default.png"); + wall_texture = LoadTexture("assets/Graphics/spritesheet-tiles-double.png"); +} + +void unload_assets() { + UnloadTexture(character_spritesheet); + UnloadTexture(wall_texture); +} diff --git a/src/assets.h b/src/assets.h new file mode 100644 index 0000000..3977369 --- /dev/null +++ b/src/assets.h @@ -0,0 +1,7 @@ +#ifndef ASSETS_H_ +#define ASSETS_H_ + +void load_assets(); +void unload_assets(); + +#endif // ASSETS_H_ diff --git a/src/constants.h b/src/constants.h index 3fc36ff..4eca1ea 100644 --- a/src/constants.h +++ b/src/constants.h @@ -1,14 +1,14 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ -#define WINDOW_WIDTH 800 -#define WINDOW_HEIGHT 600 +#define WINDOW_WIDTH 1280 +#define WINDOW_HEIGHT 720 #define TARGET_FPS 60 #define MAX_ENTITY_COUNT 500 #define ENTITY_MAX_ANIMATIONS 10 #define ANIMATION_MAX_FRAMES 4 -#define GRAVITY 14 +#define GRAVITY 200 #endif diff --git a/src/entity.c b/src/entity.c index d737ea9..84ce609 100644 --- a/src/entity.c +++ b/src/entity.c @@ -29,10 +29,18 @@ Rectangle get_entity_dest_rect_world(const struct entity* entity) { void entity_handle_collision ( - struct entity*, - struct entity*, - enum direction + struct entity* self, + struct entity* other, + enum direction direction ) { + switch (self->type) { + case Player_Entity: + player_handle_collision(self, other, direction); + break; + + default: + break; + } } static inline bool entity_animated(const struct entity* e) { @@ -67,32 +75,38 @@ Rectangle animation_get_source_rect(const struct animation* animation) { } void draw_entity_default(const struct entity* entity) { + Rectangle source_rect; + if (entity_animated(entity)) { const struct animation* current_animation = &entity->animations[entity->current_animation]; - DrawTexturePro(entity->texture, - animation_get_source_rect(current_animation), - get_entity_dest_rect_world(entity), - (Vector2) {0.0, 0.0}, - 0, - WHITE); + source_rect = animation_get_source_rect(current_animation); } else { - DrawTexturePro(entity->texture, - entity->sprite_source_rect, - get_entity_dest_rect_world(entity), - (Vector2) {0.0, 0.0}, - 0, - WHITE); + source_rect = entity->sprite_source_rect; } + + if (entity->flip) { + source_rect.width *= -1; + } + + DrawTexturePro(entity->texture, + source_rect, + get_entity_dest_rect_world(entity), + (Vector2) {0.0, 0.0}, + 0, + WHITE); } void draw_entity(const struct entity* entity) { - switch (entity->type) { - case Wall_Entity: - draw_wall(entity); - break; + /* if (entity->flags & ENTITY_COLLISION_ACTIVE) { */ + /* DrawRectangleRec( */ + /* get_entity_collider_world(entity), */ + /* RED */ + /* ); */ + /* } */ + switch (entity->type) { default: draw_entity_default(entity); break; diff --git a/src/entity.h b/src/entity.h index 4807a2b..1698536 100644 --- a/src/entity.h +++ b/src/entity.h @@ -58,6 +58,11 @@ struct entity { struct animation animations[ENTITY_MAX_ANIMATIONS]; int current_animation; enum draw_layer draw_layer; + bool flip; + + //Player data + int player_state; + Vector2 start_position; }; void update_entity(struct entity* entity, float dt); @@ -4,6 +4,7 @@ #include "physics.h" #include "game.h" #include "wall.h" +#include "assets.h" #include "player.h" struct settings settings; @@ -11,13 +12,15 @@ extern struct game game; int main() { load_or_init_settings(&settings, "settings.ini"); - init_game(); InitWindow(settings.window_width, settings.window_height, "Platformer"); SetTargetFPS(settings.target_fps); - add_player(20.0, 20.0); - add_wall(50, 100, 200, 200); - add_wall(100, 200, 200, 50); + init_game(); + load_assets(); + + add_player(300.0, 200.0); + add_wall(50, 100); + add_wall(100, 200); while (!WindowShouldClose()) { update_game(GetFrameTime()); @@ -26,7 +29,10 @@ int main() { ClearBackground(RAYWHITE); draw_game(); EndDrawing(); + + DrawFPS(1, 1); } - + + unload_assets(); return 0; } diff --git a/src/player.c b/src/player.c index 0ab53cd..9e1a782 100644 --- a/src/player.c +++ b/src/player.c @@ -1,93 +1,169 @@ #include <raylib.h> #include <raymath.h> #include <math.h> +#include <stdio.h> +#include "utils.h" #include "physics.h" #include "player.h" -#include <stdio.h> + +#define PLAYER_WIDTH 128 +#define PLAYER_HEIGHT 128 + +#define COLLIDER_WIDTH 77 +#define COLLIDER_HEIGHT 98 +#define COLLIDER_XOFF 0 +#define COLLIDER_YOFF 14 #define TOP_SPEEDX 100 #define TOP_SPEEDY 100 -#define ACCEL_X 40 +#define ACCEL_X 200 + +extern Texture character_spritesheet; + +void add_player_animations(struct entity* player); void add_player(float xpos, float ypos) { struct entity player = { - .flags = (ENTITY_ACTIVE | ENTITY_COLLISION_ACTIVE | ENTITY_VISIBLE), + .flags = (ENTITY_ACTIVE | ENTITY_COLLISION_ACTIVE | ENTITY_VISIBLE | ENTITY_ANIMATED), .type = Player_Entity, .position = (Vector2) {xpos, ypos}, - .texture = LoadTexture("assets/Graphics/spritesheet-characters-double.png"), + .texture = character_spritesheet, .sprite_source_rect = (Rectangle) { - .x = 50, - .y = 57, - .width = 160, - .height = 200 + .x = 0, + .y = 0, + .width = 128, + .height = 128 }, .collider = (Rectangle) { - .x = -50, - .y = -50, - .width = 100, - .height = 100 + .x = -COLLIDER_WIDTH / 2 + COLLIDER_XOFF, + .y = -COLLIDER_HEIGHT / 2 + COLLIDER_YOFF, + .width = COLLIDER_WIDTH, + .height = COLLIDER_HEIGHT }, .sprite_dest_rect = (Rectangle) { - .x = -50, - .y = -50, - .width = 100, - .height = 100 - } + .x = -PLAYER_WIDTH / 2, + .y = -PLAYER_HEIGHT / 2, + .width = PLAYER_WIDTH, + .height = PLAYER_HEIGHT + }, + + .player_state = Player_Idle, + .start_position = (Vector2) {xpos, ypos} }; + add_player_animations(&player); + add_entity(&player); } -float get_x_acceleration_direction(const struct entity* player) { +void player_accelerate(struct entity* player, float step) { + if (IsKeyDown(KEY_A)) { - return -1.0; + + player->velocity.x = + fmaxf(player->velocity.x - step, -TOP_SPEEDX); } else if (IsKeyDown(KEY_D)) { - return 1.0; + + player->velocity.x = + fminf(player->velocity.x + step, TOP_SPEEDX); + } else if (fabsf(player->velocity.x) > 0) { + + player->velocity.x = move_to(player->velocity.x, 0, step); } - return 0.0; } void handle_movement(struct entity* player, float dt) { - Vector2 accel = { - .x = get_x_acceleration_direction(player) * ACCEL_X, - .y = GRAVITY - }; - - if (accel.x != 0) { - player->velocity.x += dt * accel.x * 0.5; - } else if (player->velocity.x < 0) { - player->velocity.x = - fminf(player->velocity.x + ACCEL_X * 0.5 * dt, 0); - } else if (player->velocity.x > 0) { - player->velocity.x = - fmaxf(player->velocity.x - ACCEL_X * 0.5 * dt, 0); - } - player->velocity.y += GRAVITY * dt * 0.5; + player_accelerate(player, ACCEL_X * dt * 0.5); + player->velocity.y += GRAVITY * 0.5 * dt; move_and_collide(player, dt); - if (accel.x != 0) { - player->velocity.x += dt * accel.x * 0.5; - } else if (player->velocity.x < 0) { - player->velocity.x = - fminf(player->velocity.x + ACCEL_X * 0.5 * dt, 0); - } else if (player->velocity.x > 0) { - player->velocity.x = - fmaxf(player->velocity.x - ACCEL_X * 0.5 * dt, 0); - } - player->velocity.y += GRAVITY * dt * 0.5; + player_accelerate(player, ACCEL_X * dt * 0.5); + player->velocity.y += GRAVITY * 0.5 * dt; +} + +void jump(struct entity* player) { + player->velocity.y = -200; + + if (IsKeyDown(KEY_A) && player->velocity.x > 0) + player->velocity.x = 0; + else if (IsKeyDown(KEY_D) && player->velocity.x < 0) + player->velocity.x = 0; } void handle_input(struct entity* player) { - if (IsKeyPressed(KEY_SPACE)) { - player->velocity.y = -50; + if (IsKeyPressed(KEY_SPACE) && player->player_state == Player_Idle) { + jump(player); + } +} + +void reset_position(struct entity* player) { + player->position = player->start_position; +} + +void handle_fall(struct entity* player) { + if (player->position.y > WINDOW_HEIGHT + 100) + reset_position(player); +} + +void handle_flip(struct entity* player) { + if (player->velocity.x < 0) { + player->flip = true; + } else { + player->flip = false; } } void update_player(struct entity* player, float dt) { + //Collision unsets it I didn't find a better way to do this + //with the current setup + player->player_state = Player_Air; + handle_movement(player, dt); handle_input(player); + handle_fall(player); + handle_flip(player); + update_animation(&player->animations[player->current_animation], dt); +} + +void player_handle_collision +( + struct entity* player, + struct entity* other, + enum direction collision_direction + ) { + switch (other->type) { + case Wall_Entity: + if (collision_direction == Direction_Left || collision_direction == Direction_Right) { + player->velocity.x = 0.0; + } else if (collision_direction == Direction_Down || collision_direction == Direction_Up) { + player->velocity.y = 0.0; + } + + if (collision_direction == Direction_Down) { + player->player_state = Player_Idle; + } + + break; + + default: + break; + } +} + +void add_player_animations(struct entity* player) { + //Walking animation + player->animations[0] = (struct animation) { + .frame_count = 2, + .is_looping = true, + + .source_rects = { + {.x = 0, .y = 129, .width = 128, .height = 128}, + {.x = 129, .y = 129, .width = 128, .height = 128} + }, + .frame_times = {0.2, 0.2} + }; } diff --git a/src/player.h b/src/player.h index 36f2d7b..96c4c29 100644 --- a/src/player.h +++ b/src/player.h @@ -3,7 +3,18 @@ #include "entity.h" +enum player_state { + Player_Idle, + Player_Air +}; + void add_player(float xpos, float ypos); void update_player(struct entity* player, float dt); +void player_handle_collision +( + struct entity* player, + struct entity* other, + enum direction collision_direction + ); #endif // PLAYER_H_ diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..f133b15 --- /dev/null +++ b/src/utils.c @@ -0,0 +1,14 @@ +#include <math.h> +#include "utils.h" + +float move_to(float current, float target, float step) { + if (step < 0) + return move_to(current, target, -step); + + if (current > target) + return fmaxf(current-step, target); + else if (current < target) + return fminf(current+step, target); + + return current; +} diff --git a/src/utils.h b/src/utils.h new file mode 100644 index 0000000..bade4b2 --- /dev/null +++ b/src/utils.h @@ -0,0 +1,6 @@ +#ifndef UTILS_H_ +#define UTILS_H_ + +float move_to(float current, float target, float step); + +#endif // UTILS_H_ @@ -1,11 +1,30 @@ #include <raylib.h> #include "wall.h" -void add_wall(float xpos, float ypos, float width, float height) { +#define BLOCK_WIDTH 128 +#define BLOCK_HEIGHT 128 + +extern struct Texture wall_texture; + +void add_wall(float xpos, float ypos) { struct entity wall = { .type = Wall_Entity, .flags = (ENTITY_ACTIVE | ENTITY_COLLISION_ACTIVE | ENTITY_VISIBLE), + .texture = wall_texture, + .sprite_source_rect = (Rectangle) { + .x = 0, + .y = 0, + .width = 128, + .height = 128 + }, + .sprite_dest_rect = (Rectangle) { + .x = xpos - BLOCK_WIDTH / 2, + .y = ypos - BLOCK_HEIGHT / 2, + .width = BLOCK_WIDTH, + .height = BLOCK_HEIGHT + }, + .position = { .x = xpos, .y = ypos @@ -13,17 +32,13 @@ void add_wall(float xpos, float ypos, float width, float height) { .velocity = (Vector2) {0}, .collider = (Rectangle) { - .x = xpos - width / 2, - .y = ypos - height / 2, - .width = width, - .height = height + .x = xpos - BLOCK_WIDTH / 2, + .y = ypos - BLOCK_HEIGHT / 2, + .width = BLOCK_WIDTH, + .height = BLOCK_HEIGHT }, }; add_entity(&wall); } - -void draw_wall(const struct entity* wall) { - DrawRectangleRec(get_entity_collider_world(wall), RED); -} @@ -3,7 +3,6 @@ #include "entity.h" -void add_wall(float xpos, float ypos, float width, float height); -void draw_wall(const struct entity* wall); +void add_wall(float xpos, float ypos); #endif // WALL_H_ |
