|
R-Type
Distributed multiplayer game engine in C++
|
Specialized renderer for game entities with client-side interpolation. More...
#include <EntityRenderer.hpp>

Classes | |
| struct | BackgroundConfig |
| Configuration for scrolling parallax backgrounds. More... | |
| struct | RenderableEntity |
| Cached entity state for rendering. More... | |
Public Member Functions | |
| EntityRenderer (Graphics::RaylibGraphics &graphics) | |
| Constructor. | |
| ~EntityRenderer ()=default | |
| Destructor. | |
| void | updateEntity (uint32_t id, RType::Messages::Shared::EntityType type, float x, float y, int health, const std::string ¤tAnimation, int srcX, int srcY, int srcW, int srcH, float velocityX=0.0f, float velocityY=0.0f, uint32_t serverTick=0) |
| Update or create an entity in the local cache. | |
| void | removeEntity (uint32_t id) |
| Remove an entity from the rendering cache. | |
| void | clearAllEntities () |
| Clear all entities from the cache. | |
| void | setBackground (const std::string &mainBackground, const std::string ¶llaxBackground, float scrollSpeed, float parallaxSpeedFactor) |
| Set up background layers for parallax scrolling. | |
| void | clearBackground () |
| Clear background configuration. | |
| void | updateBackground (float deltaTime) |
| Update background scroll positions. | |
| void | setMyEntityId (uint32_t id) |
| Set the local player's entity ID for visual differentiation. | |
| void | render () |
| Render all cached entities. | |
| size_t | getEntityCount () const |
| Get the number of entities currently cached. | |
| bool | hasEntity (uint32_t id) const |
| Check if an entity exists in the cache. | |
| void | setDebugMode (bool enabled) |
| Toggle debug information overlay. | |
| void | setInterpolationEnabled (bool enabled) |
| Enable or disable interpolation for smooth movement. | |
| void | setInterpolationSpeed (float speed) |
| Set the interpolation speed multiplier. | |
| void | setClientSidePredictionEnabled (bool enabled) |
| Enable or disable client-side prediction for local player. | |
| void | setReconciliationThreshold (float threshold) |
| Set the reconciliation threshold for client-side prediction. | |
| float | getReconciliationThreshold () const |
| Get the current reconciliation threshold. | |
| void | updateInterpolation (float deltaTime) |
| Update interpolation for all entities. | |
| void | moveEntityLocally (uint32_t entityId, float deltaX, float deltaY) |
| Move an entity locally (client-side prediction) | |
| void | setLocalPlayerMoving (bool moving) |
| Set whether the local player is currently moving. | |
Private Member Functions | |
| void | renderPlayer (const RenderableEntity &entity, bool isLocalPlayer) |
| Render a player entity. | |
| void | renderEnemy (const RenderableEntity &entity) |
| Render an enemy entity. | |
| void | renderProjectile (const RenderableEntity &entity) |
| Render a projectile (player or enemy bullet) | |
| void | renderWall (const RenderableEntity &entity) |
| Render a wall/obstacle. | |
| void | renderOrbitalModule (const RenderableEntity &entity) |
| Render an orbital module (drone) | |
| void | renderHealthBar (float x, float y, int health, int maxHealth) |
| Render a health bar above an entity. | |
| void | renderDebugInfo (const RenderableEntity &entity) |
| Render debug information for an entity. | |
| void | renderBackground () |
| Render scrolling background layers. | |
| float | lerp (float start, float end, float t) const |
| Linear interpolation between two values. | |
| float | clamp (float value, float min, float max) const |
| Clamp a value between min and max. | |
| uint64_t | getCurrentTimeMs () const |
| Get current time in milliseconds. | |
Private Attributes | |
| std::unordered_map< uint32_t, RenderableEntity > | _entities |
| Entity cache: maps entity ID to its renderable state. | |
| uint32_t | _myEntityId = 0 |
| Local player's entity ID (for visual differentiation) | |
| Graphics::RaylibGraphics & | _graphics |
| Reference to graphics subsystem for drawing operations. | |
| bool | _showDebugInfo = true |
| Debug mode: show entity IDs and health bars (toggle with F3) | |
| bool | _interpolationEnabled = true |
| Interpolation enabled flag. | |
| float | _interpolationSpeed = 10.0f |
| bool | _clientSidePredictionEnabled = true |
| Client-side prediction enabled flag (for local player only) | |
| float | _reconciliationThreshold = 15.0f |
| bool | _localPlayerIsMoving = false |
| Track whether local player is currently moving (used for reconciliation logic) | |
| BackgroundConfig | _mainBackground |
| Main background layer (scrolls at map's scroll speed) | |
| BackgroundConfig | _parallaxBackground |
| Parallax background layer (rendered on top, scrolls slower for depth effect) | |
| bool | _backgroundActive = false |
| Whether backgrounds are configured and active. | |
Specialized renderer for game entities with client-side interpolation.
This is a NETWORK MIDDLEWARE for smooth visual rendering, NOT an ECS system. The EntityRenderer is responsible for: - Maintaining a local cache of entity states received from the server - CLIENT-SIDE INTERPOLATION: Smoothing movement between discrete server updates - Rendering entities based on their type with appropriate visuals - Handling visual differentiation (local player vs other players) - Managing entity lifecycle (creation, update, removal) INTERPOLATION FLOW: 1. Server sends position at 20-30 Hz (every 30-50ms) 2. updateEntity() saves current pos as "previous", new pos as "target" 3. updateInterpolation() smoothly moves from previous to target (60 FPS) 4. render() displays entity at interpolated position This provides smooth 60 FPS visuals from 20 Hz server updates.
Definition at line 39 of file EntityRenderer.hpp.
|
explicit |
Constructor.
| graphics | Reference to the graphics subsystem (RaylibGraphics) |
The EntityRenderer does not own the graphics object, it only holds a reference to use its drawing primitives.
Definition at line 13 of file EntityRenderer.cpp.
References LOG_DEBUG.
|
default |
Destructor.
|
private |
Clamp a value between min and max.
| value | Value to clamp |
| min | Minimum value |
| max | Maximum value |
Definition at line 639 of file EntityRenderer.cpp.
Referenced by updateInterpolation().
| void EntityRenderer::clearAllEntities | ( | ) |
Clear all entities from the cache.
Useful for scene transitions or when disconnecting from server.
Definition at line 154 of file EntityRenderer.cpp.
| void EntityRenderer::clearBackground | ( | ) |
Clear background configuration.
Called when leaving the game scene to stop background rendering.
Definition at line 216 of file EntityRenderer.cpp.
References _backgroundActive, _graphics, _mainBackground, _parallaxBackground, EntityRenderer::BackgroundConfig::loaded, LOG_DEBUG, EntityRenderer::BackgroundConfig::textureName, and Graphics::RaylibGraphics::UnloadTexture().
Referenced by setBackground().

|
private |
Get current time in milliseconds.
Definition at line 649 of file EntityRenderer.cpp.
Referenced by updateEntity().
|
inline |
Get the number of entities currently cached.
Definition at line 219 of file EntityRenderer.hpp.
References _entities.
|
inline |
Get the current reconciliation threshold.
Definition at line 282 of file EntityRenderer.hpp.
References _reconciliationThreshold.
|
inline |
Check if an entity exists in the cache.
| id | Entity unique identifier |
Definition at line 226 of file EntityRenderer.hpp.
References _entities.
|
private |
Linear interpolation between two values.
| start | Starting value |
| end | Ending value |
| t | Interpolation factor (0.0 to 1.0) |
Definition at line 635 of file EntityRenderer.cpp.
Referenced by updateInterpolation().
| void EntityRenderer::moveEntityLocally | ( | uint32_t | entityId, |
| float | deltaX, | ||
| float | deltaY | ||
| ) |
Move an entity locally (client-side prediction)
| entityId | Entity to move |
| deltaX | Movement in X direction |
| deltaY | Movement in Y direction |
Used for local player prediction: moves the entity immediately without waiting for server confirmation. Server will later send corrections which trigger reconciliation if needed.
This provides 0ms input latency for the local player.
Definition at line 619 of file EntityRenderer.cpp.
References _entities.
| void EntityRenderer::removeEntity | ( | uint32_t | id | ) |
Remove an entity from the rendering cache.
| id | Entity unique identifier to remove |
Should be called when receiving an EntityDestroyed message or when the entity is no longer in the GameState.
Definition at line 146 of file EntityRenderer.cpp.
| void EntityRenderer::render | ( | ) |
Render all cached entities.
Iterates through all entities in the cache and renders them based on their type. Entities are rendered in insertion order (no Z-ordering implemented yet).
Should be called once per frame from Rendering::Render().
Definition at line 324 of file EntityRenderer.cpp.
References _entities, _myEntityId, _showDebugInfo, RType::Messages::Shared::EnemyBullet, RType::Messages::Shared::EnemyType1, LOG_INFO, LOG_WARNING, RType::Messages::Shared::OrbitalModule, RType::Messages::Shared::Player, RType::Messages::Shared::PlayerBullet, renderBackground(), renderDebugInfo(), renderEnemy(), renderOrbitalModule(), renderPlayer(), renderProjectile(), renderWall(), and RType::Messages::Shared::Wall.

|
private |
Render scrolling background layers.
Draws both the main background and parallax layer with their respective scroll offsets for parallax depth effect.
Definition at line 256 of file EntityRenderer.cpp.
References _backgroundActive, _graphics, _mainBackground, _parallaxBackground, Graphics::RaylibGraphics::DrawRectFilled(), Graphics::RaylibGraphics::DrawTexturePro(), Graphics::RaylibGraphics::GetWindowHeight(), Graphics::RaylibGraphics::GetWindowWidth(), EntityRenderer::BackgroundConfig::loaded, EntityRenderer::BackgroundConfig::scrollOffset, EntityRenderer::BackgroundConfig::textureHeight, EntityRenderer::BackgroundConfig::textureName, and EntityRenderer::BackgroundConfig::textureWidth.
Referenced by render().

|
private |
Render debug information for an entity.
| entity | Entity to display debug info for |
Shows entity ID and health as text overlay. Only rendered when _showDebugInfo is true.
Definition at line 570 of file EntityRenderer.cpp.
References _graphics, Graphics::RaylibGraphics::DrawText(), EntityRenderer::RenderableEntity::entityId, EntityRenderer::RenderableEntity::health, EntityRenderer::RenderableEntity::type, EntityRenderer::RenderableEntity::x, and EntityRenderer::RenderableEntity::y.
Referenced by render().

|
private |
Render an enemy entity.
| entity | Enemy entity to render |
Definition at line 423 of file EntityRenderer.cpp.
References _graphics, Graphics::RaylibGraphics::DrawRectFilled(), EntityRenderer::RenderableEntity::health, renderHealthBar(), EntityRenderer::RenderableEntity::x, and EntityRenderer::RenderableEntity::y.
Referenced by render().

|
private |
Render a health bar above an entity.
| x | World position X (centered) |
| y | World position Y (above entity) |
| health | Current health points |
| maxHealth | Maximum health points |
Renders a two-layer bar: red background (damage) and green foreground (remaining health).
Definition at line 470 of file EntityRenderer.cpp.
References _graphics, and Graphics::RaylibGraphics::DrawRectFilled().
Referenced by renderEnemy(), renderOrbitalModule(), renderPlayer(), and renderWall().

|
private |
Render an orbital module (drone)
| entity | Orbital module entity to render |
Definition at line 545 of file EntityRenderer.cpp.
References _graphics, Graphics::RaylibGraphics::DrawTextureEx(), EntityRenderer::RenderableEntity::health, renderHealthBar(), EntityRenderer::RenderableEntity::scale, EntityRenderer::RenderableEntity::spriteSizeX, EntityRenderer::RenderableEntity::spriteSizeY, EntityRenderer::RenderableEntity::startPixelX, EntityRenderer::RenderableEntity::startPixelY, EntityRenderer::RenderableEntity::x, and EntityRenderer::RenderableEntity::y.
Referenced by render().

|
private |
Render a player entity.
| entity | Entity to render |
| isLocalPlayer | true if this is the player's own entity |
Players are rendered differently based on whether they are the local player (green/highlighted) or other players (blue).
Definition at line 384 of file EntityRenderer.cpp.
References _graphics, Graphics::RaylibGraphics::DrawText(), Graphics::RaylibGraphics::DrawTextureEx(), EntityRenderer::RenderableEntity::health, renderHealthBar(), EntityRenderer::RenderableEntity::scale, EntityRenderer::RenderableEntity::spriteSizeX, EntityRenderer::RenderableEntity::spriteSizeY, EntityRenderer::RenderableEntity::startPixelX, EntityRenderer::RenderableEntity::startPixelY, EntityRenderer::RenderableEntity::x, and EntityRenderer::RenderableEntity::y.
Referenced by render().

|
private |
Render a projectile (player or enemy bullet)
| entity | Projectile entity to render |
Definition at line 440 of file EntityRenderer.cpp.
References _graphics, EntityRenderer::RenderableEntity::currentAnimation, Graphics::RaylibGraphics::DrawTextureEx(), RType::Messages::Shared::EnemyBullet, EntityRenderer::RenderableEntity::entityId, LOG_DEBUG, EntityRenderer::RenderableEntity::scale, EntityRenderer::RenderableEntity::spriteSizeX, EntityRenderer::RenderableEntity::spriteSizeY, EntityRenderer::RenderableEntity::startPixelX, EntityRenderer::RenderableEntity::startPixelY, EntityRenderer::RenderableEntity::type, EntityRenderer::RenderableEntity::x, and EntityRenderer::RenderableEntity::y.
Referenced by render().

|
private |
Render a wall/obstacle.
| entity | Wall entity to render |
Definition at line 503 of file EntityRenderer.cpp.
References _graphics, Graphics::RaylibGraphics::DrawRectangleLines(), Graphics::RaylibGraphics::DrawRectFilled(), EntityRenderer::RenderableEntity::health, renderHealthBar(), EntityRenderer::RenderableEntity::spriteSizeX, EntityRenderer::RenderableEntity::spriteSizeY, EntityRenderer::RenderableEntity::x, and EntityRenderer::RenderableEntity::y.
Referenced by render().

| void EntityRenderer::setBackground | ( | const std::string & | mainBackground, |
| const std::string & | parallaxBackground, | ||
| float | scrollSpeed, | ||
| float | parallaxSpeedFactor | ||
| ) |
Set up background layers for parallax scrolling.
| mainBackground | Path to the main background texture |
| parallaxBackground | Path to the parallax layer texture (rendered on top, scrolls slower) |
| scrollSpeed | Base scroll speed in pixels/second |
| parallaxSpeedFactor | Speed factor for parallax layer (0.5 = half speed) |
The main background scrolls at scrollSpeed, while the parallax layer scrolls at scrollSpeed * parallaxSpeedFactor for depth effect.
Definition at line 159 of file EntityRenderer.cpp.
References _backgroundActive, _graphics, _mainBackground, _parallaxBackground, clearBackground(), Graphics::RaylibGraphics::GetTextureSize(), EntityRenderer::BackgroundConfig::loaded, Graphics::RaylibGraphics::LoadTexture(), LOG_INFO, LOG_WARNING, EntityRenderer::BackgroundConfig::scrollOffset, EntityRenderer::BackgroundConfig::scrollSpeed, EntityRenderer::BackgroundConfig::textureHeight, EntityRenderer::BackgroundConfig::textureName, EntityRenderer::BackgroundConfig::texturePath, and EntityRenderer::BackgroundConfig::textureWidth.

|
inline |
Enable or disable client-side prediction for local player.
| enabled | true to enable prediction (instant movement), false for interpolation |
When enabled, local player moves instantly without waiting for server. When disabled, local player is interpolated like other entities.
Definition at line 259 of file EntityRenderer.hpp.
References _clientSidePredictionEnabled.
|
inline |
Toggle debug information overlay.
| enabled | true to show entity IDs and health bars |
Definition at line 232 of file EntityRenderer.hpp.
References _showDebugInfo.
|
inline |
Enable or disable interpolation for smooth movement.
| enabled | true to enable interpolation, false for instant updates |
When enabled, entities smoothly transition between network updates. When disabled, entities snap directly to new positions.
Definition at line 241 of file EntityRenderer.hpp.
References _interpolationEnabled.
|
inline |
Set the interpolation speed multiplier.
| speed | Speed factor (higher = faster, typical: 5-15) |
Controls how quickly entities interpolate to target positions. Lower values = smoother but more lag, higher values = snappier but less smooth.
Definition at line 250 of file EntityRenderer.hpp.
References _interpolationSpeed.
|
inline |
Set whether the local player is currently moving.
| moving | true if player is actively moving, false if stopped |
This is used to adjust reconciliation behavior:
Definition at line 315 of file EntityRenderer.hpp.
References _localPlayerIsMoving.
| void EntityRenderer::setMyEntityId | ( | uint32_t | id | ) |
Set the local player's entity ID for visual differentiation.
| id | The entity ID that represents the local player |
This allows the renderer to highlight the player's own entity with a different color or visual effect.
Should be called when receiving the GameStart message which contains yourEntityId.
Definition at line 318 of file EntityRenderer.cpp.
References _myEntityId, LOG_DEBUG, and LOG_INFO.
|
inline |
Set the reconciliation threshold for client-side prediction.
| threshold | Distance in pixels before correction is applied |
Controls when the client prediction is corrected by the server's authoritative position. Smaller values = more frequent corrections (tighter sync, more visual jitter) Larger values = fewer corrections (looser sync, smoother visuals)
Recommended ranges:
Definition at line 276 of file EntityRenderer.hpp.
References _reconciliationThreshold.
| void EntityRenderer::updateBackground | ( | float | deltaTime | ) |
Update background scroll positions.
| deltaTime | Time elapsed since last frame (in seconds) |
Should be called every frame to advance the scrolling animation.
Definition at line 229 of file EntityRenderer.cpp.
References _backgroundActive, _mainBackground, _parallaxBackground, EntityRenderer::BackgroundConfig::loaded, EntityRenderer::BackgroundConfig::scrollOffset, EntityRenderer::BackgroundConfig::scrollSpeed, and EntityRenderer::BackgroundConfig::textureWidth.
| void EntityRenderer::updateEntity | ( | uint32_t | id, |
| RType::Messages::Shared::EntityType | type, | ||
| float | x, | ||
| float | y, | ||
| int | health, | ||
| const std::string & | currentAnimation, | ||
| int | srcX, | ||
| int | srcY, | ||
| int | srcW, | ||
| int | srcH, | ||
| float | velocityX = 0.0f, |
||
| float | velocityY = 0.0f, |
||
| uint32_t | serverTick = 0 |
||
| ) |
Update or create an entity in the local cache.
| id | Entity unique identifier |
| type | Entity type (Player, Enemy, Bullet) |
| x | World position X |
| y | World position Y |
| health | Current health (-1 if not applicable) |
| currentAnimation | Current animation clip name (e.g., "idle", "shoot") |
| srcX | Sprite source X |
| srcY | Sprite source Y |
| srcW | Sprite width |
| srcH | Sprite height |
| velocityX | Entity velocity X (for extrapolation, default=0) |
| velocityY | Entity velocity Y (for extrapolation, default=0) |
| serverTick | Server tick number (default=0) |
If the entity already exists, its state is updated. If it's a new entity, it's added to the cache.
This method should be called whenever a GameState or GameStart message is received from the server.
Definition at line 17 of file EntityRenderer.cpp.
References _clientSidePredictionEnabled, _entities, _interpolationEnabled, _localPlayerIsMoving, _myEntityId, _reconciliationThreshold, EntityRenderer::RenderableEntity::currentAnimation, EntityRenderer::RenderableEntity::currentFrame, RType::Messages::Shared::EnemyBullet, EntityRenderer::RenderableEntity::entityId, EntityRenderer::RenderableEntity::extrapolationEnabled, getCurrentTimeMs(), EntityRenderer::RenderableEntity::health, EntityRenderer::RenderableEntity::interpolationDelay, EntityRenderer::RenderableEntity::interpolationFactor, LOG_DEBUG, EntityRenderer::RenderableEntity::offsetX, EntityRenderer::RenderableEntity::offsetY, RType::Messages::Shared::PlayerBullet, EntityRenderer::RenderableEntity::prevX, EntityRenderer::RenderableEntity::prevY, EntityRenderer::RenderableEntity::scale, EntityRenderer::RenderableEntity::Snapshot::serverTick, EntityRenderer::RenderableEntity::snapshots, EntityRenderer::RenderableEntity::spriteSizeX, EntityRenderer::RenderableEntity::spriteSizeY, EntityRenderer::RenderableEntity::startPixelX, EntityRenderer::RenderableEntity::startPixelY, EntityRenderer::RenderableEntity::targetX, EntityRenderer::RenderableEntity::targetY, EntityRenderer::RenderableEntity::Snapshot::timestamp, EntityRenderer::RenderableEntity::type, EntityRenderer::RenderableEntity::Snapshot::velocityX, EntityRenderer::RenderableEntity::Snapshot::velocityY, EntityRenderer::RenderableEntity::Snapshot::x, EntityRenderer::RenderableEntity::x, EntityRenderer::RenderableEntity::Snapshot::y, and EntityRenderer::RenderableEntity::y.

| void EntityRenderer::updateInterpolation | ( | float | deltaTime | ) |
Update interpolation for all entities.
| deltaTime | Time elapsed since last frame (in seconds) |
Should be called every frame before render() to advance interpolation. This provides smooth movement between discrete server updates.
Definition at line 591 of file EntityRenderer.cpp.
References _entities, _interpolationEnabled, _interpolationSpeed, clamp(), RType::Messages::Shared::EnemyBullet, lerp(), and RType::Messages::Shared::PlayerBullet.

|
private |
Whether backgrounds are configured and active.
Definition at line 446 of file EntityRenderer.hpp.
Referenced by clearBackground(), renderBackground(), setBackground(), and updateBackground().
|
private |
Client-side prediction enabled flag (for local player only)
Definition at line 426 of file EntityRenderer.hpp.
Referenced by setClientSidePredictionEnabled(), and updateEntity().
|
private |
Entity cache: maps entity ID to its renderable state.
Definition at line 406 of file EntityRenderer.hpp.
Referenced by clearAllEntities(), getEntityCount(), hasEntity(), moveEntityLocally(), removeEntity(), render(), updateEntity(), and updateInterpolation().
|
private |
Reference to graphics subsystem for drawing operations.
Definition at line 412 of file EntityRenderer.hpp.
Referenced by clearBackground(), renderBackground(), renderDebugInfo(), renderEnemy(), renderHealthBar(), renderOrbitalModule(), renderPlayer(), renderProjectile(), renderWall(), and setBackground().
|
private |
Interpolation enabled flag.
Definition at line 418 of file EntityRenderer.hpp.
Referenced by setInterpolationEnabled(), updateEntity(), and updateInterpolation().
|
private |
Interpolation speed multiplier (higher = faster convergence) Set to 10.0 for smooth corrections over ~100ms (6 frames at 60 FPS) This allows client prediction to feel responsive while still correcting server authority
Definition at line 423 of file EntityRenderer.hpp.
Referenced by setInterpolationSpeed(), and updateInterpolation().
|
private |
Track whether local player is currently moving (used for reconciliation logic)
Definition at line 435 of file EntityRenderer.hpp.
Referenced by setLocalPlayerMoving(), and updateEntity().
|
private |
Main background layer (scrolls at map's scroll speed)
Definition at line 440 of file EntityRenderer.hpp.
Referenced by clearBackground(), renderBackground(), setBackground(), and updateBackground().
|
private |
Local player's entity ID (for visual differentiation)
Definition at line 409 of file EntityRenderer.hpp.
Referenced by render(), setMyEntityId(), and updateEntity().
|
private |
Parallax background layer (rendered on top, scrolls slower for depth effect)
Definition at line 443 of file EntityRenderer.hpp.
Referenced by clearBackground(), renderBackground(), setBackground(), and updateBackground().
|
private |
Reconciliation threshold in pixels (corrections smaller than this are ignored) Set to 15.0px to tolerate natural client prediction being ahead of server With 100px/s speed at 60Hz, each frame is ~1.67px, so 15px = ~9 frames (150ms) tolerance This prevents constant micro-corrections while client prediction is working normally
Definition at line 432 of file EntityRenderer.hpp.
Referenced by getReconciliationThreshold(), setReconciliationThreshold(), and updateEntity().
|
private |
Debug mode: show entity IDs and health bars (toggle with F3)
Definition at line 415 of file EntityRenderer.hpp.
Referenced by render(), and setDebugMode().