Initial commit: breakpilot-lehrer - Lehrer KI Platform
Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website, Klausur-Service, School-Service, Voice-Service, Geo-Service, BreakPilot Drive, Agent-Core Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
317
breakpilot-drive/UnityScripts/Core/GameManager.cs
Normal file
317
breakpilot-drive/UnityScripts/Core/GameManager.cs
Normal file
@@ -0,0 +1,317 @@
|
||||
// ==============================================
|
||||
// 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<int> OnScoreChanged;
|
||||
public event Action<int> OnLivesChanged;
|
||||
public event Action<float> OnDistanceChanged;
|
||||
public event Action<GameState> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user