Scene¶
Represents a game level or screen containing entities.
Description¶
A Scene manages a collection of Entities and a CollisionSystem. It is responsible for updating and drawing all entities it contains. Scenes provide lifecycle hooks (init(), update(), draw()) to manage gameplay segments.
Scenes are the primary organizational unit in PixelRoot32, similar to levels or screens in other game engines. Each scene can contain up to MAX_ENTITIES (32) entities.
Namespace¶
Inheritance¶
- Base class: None (abstract base class)
- Inherited by: Your custom scene classes (e.g.,
MainMenuScene,GameScene)
Constructors¶
Scene()¶
Creates an empty scene ready to be populated with entities.
Notes: - The scene starts with no entities - init() should be called when the scene becomes active - The collision system is automatically initialized
Example:
class MyScene : public pixelroot32::core::Scene {
public:
void init() override {
// Initialize scene resources
}
void update(unsigned long deltaTime) override {
Scene::update(deltaTime); // Update entities and collisions
}
void draw(pixelroot32::graphics::Renderer& renderer) override {
Scene::draw(renderer); // Draw all entities
}
};
Public Methods¶
virtual void init()¶
Initializes the scene. Called when entering the scene.
Returns: - void
Notes: - Called automatically when the scene is set via Engine::setScene() - Override this method to initialize scene-specific resources - Safe to call multiple times (idempotent) - Add entities here or in the constructor
Example:
class GameScene : public pixelroot32::core::Scene {
private:
PlayerActor* player;
std::array<EnemyActor*, 10> enemies;
public:
void init() override {
// Create player
player = new PlayerActor();
addEntity(player);
// Create enemies
for (int i = 0; i < 10; i++) {
enemies[i] = new EnemyActor();
addEntity(enemies[i]);
}
}
};
virtual void update(unsigned long deltaTime)¶
Updates all entities in the scene and handles collisions.
Parameters: - deltaTime (unsigned long): Time elapsed since last frame in milliseconds
Notes: - Called automatically by the engine every frame - Updates all entities in the scene - Processes collisions between actors - Override to add custom update logic, but call Scene::update(deltaTime) to maintain entity updates
Example:
void update(unsigned long deltaTime) override {
// Custom update logic
gameTimer += deltaTime;
// Update entities and collisions
Scene::update(deltaTime);
// Additional logic after entity updates
if (gameTimer > 60000) {
// Game over after 60 seconds
}
}
virtual void draw(Renderer& renderer)¶
Draws all visible entities in the scene.
Parameters: - renderer (pixelroot32::graphics::Renderer&): The renderer to use for drawing
Notes: - Called automatically by the engine every frame after update() - Draws all visible entities in the scene - Override to add custom drawing logic, but call Scene::draw(renderer) to maintain entity rendering - Entities are drawn in the order they were added
Example:
void draw(pixelroot32::graphics::Renderer& renderer) override {
// Draw background
renderer.drawTileMap(backgroundTileMap, 0, 0, Color::White);
// Draw all entities
Scene::draw(renderer);
// Draw UI overlay
renderer.drawText("Score: 100", 10, 10, Color::White, 1);
}
void addEntity(Entity* entity)¶
Adds an entity to the scene.
Parameters: - entity (Entity*): Pointer to the Entity to add. Must not be nullptr.
Notes: - Entities are added to an internal queue - Maximum of MAX_ENTITIES (32) entities per scene - If the limit is reached, the entity may not be added (check return value if available) - Entities are updated and drawn in the order they were added - The entity's lifetime is managed by the scene (do not delete manually while in scene)
Example:
void init() override {
// Create and add player
PlayerActor* player = new PlayerActor();
player->setPosition(64, 64);
addEntity(player);
// Create and add enemy
EnemyActor* enemy = new EnemyActor();
enemy->setPosition(100, 100);
addEntity(enemy);
}
void removeEntity(Entity* entity)¶
Removes an entity from the scene.
Parameters: - entity (Entity*): Pointer to the Entity to remove
Notes: - The entity is removed from the update and draw queues - The entity is not deleted automatically (you must manage its lifetime) - Safe to call even if the entity is not in the scene - Consider using object pooling instead of frequent add/remove
Example:
void onEnemyDestroyed(EnemyActor* enemy) {
removeEntity(enemy);
// Return to pool or delete
enemyPool.returnToPool(enemy);
}
void clearEntities()¶
Removes all entities from the scene.
Notes: - All entities are removed from the update and draw queues - Entities are not deleted automatically (you must manage their lifetimes) - Useful for scene cleanup or reset - Consider using object pooling to reuse entities
Example:
void reset() {
clearEntities();
// Return all entities to pool
for (auto* entity : entityPool) {
entityPool.returnToPool(entity);
}
}
Protected Members¶
ArduinoQueue entities¶
Queue of entities in the scene. Accessible to derived classes for custom entity management.
Type: ArduinoQueue<Entity*>
Notes: - Maximum capacity: MAX_ENTITIES (32) - Direct access allows custom iteration or filtering - Use with caution: modifying while iterating may cause issues
CollisionSystem collisionSystem¶
System to handle collisions between actors. Accessible to derived classes for custom collision handling.
Type: pixelroot32::physics::CollisionSystem
Notes: - Automatically processes collisions between actors - Uses collision layers and masks for filtering - Can be accessed for custom collision queries
MAX_ENTITIES Constant¶
The maximum number of entities allowed per scene.
Value: 32
Notes: - Hard limit: cannot be changed without modifying engine code - Includes all entity types: actors, UI elements, particles, etc. - Plan your entity usage carefully - Use object pooling to reuse entities instead of creating new ones
Usage Example¶
#include "core/Scene.h"
#include "core/Actor.h"
class MyGameScene : public pixelroot32::core::Scene {
private:
PlayerActor* player;
public:
void init() override {
// Create player
player = new PlayerActor();
player->setPosition(64, 64);
addEntity(player);
// Create some enemies
for (int i = 0; i < 5; i++) {
EnemyActor* enemy = new EnemyActor();
enemy->setPosition(10 + i * 20, 10);
addEntity(enemy);
}
}
void update(unsigned long deltaTime) override {
// Custom game logic
if (player->isDead()) {
// Handle game over
}
// Update entities and collisions
Scene::update(deltaTime);
}
void draw(pixelroot32::graphics::Renderer& renderer) override {
// Draw background
renderer.drawFilledRectangle(0, 0, 128, 128, Color::Black);
// Draw all entities
Scene::draw(renderer);
// Draw HUD
char scoreText[32];
snprintf(scoreText, sizeof(scoreText), "Score: %d", score);
renderer.drawText(scoreText, 10, 10, Color::White, 1);
}
};
Performance Considerations¶
- Entity limit:
MAX_ENTITIES = 32is a hard limit; plan accordingly - Add/Remove: Frequent add/remove operations can be expensive; use object pooling
- Update order: Entities are updated in add order; consider order for dependencies
- Collision checks: CollisionSystem automatically handles actor collisions efficiently
ESP32 Considerations¶
- Memory: Each entity consumes memory; stay well below the limit
- Object pooling: Essential for ESP32 to avoid memory fragmentation
- Scene switching: Clearing and recreating scenes can fragment memory; reuse scenes when possible
See Also¶
- Entity - Base entity class
- Actor - Entity with collision support
- PhysicsActor - Entity with physics
- CollisionSystem - Collision detection
- Manual - Scenes and Entities
- API Overview