- **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.
426 lines
12 KiB
Markdown
426 lines
12 KiB
Markdown
# Code Organization & Structure Improvements
|
|
|
|
## ✅ Progress Tracker
|
|
|
|
### Phase 1: Core Reorganization - IN PROGRESS ⚠️
|
|
|
|
**✅ Completed:**
|
|
|
|
- ✅ Created new directory structure (interfaces/, application/, assets/, input/, state/, memory/)
|
|
- ✅ Created core interfaces (IRenderer.h, IAudioSystem.h, IAssetLoader.h, IInputHandler.h, IGameRules.h)
|
|
- ✅ Created ServiceContainer for dependency injection
|
|
- ✅ Moved ApplicationManager to core/application/
|
|
- ✅ Moved AssetManager to core/assets/
|
|
- ✅ Moved InputManager to core/input/
|
|
- ✅ Moved StateManager to core/state/
|
|
- ✅ Moved Game files to gameplay/core/
|
|
- ✅ Moved Font files to graphics/ui/
|
|
- ✅ Moved Starfield files to graphics/effects/
|
|
- ✅ Moved RenderManager and GameRenderer to graphics/renderers/
|
|
- ✅ Moved LineEffect to gameplay/effects/
|
|
- ✅ Cleaned up duplicate files
|
|
- ✅ Audio and Scores files already properly located
|
|
|
|
**⚠️ Currently In Progress:**
|
|
|
|
- ✅ Updated critical include paths in main.cpp, state files, graphics renderers
|
|
- ✅ Fixed RenderManager duplicate method declarations
|
|
- ✅ Resolved GameRenderer.h and LoadingState.cpp include paths
|
|
- ⚠️ Still fixing remaining include path issues (ongoing)
|
|
- ⚠️ Still debugging Game.h redefinition errors (ongoing)
|
|
|
|
**❌ Next Steps:**
|
|
|
|
- ❌ Complete all remaining #include statement updates
|
|
- ❌ Resolve Game.h redefinition compilation errors
|
|
- ❌ Test successful compilation of both tetris and tetris_refactored targets
|
|
- ❌ Update documentation
|
|
- ❌ Begin Phase 2 - Interface implementation
|
|
|
|
### Phase 2: Interface Extraction - NOT STARTED ❌
|
|
|
|
### Phase 3: Module Separation - NOT STARTED ❌
|
|
|
|
### Phase 4: Documentation & Standards - NOT STARTED ❌
|
|
|
|
## Current Structure Analysis
|
|
|
|
### Strengths
|
|
|
|
- ✅ Clear domain separation (core/, gameplay/, graphics/, audio/, etc.)
|
|
- ✅ Consistent naming conventions
|
|
- ✅ Modern C++ header organization
|
|
- ✅ Proper forward declarations
|
|
|
|
### Areas for Improvement
|
|
|
|
- ⚠️ Some files in root src/ should be moved to appropriate subdirectories
|
|
- ⚠️ Missing interfaces/contracts
|
|
- ⚠️ Some circular dependencies
|
|
- ⚠️ CMakeLists.txt has duplicate entries
|
|
|
|
## Proposed Directory Restructure
|
|
|
|
```text
|
|
src/
|
|
├── core/ # Core engine systems
|
|
│ ├── interfaces/ # Abstract interfaces (NEW)
|
|
│ │ ├── IRenderer.h
|
|
│ │ ├── IAudioSystem.h
|
|
│ │ ├── IAssetLoader.h
|
|
│ │ ├── IInputHandler.h
|
|
│ │ └── IGameRules.h
|
|
│ ├── application/ # Application lifecycle (NEW)
|
|
│ │ ├── ApplicationManager.cpp/h
|
|
│ │ ├── ServiceContainer.cpp/h
|
|
│ │ └── SystemCoordinator.cpp/h
|
|
│ ├── assets/ # Asset management
|
|
│ │ ├── AssetManager.cpp/h
|
|
│ │ └── AssetLoader.cpp/h
|
|
│ ├── input/ # Input handling
|
|
│ │ └── InputManager.cpp/h
|
|
│ ├── state/ # State management
|
|
│ │ └── StateManager.cpp/h
|
|
│ ├── memory/ # Memory management (NEW)
|
|
│ │ ├── ObjectPool.h
|
|
│ │ └── MemoryTracker.h
|
|
│ └── Config.h
|
|
│ └── GlobalState.cpp/h
|
|
│ └── GravityManager.cpp/h
|
|
├── gameplay/ # Game logic
|
|
│ ├── core/ # Core game mechanics
|
|
│ │ ├── Game.cpp/h
|
|
│ │ ├── Board.cpp/h # Extract from Game.cpp
|
|
│ │ ├── Piece.cpp/h # Extract from Game.cpp
|
|
│ │ └── PieceFactory.cpp/h # Extract from Game.cpp
|
|
│ ├── rules/ # Game rules (NEW)
|
|
│ │ ├── ClassicTetrisRules.cpp/h
|
|
│ │ ├── ModernTetrisRules.cpp/h
|
|
│ │ └── ScoringSystem.cpp/h
|
|
│ ├── effects/ # Visual effects
|
|
│ │ └── LineEffect.cpp/h
|
|
│ └── mechanics/ # Game mechanics (NEW)
|
|
│ ├── RotationSystem.cpp/h
|
|
│ ├── KickTable.cpp/h
|
|
│ └── BagRandomizer.cpp/h
|
|
├── graphics/ # Rendering and visual
|
|
│ ├── renderers/ # Different renderers
|
|
│ │ ├── RenderManager.cpp/h
|
|
│ │ ├── GameRenderer.cpp/h
|
|
│ │ ├── UIRenderer.cpp/h # Extract from various places
|
|
│ │ └── EffectRenderer.cpp/h # New
|
|
│ ├── effects/ # Visual effects
|
|
│ │ ├── Starfield.cpp/h
|
|
│ │ ├── Starfield3D.cpp/h
|
|
│ │ └── ParticleSystem.cpp/h # New
|
|
│ ├── ui/ # UI components
|
|
│ │ ├── Font.cpp/h
|
|
│ │ ├── Button.cpp/h # New
|
|
│ │ ├── Panel.cpp/h # New
|
|
│ │ └── ScoreDisplay.cpp/h # New
|
|
│ └── resources/ # Graphics resources
|
|
│ ├── TextureAtlas.cpp/h # New
|
|
│ └── SpriteManager.cpp/h # New
|
|
├── audio/ # Audio system
|
|
│ ├── Audio.cpp/h
|
|
│ ├── SoundEffect.cpp/h
|
|
│ ├── MusicManager.cpp/h # New
|
|
│ └── AudioMixer.cpp/h # New
|
|
├── persistence/ # Data persistence
|
|
│ ├── Scores.cpp/h
|
|
│ ├── Settings.cpp/h # New
|
|
│ ├── SaveGame.cpp/h # New
|
|
│ └── Serialization.cpp/h # New
|
|
├── states/ # Game states
|
|
│ ├── State.h # Base interface
|
|
│ ├── LoadingState.cpp/h
|
|
│ ├── MenuState.cpp/h
|
|
│ ├── LevelSelectorState.cpp/h
|
|
│ ├── PlayingState.cpp/h
|
|
│ ├── PausedState.cpp/h # New
|
|
│ ├── GameOverState.cpp/h # New
|
|
│ └── SettingsState.cpp/h # New
|
|
├── network/ # Future: Multiplayer (NEW)
|
|
│ ├── NetworkManager.h
|
|
│ ├── Protocol.h
|
|
│ └── MultiplayerGame.h
|
|
├── utils/ # Utilities (NEW)
|
|
│ ├── Logger.cpp/h
|
|
│ ├── Timer.cpp/h
|
|
│ ├── MathUtils.h
|
|
│ └── StringUtils.h
|
|
├── platform/ # Platform-specific (NEW)
|
|
│ ├── Platform.h
|
|
│ ├── Windows/
|
|
│ ├── Linux/
|
|
│ └── macOS/
|
|
└── main.cpp # Keep original main
|
|
└── main_new.cpp # Refactored main
|
|
```
|
|
|
|
## Module Dependencies
|
|
|
|
### Clean Dependency Graph
|
|
|
|
```text
|
|
Application Layer: main.cpp → ApplicationManager
|
|
Core Layer: ServiceContainer → All Managers
|
|
Gameplay Layer: Game → Rules → Mechanics
|
|
Graphics Layer: RenderManager → Renderers → Resources
|
|
Audio Layer: AudioSystem → Concrete Implementations
|
|
Persistence Layer: SaveSystem → Serialization
|
|
Platform Layer: Platform Abstraction (lowest level)
|
|
```
|
|
|
|
### Dependency Rules
|
|
|
|
1. **No circular dependencies**
|
|
2. **Higher layers can depend on lower layers only**
|
|
3. **Use interfaces for cross-layer communication**
|
|
4. **Platform layer has no dependencies on other layers**
|
|
|
|
## Header Organization
|
|
|
|
### 1. Consistent Header Structure
|
|
|
|
```cpp
|
|
// Standard template for all headers
|
|
#pragma once
|
|
|
|
// System includes
|
|
#include <vector>
|
|
#include <memory>
|
|
|
|
// External library includes
|
|
#include <SDL3/SDL.h>
|
|
|
|
// Internal includes (from most general to most specific)
|
|
#include "core/interfaces/IRenderer.h"
|
|
#include "graphics/resources/Texture.h"
|
|
#include "MyClass.h"
|
|
|
|
// Forward declarations
|
|
class GameRenderer;
|
|
class TextureAtlas;
|
|
|
|
// Class definition
|
|
class MyClass {
|
|
// Public interface first
|
|
public:
|
|
// Constructors/Destructors
|
|
MyClass();
|
|
~MyClass();
|
|
|
|
// Core functionality
|
|
void update(double deltaTime);
|
|
void render();
|
|
|
|
// Getters/Setters
|
|
int getValue() const { return value; }
|
|
void setValue(int v) { value = v; }
|
|
|
|
// Private implementation
|
|
private:
|
|
// Member variables
|
|
int value{0};
|
|
std::unique_ptr<GameRenderer> renderer;
|
|
|
|
// Private methods
|
|
void initializeRenderer();
|
|
};
|
|
```
|
|
|
|
### 2. Include Guards and PCH
|
|
|
|
```cpp
|
|
// PrecompiledHeaders.h (NEW)
|
|
#pragma once
|
|
|
|
// Standard library
|
|
#include <vector>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <algorithm>
|
|
|
|
// External libraries (stable)
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3_ttf/SDL_ttf.h>
|
|
|
|
// Common project headers
|
|
#include "core/Config.h"
|
|
#include "core/interfaces/IRenderer.h"
|
|
```
|
|
|
|
## Code Style Improvements
|
|
|
|
### 1. Consistent Naming Conventions
|
|
|
|
```cpp
|
|
// Classes: PascalCase
|
|
class GameRenderer;
|
|
class TextureAtlas;
|
|
|
|
// Functions/Methods: camelCase
|
|
void updateGameLogic();
|
|
bool isValidPosition();
|
|
|
|
// Variables: camelCase
|
|
int currentScore;
|
|
double deltaTime;
|
|
|
|
// Constants: UPPER_SNAKE_CASE
|
|
const int MAX_LEVEL = 30;
|
|
const double GRAVITY_MULTIPLIER = 1.0;
|
|
|
|
// Private members: camelCase with suffix
|
|
class MyClass {
|
|
private:
|
|
int memberVariable_; // or m_memberVariable
|
|
static int staticCounter_;
|
|
};
|
|
```
|
|
|
|
### 2. Documentation Standards
|
|
|
|
```cpp
|
|
/**
|
|
* @brief Manages the core game state and logic for Tetris
|
|
*
|
|
* The Game class handles piece movement, rotation, line clearing,
|
|
* and scoring according to classic Tetris rules.
|
|
*
|
|
* @example
|
|
* ```cpp
|
|
* Game game(startLevel);
|
|
* game.reset(0);
|
|
* game.move(-1); // Move left
|
|
* game.rotate(1); // Rotate clockwise
|
|
* ```
|
|
*/
|
|
class Game {
|
|
public:
|
|
/**
|
|
* @brief Moves the current piece horizontally
|
|
* @param dx Direction to move (-1 for left, +1 for right)
|
|
* @return true if the move was successful, false if blocked
|
|
*/
|
|
bool move(int dx);
|
|
|
|
/**
|
|
* @brief Gets the current score
|
|
* @return Current score value
|
|
* @note Score never decreases during gameplay
|
|
*/
|
|
int score() const noexcept { return score_; }
|
|
};
|
|
```
|
|
|
|
## CMake Improvements
|
|
|
|
### 1. Modular CMakeLists.txt
|
|
|
|
```cmake
|
|
# CMakeLists.txt (main)
|
|
cmake_minimum_required(VERSION 3.20)
|
|
project(tetris_sdl3 LANGUAGES CXX)
|
|
|
|
# Global settings
|
|
set(CMAKE_CXX_STANDARD 20)
|
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
|
|
# Find packages
|
|
find_package(SDL3 CONFIG REQUIRED)
|
|
find_package(SDL3_ttf CONFIG REQUIRED)
|
|
|
|
# Add subdirectories
|
|
add_subdirectory(src/core)
|
|
add_subdirectory(src/gameplay)
|
|
add_subdirectory(src/graphics)
|
|
add_subdirectory(src/audio)
|
|
add_subdirectory(src/persistence)
|
|
add_subdirectory(src/states)
|
|
|
|
# Main executable
|
|
add_executable(tetris src/main.cpp)
|
|
target_link_libraries(tetris PRIVATE
|
|
tetris::core
|
|
tetris::gameplay
|
|
tetris::graphics
|
|
tetris::audio
|
|
tetris::persistence
|
|
tetris::states
|
|
)
|
|
|
|
# Tests
|
|
if(BUILD_TESTING)
|
|
add_subdirectory(tests)
|
|
endif()
|
|
```
|
|
|
|
### 2. Module CMakeLists.txt
|
|
|
|
```cmake
|
|
# src/core/CMakeLists.txt
|
|
add_library(tetris_core
|
|
ApplicationManager.cpp
|
|
StateManager.cpp
|
|
InputManager.cpp
|
|
AssetManager.cpp
|
|
GlobalState.cpp
|
|
GravityManager.cpp
|
|
)
|
|
|
|
add_library(tetris::core ALIAS tetris_core)
|
|
|
|
target_include_directories(tetris_core
|
|
PUBLIC ${CMAKE_SOURCE_DIR}/src
|
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
|
)
|
|
|
|
target_link_libraries(tetris_core
|
|
PUBLIC SDL3::SDL3 SDL3_ttf::SDL3_ttf
|
|
)
|
|
|
|
# Export for use by other modules
|
|
target_compile_features(tetris_core PUBLIC cxx_std_20)
|
|
```
|
|
|
|
## Implementation Timeline
|
|
|
|
### Phase 1: Core Reorganization (Week 1-2)
|
|
|
|
1. Create new directory structure
|
|
2. Move files to appropriate locations
|
|
3. Update CMakeLists.txt files
|
|
4. Fix include paths
|
|
|
|
### Phase 2: Interface Extraction (Week 3-4)
|
|
|
|
1. Create interface headers
|
|
2. Update implementations to use interfaces
|
|
3. Add dependency injection container
|
|
|
|
### Phase 3: Module Separation (Week 5-6)
|
|
|
|
1. Split large classes (Game, ApplicationManager)
|
|
2. Create separate CMake modules
|
|
3. Establish clean dependency graph
|
|
|
|
### Phase 4: Documentation & Standards (Week 7-8)
|
|
|
|
1. Add comprehensive documentation
|
|
2. Implement coding standards
|
|
3. Add static analysis tools
|
|
4. Update build scripts
|
|
|
|
## Benefits
|
|
|
|
1. **Maintainability**: Clear module boundaries and responsibilities
|
|
2. **Testability**: Easy to mock and test individual components
|
|
3. **Scalability**: Easy to add new features without affecting existing code
|
|
4. **Team Development**: Multiple developers can work on different modules
|
|
5. **Code Reuse**: Modular design enables component reuse
|