using Godot; using Godot.Collections; namespace Scripts; public partial class GameManager : Node { private int asteroidMaxNumber = 3; private int asteroidNumber; public bool GameOver { get; private set; } [Export] private bool debug = true; [Export] private Array asteroids; [Export] private Node3D asteroidsContainer; [Export] private RichTextLabel labelAsteroids; [Export] private RichTextLabel labelLevel; [Export] private RichTextLabel labelLifes; [Export] private RichTextLabel labelNextLevel; [Export] private RichTextLabel labelPoints; [Export] private RichTextLabel labelDebug; [Export] private RichTextLabel labelGameOver; [Export] private Button restartButton; [Export] private RichTextLabel reachedPointsLabel; private int level = 1; public int MaxLives { get; private set; } = 10; private int lives = 10; private int nextLevelPoints = 11; private int points; private float spawnRate = 1f; private float spawnTimer; public int AsteroidNumber { get => asteroidNumber; set { asteroidNumber = value; RefreshUi(); } } public int Lives { get => lives; set { lives = value; if (lives <= 0) SetGameOver(); RefreshUi(); PlayerShip.Instance.RefreshUi(); } } public int Points { get => points; set { points = value; if (points >= nextLevelPoints) NextLevel(); RefreshUi(); } } public int Level { get => level; private set { level = value; RefreshUi(); } } private int NextLevelPoints { get => nextLevelPoints; set { nextLevelPoints = value; RefreshUi(); } } private int AsteroidMaxNumber { get => asteroidMaxNumber; set { asteroidMaxNumber = value; RefreshUi(); } } public static GameManager Instance { get; private set; } public override void _Ready() { Instance = this; Lives = MaxLives; spawnTimer = spawnRate; SoundManager.Instance.Play(SoundManager.Sound.BackgroundMusic); restartButton.Pressed += RestartButtonOnPressed; RefreshUi(); PlayerShip.Instance.RefreshUi(); } private void RestartButtonOnPressed() => GetTree().ReloadCurrentScene(); public override void _Process(double delta) { spawnTimer -= (float)delta; if (spawnTimer < 0) { if (AsteroidNumber < asteroidMaxNumber) SpawnNewAsteroid(); spawnTimer = spawnRate; } } private void SpawnNewAsteroid() { if (GameOver) return; GD.Print("Spawn new asteroid"); AsteroidNumber++; Node asteroid = asteroids.PickRandom().Instantiate(); asteroidsContainer.AddChild(asteroid); asteroid.Name = $"Asteroid{AsteroidNumber}"; } private void RefreshUi() { labelLifes.Text = $"Lives: {lives}"; labelAsteroids.Text = $"Asteroids: {asteroidNumber} / {asteroidMaxNumber}"; labelPoints.Text = $"Points: {points}"; labelNextLevel.Text = $"Next Level at: {NextLevelPoints}"; labelLevel.Text = $"Actual Level: {Level}"; labelDebug.Visible = debug; labelGameOver.Visible = GameOver; restartButton.Visible = GameOver; reachedPointsLabel.Visible = GameOver; } private void NextLevel() { GD.Print("Next Level!"); Level++; NextLevelPoints = Level * 33; AsteroidMaxNumber = 3 + Level; spawnRate = 1f - Level * 0.1f; } public void OnGameAreaBodyExited(Node body) { GD.Print($"{body.Name} leaved GameArea!"); } private void SetGameOver() { GameOver = true; reachedPointsLabel.Text = $"[center]You have reached level {Level} and {Points} points![/center]"; SoundManager.Instance.Stop(SoundManager.Sound.BackgroundMusic); SoundManager.Instance.Play(SoundManager.Sound.GameOver); } }