Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
14ffc1e
fix(client>components): Fixed fat finger in animation struct
Babouye Jan 18, 2026
7a1d485
feat(client>gui): Added complete assetManager
Babouye Jan 18, 2026
a8e7fe6
feat(client>handlers): Added animation handling in handle_spawn
Babouye Jan 18, 2026
df5f9ab
feat(client>systems): Added animationSystem
Babouye Jan 18, 2026
b11b305
feat(client>systems): Added engine and assetManager to renderer
Babouye Jan 18, 2026
504efbb
feat(client>systems): Added animation drawing in renderer
Babouye Jan 18, 2026
cb8e128
feat(client): Registered new animationSystem in app.cpp
Babouye Jan 18, 2026
07f9bcf
feat(client>systems): Added scale calculation with hitbox
Babouye Jan 18, 2026
5d55224
feat(client>sprites): Switched player sprite now that the spritesheet…
Babouye Jan 18, 2026
f79d316
feat(client>sprites): Cropped bullet spritesheet and adapt related code
Babouye Jan 18, 2026
45cb7ce
ref(client>rendering): Changed background drawing from `MenuRenderer`…
PierreMarguerie Jan 18, 2026
dd013be
fix(client>rendering): Fixed flickering screen
PierreMarguerie Jan 18, 2026
681a1d7
ref(client>systems>renderer): Removed unused `GameEngine` reference
PierreMarguerie Jan 18, 2026
8083915
feat(client>components): Added loop boolean in animation component
Babouye Jan 18, 2026
a6b3659
feat(client>gui): Handled new loop boolean in assetManager
Babouye Jan 18, 2026
053a3a5
feat(client>handlers): Added loop boolean to component on spawn
Babouye Jan 18, 2026
28ac860
feat(client>systems): Added animation system that allow to stop an an…
Babouye Jan 18, 2026
8a5b5ce
ref(client>assets): Added a common filepath prefix for easier path ad…
PierreMarguerie Jan 18, 2026
5ae0f90
fix(merge): Fixed merge conflict induced error
PierreMarguerie Jan 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Client/assets/sprites/bullet.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Client/assets/sprites/player1.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Client/assets/sprites/player2.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Client/assets/sprites/player3.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Client/assets/sprites/player4.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Client/assets/sprites/player5.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions Client/src/app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "packets/server/spawn.hpp"
#include "systems/IO.hpp"
#include "systems/Menus.hpp"
#include "systems/animationSystem.hpp"
#include "systems/interpolation.hpp"
#include "systems/network.hpp"
#include "systems/renderer.hpp"
Expand Down Expand Up @@ -52,13 +53,14 @@ void App::registerAllComponents()

void App::registerAllSystems()
{
_toolbox.engine.getEcs()->registerSystem(std::make_shared<systems::AnimationSystem>());
_toolbox.engine.getEcs()->registerSystem(std::make_shared<systems::Interpolation>());
_toolbox.engine.getEcs()->registerSystem(std::make_shared<systems::IO>(_networkService));
_toolbox.engine.getEcs()->registerSystem(
std::make_shared<systems::Network>(_client, _networkService));
_toolbox.engine.getEcs()->registerSystem(std::make_shared<systems::Renderer>(_shouldStop));
_toolbox.engine.getEcs()->registerSystem(
std::make_shared<systems::MenuRenderer>(_lobbies, _networkService, _toolbox.engine));
_toolbox.engine.getEcs()->registerSystem(
std::make_shared<systems::Network>(_client, _networkService));
}

void App::registerAllCallbacks()
Expand Down
3 changes: 2 additions & 1 deletion Client/src/components/animations.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ struct Animation
int current_frame;
float frame_time;
float elapsed_time;
int frame_with;
int frame_width;
int frame_height;
bool loop;
};
} // namespace components
37 changes: 22 additions & 15 deletions Client/src/gui/assetManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,44 +4,51 @@

#include "logger/Logger.h"

static constexpr std::string_view ENEMY_TEXTURE_PATH = "Client/assets/sprites/enemyAerial.gif";
static constexpr std::string_view BULLET_TEXTURE_PATH = "Client/assets/sprites/bullets.gif";
static constexpr std::string_view ENEMY_TEXTURE_PATH =
ASSET_FILEPATH_PREFIX "/sprites/enemyAerial.gif";
static constexpr std::string_view BULLET_TEXTURE_PATH = ASSET_FILEPATH_PREFIX "/sprites/bullet.gif";

