Demonstrating sprite animation, player input handling, and ImGui debug features within my custom C++/SFML engine.
Video will be updated at a later date.
This project, developed for my 'Games Engine Construction' module at Teesside University (Year 2, 2025 - 2026), involves developing a complete 2D game engine - using C++ and SFML. The primary goal was to create a architectural-focused game engine suitable to create simple 2D games. The initial project setup, including ImGui integration, was provided by the module.
The tilemap ("Pixel platformer industrial expansion") is courtesy of Kenney, available at: https://kenney.nl/assets/pixel-platformer-industrial-expansion.
The character and enemy sprite's ("SKELETON GUNSLINGER") are courtesy of PikselKisin, available at: https://pikselkisin.itch.io/skeleton-gunslinger.
The collectable coin ("Essential Game Collectables 3 Pack") is courtesy of Ace Studios, available at: https://ace-studi0s.itch.io/essential-game-collectables-3-pack.
Core Architecture: Developed a decoupled Simulation/Graphics architecture using a fixed-timestep game loop to ensure deterministic physics and logic across variable hardware.
Data-Driven Level Loading: Engineered a parser to dynamically instantiate world geometry and entities from external '.txt' configuration files, allowing for rapid level iteration without recompiling code.
Polymorphic Entity System: Built a scalable hierarchy (Base Entity, Dynamic Entity) to manage diverse game actors including Player controllers, stationary & patrolling enemies, and collectables.
Gameplay Systems: Implemented a projectile/shooting mechanic utilising a centralised bullet pool and specific entity state logic for combat interactions.
Advanced Physics Logic: Developed a Custom Rectangle class for discrete AABB collision detection, featuring gravity simulation, grounded-state detection, and horizontal/vertical resolution logic.
Decoupled Input: Utilised the Observer Pattern to separate raw SFML hardware events from character-specific movement and action logic.
Asset Pipeline: Engineered automated Texture and Animation Managers to handle sprite-sheet slicing and frame-timing, preventing redundant memory allocations.
Developer Tooling: Integrated an ImGui debugging suite for real-time monitoring of physics bounds, velocity vectors, and entity state inspection.
Language: C++
Libraries/Frameworks: SFML, Standard Libraries (map, vector, string, iostream)
Core Concepts: OOP (Encapsulation & Inheritance), Design Patterns (Observer, Singleton), Data Structures (std::map, std::vector), Algorithms (AABB Collision), Asset Management, Game Loop Architecture
IDE: Visual Studio
Tools: GitHub, ImGui
As my most ambitious project to date, building this engine has significantly deepened my core C++ knowledge and familiarised me with tools like ImGui and SFML.
Architectural Decoupling & Memory Ownership: A significant challenge was managing a polymorphic entity hierarchy while maintaining memory safety. I transitioned from raw pointers to using 'std::unique_ptr' within a std::vector for centralised entity ownership. To balance safety with performance, I implemented an "Ownership vs. Observation" strategy: the simulation owns the memory, but frequently accessed entities like the Player are cached via raw pointers to avoid expensive lookups.
Simulation vs Rendering (Interpolation): To solve the jittering and sinking issues in physics simulations, I decoupled the Simulation State from the Render State. I implemented a fixed-timestep game loop using an accumulator. By storing 'm_previousPosition' and using an alpha value based on the remaining time in the accumulator, I utilised Linear Interpolation (LERP) to ensure smooth visuals even when the rendering frame rate differs from the 60Hz physics clock.
Performance Optimisation through Design Patterns:
Object Pooling: To prevent heap fragmentation and the overhead of frequent allocations, I engineered a bullet system that pre-allocates a pool of 20 projectiles at level load, recycling them via an 'm_isActive' flag.
Broadcasting Action Vectors: The standard Observer Pattern initially struggled with simultaneous key presses. I refactored the 'InputManager' to broadcast a 'std::vector<Actions>' rather than single events, allowing for fluid, simultaneous movement and action logic.
AI Pathfinding: For enemy behaviour, I developed an "Edge Detection" sensor using a small virtual AABB ahead of the entity to check for world geometry, providing a cost-effective alternative to complex pathfinding for a 2D environment.
Module Grade: 96%