CacoEngine is a modern 2D game engine built with C++ and SDL2, designed to provide game developers with a powerful yet intuitive framework for creating 2D games. This chapter introduces the core concepts, architecture, and philosophy behind CacoEngine.
CacoEngine prioritizes ease of use without sacrificing power. The engine provides sensible defaults while allowing deep customization when needed.
Built on SDL2 for hardware-accelerated graphics, CacoEngine is designed for smooth 60+ FPS gameplay with efficient memory management.
The engine uses inheritance and composition patterns, making it easy to extend and customize for specific game requirements.
CacoEngine::Engine (Abstract Base Class)
โโโ Game Loop Management
โโโ Window & Renderer Control
โโโ Event System
โโโ Object Management
โโโ Physics Integration
The main engine class that manages the game lifecycle:
class Engine {
protected:
std::vector<Extension> Extensions;
SDL_Event Event;
Renderer EngineRenderer;
std::vector<std::shared_ptr<Object>> Objects;
std::vector<std::shared_ptr<RigidObject2D>> RigidObjects;
public:
void Run();
virtual void OnInitialize() = 0;
virtual void OnUpdate(double deltaTime) = 0;
virtual void OnKeyPress(SDL_KeyboardEvent& event) = 0;
virtual void OnMouseClick(SDL_MouseButtonEvent& event) = 0;
virtual void OnMouseScroll(SDL_MouseWheelEvent& event) = 0;
};Hardware-accelerated 2D rendering:
class Renderer {
public:
RGBA Color;
void Clear(RGBA color = RGBA());
void SetColor(RGBA color);
SDL_Renderer* GetInstance();
};Flexible object hierarchy for game entities:
class Object {
public:
Vector2Df Position;
Texture mTexture;
RGBA FillColor;
RasterizeMode FillMode;
Mesh ObjectMesh;
void Translate(Vector2Df offset);
void SetFillColor(RGBA color);
};Real-time physics simulation:
class RigidBody2D {
public:
Vector2Df Velocity;
Vector2Df Acceleration;
Vector2Df Force;
double Mass;
void AddForce(Vector2Df force);
void UpdateAcceleration();
};void Engine::Initialize() {
// SDL initialization
// Window creation
// Renderer setup
// Extension loading
// Call OnInitialize()
}void Engine::Run() {
while (IsRunning) {
// Handle events
// Update physics
// Call OnUpdate()
// Render objects
// Calculate delta time
}
}// Input events are dispatched to virtual methods
OnKeyPress(keyboardEvent);
OnMouseClick(mouseEvent);
OnMouseScroll(scrollEvent);// Clear screen
// Render all objects
// Render rigid objects
// Present frame#include "engine.hpp"
#include "sprite.hpp"
class MyGame : public CacoEngine::Engine {
private:
std::shared_ptr<CacoEngine::Sprite> player;
public:
MyGame() : Engine("My Game", CacoEngine::Vector2Df(800, 600)) {}
void OnInitialize() override {
// Load assets
auto texture = CacoEngine::TextureManager::CreateTexture("player.png", EngineRenderer);
// Create player sprite
player = std::make_shared<CacoEngine::Sprite>(
texture,
CacoEngine::Vector2Df(400, 300), // Position
CacoEngine::Vector2Df(64, 64) // Size
);
// Add to engine
AddObject(player);
}
void OnUpdate(double deltaTime) override {
// Game logic here
// Objects are automatically rendered
}
void OnKeyPress(SDL_KeyboardEvent& event) override {
switch (event.keysym.sym) {
case SDLK_LEFT:
player->Translate(CacoEngine::Vector2Df(-100 * deltaTime, 0));
break;
case SDLK_RIGHT:
player->Translate(CacoEngine::Vector2Df(100 * deltaTime, 0));
break;
}
}
void OnMouseClick(SDL_MouseButtonEvent& event) override {
// Handle mouse clicks
}
void OnMouseScroll(SDL_MouseWheelEvent& event) override {
// Handle scroll events
}
};int main() {
MyGame game;
game.Run(); // Starts the game loop
return 0;
}- Smart Pointers: Automatic memory management with
std::shared_ptr - Object Pooling: Reuse objects to reduce allocations
- Efficient Rendering: Hardware-accelerated graphics with SDL2
- Delta Time: Smooth animation independent of frame rate
- Efficient Updates: Only update changed objects
- Culling: Automatic off-screen object culling
- Broad Phase: Efficient collision detection algorithms
- Narrow Phase: Precise collision resolution
- Force Integration: Stable physics simulation
enum class Extension {
Video = SDL_INIT_VIDEO,
Audio = SDL_INIT_AUDIO
};
// Add extensions to your engine
void OnInitialize() override {
AddExtension(Extension::Video);
AddExtension(Extension::Audio);
}You can extend the engine with custom functionality:
class MyGameEngine : public CacoEngine::Engine {
private:
AudioManager audioManager;
NetworkManager networkManager;
public:
void OnInitialize() override {
// Initialize custom systems
audioManager.Initialize();
networkManager.Connect();
}
};enum class RasterizeMode {
Points, // Render as points
WireFrame, // Render as wireframe
SolidColor, // Render as solid color
Texture // Render with texture
};
// Set render mode
object->FillMode = RasterizeMode::Texture;- Object Sorting: Objects sorted by depth/priority
- Culling: Off-screen objects are culled
- Batch Rendering: Similar objects rendered together
- Texture Binding: Textures applied efficiently
// Engine constructor parameters
Engine(
std::string_view title = "CacoEngine App",
Vector2Df resolution = Vector2Df(800, 600),
bool fullscreen = false
);// Access window properties
std::string_view Title;
Vector2Df Resolution;
bool IsRunning;
Vector2D CursorPosition;
SDL_Window* Window;Now that you understand the engine overview, let's dive deeper into specific systems:
- Chapter 2: Architecture & Design - Detailed architecture patterns
- Chapter 3: Objects & Rendering - Object system deep dive
- Chapter 4: Physics System - Physics and collision systems
CacoEngine provides:
- Simple API: Easy to learn, powerful to use
- Performance: Hardware-accelerated graphics with efficient algorithms
- Flexibility: Extensible architecture for custom game requirements
- Completeness: Full game development framework with physics, rendering, and input
The engine follows modern C++ practices with automatic memory management, event-driven architecture, and component-based design, making it suitable for both beginners and experienced developers.