// static constexpr std::string_view UI_MENU_BG_PATH = "../../Client/assets/ui/MenuBackground.png";
// static constexpr std::string_view UI_PAUSE_BTN_PATH = "../../Client/assets/ui/PauseButton.png";

void AssetManager::init()
void gui::AssetManager::init()
{
_background = std::make_unique<gui::Texture>(BACKGROUND_TEXTURE_FILEPATH.data());
size_t entityCount = static_cast<size_t>(entity::Type::kBullet) + 1;
_textures.reserve(entityCount);

_textures.emplace_back(gui::PLAYER_TEXTURE_FILEPATH.data(), 0.2f);

_textures.emplace_back(ENEMY_TEXTURE_PATH.data(), 0.15f);

_textures.emplace_back(BULLET_TEXTURE_PATH.data(), 0.1f);
_textures.emplace_back(gui::PLAYER_TEXTURE_FILEPATH.data(), 1.0f);
_textures.emplace_back(ENEMY_TEXTURE_PATH.data(), 1.0f);
_textures.emplace_back(BULLET_TEXTURE_PATH.data(), 1.0f);

LOG_INFO("AssetManager: Loaded {} game textures and {} UI textures",
_textures.size(),
_uiTextures.size());
// _uiTextures[gui::UIAsset::kMenuBackground] =
// std::make_unique<gui::Texture>(UI_MENU_BG_PATH.data(), 1.0f);
// _uiTextures[gui::UIAsset::kPauseButton] =
// std::make_unique<gui::Texture>(UI_PAUSE_BTN_PATH.data(), 0.5f);

LOG_INFO("AssetManager: Loaded {} game textures and {} UI textures",
_textures.size(),
_uiTextures.size());
}

const gui::Texture& AssetManager::getTexture(entity::Type id) const
const gui::Texture& gui::AssetManager::getTexture(entity::Type id) const
{
size_t index = static_cast<size_t>(id);
if (index >= _textures.size()) {
LOG_ERR("AssetManager: Attempting to access unknown game texture index {}", index);
return _textures[0]; // Return player texture as fallback
return _textures[0];
}
return _textures[index];
}

const gui::Texture& AssetManager::getUITexture(gui::UIAsset id) const
const Texture2D& gui::AssetManager::getBackground() const
{
if (!_background) {
return _textures.back().getTexture();
}
return _background->getTexture();
}

const gui::Texture& gui::AssetManager::getUITexture(gui::UIAsset id) const
{
auto it = _uiTextures.find(id);
if (it == _uiTextures.end()) {
Expand Down
44 changes: 43 additions & 1 deletion Client/src/gui/assetManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,41 @@ enum class UIAsset
kScoreFont
};

} // namespace gui
struct SpriteConfig
{
int frameCount;
int frameWidth;
int frameHeight;
float frameTime;
};

struct AnimationConfig
{
int frameCount;
float frameTime;
int frameWidth;
int frameHeight;
bool loop;
};

static const std::unordered_map<entity::Type, AnimationConfig> entityTypeToAnimation = {
{entity::Type::kPlayer,
{5,
0.15f,
33,
15,
true}}, // {Number of frames, Time per frame, Frame width, Frame height, Loop}
{entity::Type::kEnemy, {8, 0.15f, 32, 32, true}},
{entity::Type::kBullet, {3, 0.15f, 18, 14, false}},
};

inline AnimationConfig typeToAnimation(const entity::Type& type)
{
if (!entityTypeToAnimation.contains(type)) {
return {1, 0.0f, 0, 0, false};
}
return entityTypeToAnimation.at(type);
}

class AssetManager
{
Expand All @@ -30,9 +64,17 @@ class AssetManager

[[nodiscard]] const gui::Texture& getTexture(entity::Type id) const;

[[nodiscard]] const Texture2D& getBackground() const;

[[nodiscard]] const gui::Texture& getUITexture(gui::UIAsset id) const;

[[nodiscard]] const gui::SpriteConfig& getSpriteConfig(entity::Type id) const;

private:
std::unique_ptr<gui::Texture> _background;
std::vector<gui::Texture> _textures;
std::map<entity::Type, gui::SpriteConfig> _spriteConfigs;
std::map<gui::UIAsset, std::unique_ptr<gui::Texture>> _uiTextures;
};

} // namespace gui
6 changes: 5 additions & 1 deletion Client/src/gui/texture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

