// ============================================== // GameManager.cs - Zentrale Spielsteuerung // ============================================== // Verwaltet Spielzustand, Score, Leben und // koordiniert alle anderen Manager. using System; using UnityEngine; using UnityEngine.SceneManagement; namespace BreakpilotDrive { public enum GameState { MainMenu, Playing, Paused, QuizActive, GameOver } public class GameManager : MonoBehaviour { public static GameManager Instance { get; private set; } [Header("Spieleinstellungen")] [SerializeField] private int startLives = 3; [SerializeField] private float pauseQuestionInterval = 500f; // Alle X Meter [Header("UI Referenzen")] [SerializeField] private GameObject gameOverPanel; [SerializeField] private GameObject pausePanel; // Spielzustand private GameState currentState = GameState.MainMenu; private int score = 0; private int lives; private float distanceTraveled = 0f; private float playTime = 0f; private float nextPauseQuestionDistance; // Schwierigkeit (von API geladen) private int currentDifficulty = 3; private GameDifficulty difficultySettings; // Events public event Action OnScoreChanged; public event Action OnLivesChanged; public event Action OnDistanceChanged; public event Action OnStateChanged; // Properties public GameState CurrentState => currentState; public int Score => score; public int Lives => lives; public float DistanceTraveled => distanceTraveled; public float PlayTime => playTime; public int CurrentDifficulty => currentDifficulty; public GameDifficulty DifficultySettings => difficultySettings; void Awake() { if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } void Start() { // UI initial verstecken if (gameOverPanel) gameOverPanel.SetActive(false); if (pausePanel) pausePanel.SetActive(false); } void Update() { if (currentState == GameState.Playing) { // Spielzeit zaehlen playTime += Time.deltaTime; // Pause-Fragen pruefen if (distanceTraveled >= nextPauseQuestionDistance) { TriggerPauseQuestion(); } // Escape fuer Pause if (Input.GetKeyDown(KeyCode.Escape)) { PauseGame(); } } else if (currentState == GameState.Paused) { if (Input.GetKeyDown(KeyCode.Escape)) { ResumeGame(); } } } // ============================================== // Spiel starten // ============================================== public void StartGame(string userId = "guest") { // Werte zuruecksetzen score = 0; lives = startLives; distanceTraveled = 0f; playTime = 0f; nextPauseQuestionDistance = pauseQuestionInterval; // Events ausloesen OnScoreChanged?.Invoke(score); OnLivesChanged?.Invoke(lives); // Schwierigkeit laden if (BreakpilotAPI.Instance != null) { StartCoroutine(BreakpilotAPI.Instance.GetLearningLevel(userId, onSuccess: (level) => { currentDifficulty = level.overall_level; LoadDifficultySettings(); } )); } else { LoadDifficultySettings(); } // Quiz-Statistik zuruecksetzen if (QuizManager.Instance != null) { QuizManager.Instance.ResetStatistics(); } SetState(GameState.Playing); } private void LoadDifficultySettings() { if (BreakpilotAPI.Instance != null) { StartCoroutine(BreakpilotAPI.Instance.GetDifficulty(currentDifficulty, onSuccess: (settings) => { difficultySettings = settings; Debug.Log($"Schwierigkeit {currentDifficulty} geladen: Speed={settings.lane_speed}"); } )); } } // ============================================== // Score-System // ============================================== public void AddScore(int points) { score = Mathf.Max(0, score + points); OnScoreChanged?.Invoke(score); } public void AddDistance(float distance) { distanceTraveled += distance; OnDistanceChanged?.Invoke(distanceTraveled); } // ============================================== // Leben-System // ============================================== public void LoseLife() { lives--; OnLivesChanged?.Invoke(lives); if (lives <= 0) { GameOver(); } } public void GainLife() { lives++; OnLivesChanged?.Invoke(lives); } // ============================================== // Pause-Fragen // ============================================== private void TriggerPauseQuestion() { nextPauseQuestionDistance += pauseQuestionInterval; if (BreakpilotAPI.Instance != null && QuizManager.Instance != null) { // Pause-Frage aus Cache holen var questions = BreakpilotAPI.Instance.GetCachedQuestions(); var pauseQuestions = questions.FindAll(q => q.quiz_mode == "pause"); if (pauseQuestions.Count > 0) { int index = UnityEngine.Random.Range(0, pauseQuestions.Count); QuizManager.Instance.ShowPauseQuestion(pauseQuestions[index]); } } } // ============================================== // Spielzustand // ============================================== public void SetState(GameState newState) { currentState = newState; OnStateChanged?.Invoke(newState); switch (newState) { case GameState.Playing: Time.timeScale = 1f; break; case GameState.Paused: case GameState.QuizActive: Time.timeScale = 0f; break; case GameState.GameOver: Time.timeScale = 0f; break; } } public void PauseGame() { if (currentState == GameState.Playing) { SetState(GameState.Paused); if (pausePanel) pausePanel.SetActive(true); } } public void ResumeGame() { if (currentState == GameState.Paused) { SetState(GameState.Playing); if (pausePanel) pausePanel.SetActive(false); } } // ============================================== // Spiel beenden // ============================================== public void GameOver() { SetState(GameState.GameOver); if (gameOverPanel) gameOverPanel.SetActive(true); // Session speichern SaveSession(); } private void SaveSession() { if (BreakpilotAPI.Instance == null) return; GameSession session = new GameSession { user_id = "guest", // TODO: Echte User-ID game_mode = "video", duration_seconds = Mathf.RoundToInt(playTime), distance_traveled = distanceTraveled, score = score, questions_answered = QuizManager.Instance?.GetQuestionsAnswered() ?? 0, questions_correct = QuizManager.Instance?.GetQuestionsCorrect() ?? 0, difficulty_level = currentDifficulty }; StartCoroutine(BreakpilotAPI.Instance.SaveGameSession(session, onSuccess: (response) => { Debug.Log($"Session gespeichert: {response.session_id}"); if (response.new_level.HasValue) { Debug.Log($"Level Up! Neues Level: {response.new_level}"); } } )); } // ============================================== // Neustart // ============================================== public void RestartGame() { if (gameOverPanel) gameOverPanel.SetActive(false); StartGame(); } public void LoadMainMenu() { Time.timeScale = 1f; SceneManager.LoadScene("MainMenu"); } } }