Godot-SpaceShooter/Scripts/GameManager.cs

146 lines
4.1 KiB
C#

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<PackedScene> 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);
}
}