namespace gui {

static constexpr std::string_view PLAYER_TEXTURE_FILEPATH = "Client/assets/sprites/players.gif";
#define ASSET_FILEPATH_PREFIX "Client/assets"
static constexpr std::string_view PLAYER_TEXTURE_FILEPATH =
ASSET_FILEPATH_PREFIX "/sprites/player1.gif";
static constexpr std::string_view BACKGROUND_TEXTURE_FILEPATH =
ASSET_FILEPATH_PREFIX "/background.png";

class Texture
{
Expand Down
16 changes: 15 additions & 1 deletion Client/src/handlers/handle_spawn.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "app.hpp"
#include "components/animations.hpp"
#include "components/sprite.hpp"
#include "components/target_pos.hpp"
#include "gui/assetManager.hpp"
#include "handlers.hpp"
#include "rteng.hpp"

Expand All @@ -13,6 +15,19 @@ static void addGraphicalComponents(rtecs::types::EntityID id,
toolbox.engine.getEcs()->addEntityComponents<components::Sprite>(
id, {type.value().get().type});
}

const gui::AnimationConfig& config = gui::typeToAnimation(type.value().get().type);
if (config.frameCount > 1) {
toolbox.engine.getEcs()->addEntityComponents<components::Animation>(id,
{config.frameCount,
0,
config.frameTime,
0.0f,
config.frameWidth,
config.frameHeight,
config.loop});
}

rtecs::types::OptionalRef<components::Position> pos =
toolbox.engine.getEcs()->group<components::Position>().getEntity<components::Position>(id);
if (pos) {
Expand Down Expand Up @@ -42,5 +57,4 @@ void handleSpawn(Spawn packet,
addGraphicalComponents(real, toolbox);
LOG_TRACE_R2("Finished recomposing entity {}", real);
}

} // namespace packet::handler
11 changes: 4 additions & 7 deletions Client/src/systems/Menus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ MenuRenderer::MenuRenderer(client::Lobby& lobby,
: ASystem("MenuRenderer"),
_service(service),
_lobby(lobby),
_engine(engine),
_texture(BACKGROUND_TEXTURE_FILEPATH.data())
_engine(engine)
{
_buttons.reserve(5);

Expand Down Expand Up @@ -118,15 +117,13 @@ void MenuRenderer::renderPreGameMenu()
void MenuRenderer::apply(rtecs::ECS&)
{
if (_engine.getGameState() == game::state::GameRunning || WindowShouldClose()) {
if (!WindowShouldClose()) {
EndDrawing();
}
return;
}
const size_t menuState = _engine.getMenuState();

BeginDrawing();

ClearBackground(GREEN);
DrawTexture(_texture.getTexture(), 0, 0, WHITE);

if (menuState == menu::state::MenuLobby) {
renderPreGameMenu();
}
Expand Down
17 changes: 9 additions & 8 deletions Client/src/systems/Menus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ struct Lobby;

#define SHARE_FONT(s) std::make_shared<Font>(LoadFontEx(s, FONT_SIZE, nullptr, 250));

static constexpr std::string_view START_BUTTON_FILEPATH = "Client/assets/buttons/start.png";
static constexpr std::string_view PLAY_BUTTON_FILEPATH = "Client/assets/buttons/play.png";
static constexpr std::string_view CREDITS_BUTTON_FILEPATH = "Client/assets/buttons/credits.png";
static constexpr std::string_view CREATE_BUTTON_FILEPATH = "Client/assets/buttons/create.png";
static constexpr std::string_view BACKGROUND_TEXTURE_FILEPATH = "Client/assets/background.png";
static constexpr std::string_view BASIC_FONT = "Client/assets/basic.ttf";
static constexpr std::string_view DYSLEXIC_FONT = "Client/assets/dyslexic.ttf";
static constexpr std::string_view START_BUTTON_FILEPATH =
ASSET_FILEPATH_PREFIX "/buttons/start.png";
static constexpr std::string_view PLAY_BUTTON_FILEPATH = ASSET_FILEPATH_PREFIX "/buttons/play.png";
static constexpr std::string_view CREDITS_BUTTON_FILEPATH =
ASSET_FILEPATH_PREFIX "/buttons/credits.png";
static constexpr std::string_view CREATE_BUTTON_FILEPATH =
ASSET_FILEPATH_PREFIX "/buttons/create.png";
static constexpr std::string_view BASIC_FONT = ASSET_FILEPATH_PREFIX "/basic.ttf";
static constexpr std::string_view DYSLEXIC_FONT = ASSET_FILEPATH_PREFIX "/dyslexic.ttf";

static constexpr Color SEMI_WHITE = {255, 255, 255, 255 / 2};

Expand Down Expand Up @@ -119,7 +121,6 @@ class MenuRenderer : public rtecs::systems::ASystem
std::shared_ptr<Font> _basicFont;
std::shared_ptr<Font> _dyslexicFont;
rteng::GameEngine& _engine;
gui::Texture _texture;
std::vector<gui::Button> _buttons;
};

Expand Down
30 changes: 30 additions & 0 deletions Client/src/systems/animationSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "animationSystem.hpp"

#include <raylib.h>

#include "components/animations.hpp"

namespace systems {

AnimationSystem::AnimationSystem()
: rtecs::systems::ASystem("AnimationSystem")
{
}

void AnimationSystem::apply(rtecs::ECS& ecs)
{
float dt = GetFrameTime();

ecs.group<components::Animation>().apply(
[dt](const rtecs::types::EntityID&, components::Animation& anim) {
anim.elapsed_time += dt;
if (anim.elapsed_time >= anim.frame_time) {
anim.elapsed_time = 0;

if (anim.loop || anim.current_frame < anim.frame_count - 1) {
anim.current_frame = (anim.current_frame + 1) % anim.frame_count;
}
}
});
}
} // namespace systems
17 changes: 17 additions & 0 deletions Client/src/systems/animationSystem.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "rtecs/ECS.hpp"
#include "rtecs/systems/ASystem.hpp"

namespace systems {

class AnimationSystem final : public rtecs::systems::ASystem
{
public:
AnimationSystem();
~AnimationSystem() override = default;

void apply(rtecs::ECS& ecs) override;
};

} // namespace systems
46 changes: 40 additions & 6 deletions Client/src/systems/renderer.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "renderer.hpp"

#include "components/animations.hpp"
#include "components/hitbox.hpp"
#include "components/position.hpp"
#include "components/sprite.hpp"
#include "enums/entity_types.hpp"
Expand Down Expand Up @@ -27,15 +29,47 @@ void Renderer::apply(rtecs::ECS& ecs)
return;
}
BeginDrawing();
ClearBackground({0, 255, 0, 255});
ClearBackground(GREEN);
DrawTexture(_assetManager.getBackground(), 0, 0, WHITE);
ecs.group<components::Sprite, components::Position>().apply(
[this](const rtecs::types::EntityID&,
const components::Sprite& sprite,
const components::Position& pos) {
[&](const rtecs::types::EntityID& id,
const components::Sprite& sprite,
const components::Position& pos) {
const gui::Texture& tex = _assetManager.getTexture(sprite.type);
DrawTextureEx(tex.getTexture(), {pos.x, pos.y}, 0.0f, tex.getScale(), WHITE);
Texture2D rawTex = tex.getTexture();

Rectangle sourceRec = {0.0f, 0.0f, (float)rawTex.width, (float)rawTex.height};

const auto animOpt =
ecs.group<components::Animation>().getEntity<components::Animation>(id);
if (animOpt.has_value()) {
const components::Animation& anim = animOpt.value().get();
sourceRec.x = anim.current_frame * anim.frame_width;
sourceRec.y = 0.0f;
sourceRec.width = (float)anim.frame_width;
sourceRec.height = (float)anim.frame_height;
}

float scaleX = (float)tex.getScale();
float scaleY = (float)tex.getScale();

const auto hitboxOpt =
ecs.group<components::Hitbox>().getEntity<components::Hitbox>(id);

if (hitboxOpt.has_value()) {
const auto& hb = hitboxOpt.value().get();
if (sourceRec.width != 0) {
scaleX = hb.width / sourceRec.width;
}
if (sourceRec.height != 0) {
scaleY = hb.height / sourceRec.height;
}
}

Rectangle destRec = {pos.x, pos.y, sourceRec.width * scaleX, sourceRec.height * scaleY};

DrawTexturePro(rawTex, sourceRec, destRec, {0, 0}, 0.0f, WHITE);
});
EndDrawing();
}

} // namespace systems
3 changes: 2 additions & 1 deletion Client/src/systems/renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "gui/assetManager.hpp"
#include "gui/texture.hpp"
#include "rtecs/systems/ASystem.hpp"
#include "rteng.hpp"

namespace systems {

Expand All @@ -21,7 +22,7 @@ class Renderer final : public rtecs::systems::ASystem

private:
bool& _closing;
AssetManager _assetManager;
gui::AssetManager _assetManager;
};

} // namespace systems
Loading