summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoredGuy <osome3717@gmail.com>2026-03-23 17:11:28 +0300
committerBoredGuy <osome3717@gmail.com>2026-03-23 17:11:28 +0300
commit7c438c2a0e25d22323b5def545f32e97eee689f0 (patch)
treea9e2cf29a967c88d022ea8e6c20a522a9c482610
parent6dbd16cd920b51bc24b60d0561bd707ff8862cc5 (diff)
Asset system
- Multiple entity updates
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/assets.c15
-rw-r--r--src/assets.h7
-rw-r--r--src/constants.h6
-rw-r--r--src/entity.c52
-rw-r--r--src/entity.h5
-rw-r--r--src/main.c16
-rw-r--r--src/player.c172
-rw-r--r--src/player.h11
-rw-r--r--src/utils.c14
-rw-r--r--src/utils.h6
-rw-r--r--src/wall.c33
-rw-r--r--src/wall.h3
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);
diff --git a/src/main.c b/src/main.c
index 75de22f..5fa3ca1 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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_
diff --git a/src/wall.c b/src/wall.c
index 6ee3a2a..5a17f21 100644
--- a/src/wall.c
+++ b/src/wall.c
@@ -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);
-}
diff --git a/src/wall.h b/src/wall.h
index 2a481f4..17d8a2e 100644
--- a/src/wall.h
+++ b/src/wall.h
@@ -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_