- **Visual Effects**: Upgraded line clear particles to use the game's block texture instead of simple circles, matching the reference web game's aesthetic. - **Particle Physics**: Tuned particle velocity, gravity, and fade rates for a more dynamic explosion effect. - **Rendering Integration**: Updated [main.cpp](cci:7://file:///d:/Sites/Work/tetris/src/main.cpp:0:0-0:0) and `GameRenderer` to pass the block texture to the effect system and correctly trigger animations upon line completion. - **Menu UI**: Fixed [MenuState](cci:1://file:///d:/Sites/Work/tetris/src/states/MenuState.cpp:19:0-19:55) layout calculations to use fixed logical dimensions (1200x1000), ensuring consistent centering and alignment of the logo, buttons, and settings icon across different window sizes. - **Code Cleanup**: Refactored `PlayingState` to delegate effect triggering to the rendering layer where correct screen coordinates are available.
4.1 KiB
4.1 KiB
Performance Optimization Recommendations
Current Performance Analysis
Memory Management
- Good: Proper RAII patterns, smart pointers
- Improvement: Object pooling for frequently created/destroyed objects
Rendering Performance
- Current: SDL3 with immediate mode rendering
- Optimization Opportunities: Batch rendering, texture atlasing
Game Logic Performance
- Current: Simple collision detection, adequate for Tetris
- Good: Efficient board representation using flat array
Specific Optimizations
1. Object Pooling for Game Pieces
// src/gameplay/PiecePool.h
class PiecePool {
private:
std::vector<std::unique_ptr<Piece>> available;
std::vector<std::unique_ptr<Piece>> inUse;
public:
std::unique_ptr<Piece> acquire(PieceType type);
void release(std::unique_ptr<Piece> piece);
void preAllocate(size_t count);
};
2. Texture Atlas for UI Elements
// src/graphics/TextureAtlas.h
class TextureAtlas {
private:
SDL_Texture* atlasTexture;
std::unordered_map<std::string, SDL_Rect> regions;
public:
void loadAtlas(const std::string& atlasPath, const std::string& configPath);
SDL_Rect getRegion(const std::string& name) const;
SDL_Texture* getTexture() const { return atlasTexture; }
};
3. Batch Rendering System
// src/graphics/BatchRenderer.h
class BatchRenderer {
private:
struct RenderCommand {
SDL_Texture* texture;
SDL_Rect srcRect;
SDL_Rect dstRect;
};
std::vector<RenderCommand> commands;
public:
void addSprite(SDL_Texture* texture, const SDL_Rect& src, const SDL_Rect& dst);
void flush();
void clear();
};
4. Memory-Efficient Board Representation
// Current: std::array<int, COLS*ROWS> board (40 integers = 160 bytes)
// Optimized: Bitset representation for filled/empty + color array for occupied cells
class OptimizedBoard {
private:
std::bitset<COLS * ROWS> occupied; // 25 bytes (200 bits)
std::array<uint8_t, COLS * ROWS> colors; // 200 bytes, but only for occupied cells
public:
bool isOccupied(int x, int y) const;
uint8_t getColor(int x, int y) const;
void setCell(int x, int y, uint8_t color);
void clearCell(int x, int y);
};
5. Cache-Friendly Data Structures
// Group related data together for better cache locality
struct GameState {
// Hot data (frequently accessed)
std::array<uint8_t, COLS * ROWS> board;
Piece currentPiece;
int score;
int level;
int lines;
// Cold data (less frequently accessed)
std::vector<PieceType> bag;
Piece holdPiece;
bool gameOver;
bool paused;
};
Performance Measurement
1. Add Profiling Infrastructure
// src/core/Profiler.h
class Profiler {
private:
std::unordered_map<std::string, std::chrono::high_resolution_clock::time_point> startTimes;
std::unordered_map<std::string, double> averageTimes;
public:
void beginTimer(const std::string& name);
void endTimer(const std::string& name);
void printStats();
};
// Usage:
// profiler.beginTimer("GameLogic");
// game.update(deltaTime);
// profiler.endTimer("GameLogic");
2. Frame Rate Optimization
// Target 60 FPS with consistent frame timing
class FrameRateManager {
private:
std::chrono::high_resolution_clock::time_point lastFrame;
double targetFrameTime = 1000.0 / 60.0; // 16.67ms
public:
void beginFrame();
void endFrame();
double getDeltaTime() const;
bool shouldSkipFrame() const;
};
Expected Performance Gains
- Object Pooling: 30-50% reduction in allocation overhead
- Texture Atlas: 20-30% improvement in rendering performance
- Batch Rendering: 40-60% reduction in draw calls
- Optimized Board: 60% reduction in memory usage
- Cache Optimization: 10-20% improvement in game logic performance
Implementation Priority
- High Impact, Low Effort: Profiling infrastructure, frame rate management
- Medium Impact, Medium Effort: Object pooling, optimized board representation
- High Impact, High Effort: Texture atlas, batch rendering system