import 'package:flame/components.dart'; import 'package:shitman/attributes/resetable.dart'; import 'package:shitman/game/shitman_game.dart'; import 'package:shitman/game/components/base.dart'; import 'package:shitman/game/components/player.dart'; import 'package:shitman/services/log_service.dart'; import 'package:shitman/settings/app_settings.dart'; class ShitLevel extends PositionComponent with HasGameReference, Resetable, AppLogging, AppSettings { /// Base class for game levels. /// This can be extended to create specific levels with unique layouts String levelName; int difficulty; bool _isActive = false; // Core game components late Player player; ShitLevel({required this.levelName, this.difficulty = 1}); /// Whether the level is currently active bool get isActive => _isActive; @override Future onLoad() async { await super.onLoad(); await initSettings(); // Initialize level-specific components await initializeLevelComponents(); appLog.fine('Level loaded: $levelName (difficulty: $difficulty)'); } /// Initialize the core components for this level Future initializeLevelComponents() async { appLog.fine('Initializing level components for $levelName'); // Create player player = Player(); add(player); // Setup camera to follow player if game reference is available try { game.camera.follow(player); } catch (e) { appLog.warning('Unable to setup camera following: $e'); } appLog.fine('Level components initialized'); } /// Start the level gameplay Future startLevel() async { if (_isActive) return; _isActive = true; appLog.info('Starting level: $levelName'); // Any level-specific start logic can be added here await onLevelStart(); } /// End the level gameplay Future endLevel() async { if (!_isActive) return; _isActive = false; appLog.info('Ending level: $levelName'); // Any level-specific end logic can be added here await onLevelEnd(); } /// Override this method in subclasses for custom start logic Future onLevelStart() async { // Default implementation does nothing } /// Override this method in subclasses for custom end logic Future onLevelEnd() async { // Default implementation does nothing } /// Get all components in this level that implement Resetable List getResetableComponents() { return children.whereType().toList(); } /// Get all ShitComponents in this level List getAllShitComponents() { return children.whereType().toList(); } /// Reset all components in this level Future resetAllComponents() async { appLog.fine('Resetting all components in level: $levelName'); final resetableComponents = getResetableComponents(); for (final component in resetableComponents) { await component.reset(); } } @override Future reset() async { appLog.fine('Resetting level: $levelName'); _isActive = false; // Reset all child components first await resetAllComponents(); // Override in subclasses for additional reset logic await onLevelReset(); } /// Override this method in subclasses for custom reset logic Future onLevelReset() async { // Default implementation does nothing } }