2023-11-20 09:35:59 +00:00
|
|
|
using Godot;
|
|
|
|
|
using System;
|
|
|
|
|
|
|
|
|
|
public partial class game : Node2D
|
|
|
|
|
{
|
2025-04-19 22:33:53 +00:00
|
|
|
private Node _lasers;
|
2025-04-23 01:16:21 +00:00
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private player _player;
|
2025-04-23 01:16:21 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Node _asteroids;
|
2025-04-23 01:16:21 +00:00
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private wavecontroller _waveController;
|
2025-04-23 01:16:21 +00:00
|
|
|
|
|
|
|
|
private CenterContainer _pauseMenu;
|
|
|
|
|
|
|
|
|
|
private Control _pauseControl;
|
2023-12-08 14:21:45 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Node _friendlies;
|
2025-04-18 01:07:51 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Node _enemies;
|
2025-04-18 01:07:51 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Node _ships;
|
2025-04-18 01:07:51 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Control _hud;
|
2023-12-09 07:49:33 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Label _scoreLabel;
|
2023-12-09 07:49:33 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Label _healthLabel;
|
2024-08-15 17:12:48 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private Label _flightAssistLabel;
|
2024-08-15 21:55:44 +00:00
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private Label _waveCounterLabel;
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private hud _h;
|
2025-04-22 04:43:03 +00:00
|
|
|
|
|
|
|
|
private int _score;
|
2023-12-09 07:49:33 +00:00
|
|
|
|
|
|
|
|
|
2025-04-23 16:20:00 +00:00
|
|
|
private readonly PackedScene _asteroidScene = GD.Load<PackedScene>("res://scenes/entities/asteroid.tscn");
|
2023-11-20 09:35:59 +00:00
|
|
|
|
2023-12-09 07:49:33 +00:00
|
|
|
|
2023-11-20 09:35:59 +00:00
|
|
|
public override void _Ready()
|
|
|
|
|
{
|
2025-04-22 04:43:03 +00:00
|
|
|
_waveController = GetNode<wavecontroller>("WaveController");
|
2025-04-19 22:33:53 +00:00
|
|
|
_hud = GetNode<Control>("UI/HUD");
|
2025-04-22 04:43:03 +00:00
|
|
|
_scoreLabel = GetNode<Label>("UI/HUD/Layout/Score");
|
|
|
|
|
_flightAssistLabel = GetNode<Label>("UI/HUD/Layout/FlightAssist");
|
2025-04-23 01:16:21 +00:00
|
|
|
_pauseMenu = GetNode<CenterContainer>("UI/PauseControl/PauseMenu");
|
|
|
|
|
_pauseControl = GetNode<Control>("UI/PauseControl");
|
2025-04-22 04:43:03 +00:00
|
|
|
|
2024-08-15 17:12:48 +00:00
|
|
|
//HealthLabel = GetNode<Label>("UI/HUD/Health");
|
2025-04-19 22:33:53 +00:00
|
|
|
_asteroids = GetNode<Node>("Asteroids");
|
2023-12-08 14:21:45 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
_lasers = GetNode<Node>("Lasers");
|
2025-04-22 04:43:03 +00:00
|
|
|
_ships = GetNode<Node>("WaveController/Ships");
|
|
|
|
|
_enemies = GetNode<Node>("WaveController/Ships/Enemy");
|
|
|
|
|
_friendlies = GetNode<Node>("WaveController/Ships/Friendly");
|
|
|
|
|
_player = GetNode<player>("WaveController/Ships/Friendly/Player");
|
2025-04-18 23:21:19 +00:00
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
NewWave();
|
|
|
|
|
|
|
|
|
|
//var p = new player();
|
|
|
|
|
//p.LaserShot += OnPlayerLaserShot;
|
|
|
|
|
}
|
2025-04-18 23:21:19 +00:00
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private void SetupAISignals()
|
|
|
|
|
{
|
2025-04-18 23:21:19 +00:00
|
|
|
//AI fighter signals
|
2025-04-19 22:33:53 +00:00
|
|
|
foreach (Node node in _enemies.GetChildren())
|
2025-04-18 23:21:19 +00:00
|
|
|
{
|
2025-04-22 04:43:03 +00:00
|
|
|
if (node is not ai_fighter ai) continue;
|
|
|
|
|
//GD.Print("Connected laser signal for: ", ai.Name);
|
|
|
|
|
ai.LaserShot += OnAILaserShot;
|
|
|
|
|
ai.OnDeath += OnAIDeath;
|
2025-04-18 23:21:19 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
foreach (Node node in _friendlies.GetChildren())
|
2025-04-18 23:21:19 +00:00
|
|
|
{
|
2025-04-22 04:43:03 +00:00
|
|
|
switch (node)
|
2025-04-18 23:21:19 +00:00
|
|
|
{
|
2025-04-22 04:43:03 +00:00
|
|
|
case player:
|
|
|
|
|
continue;
|
|
|
|
|
case ai_fighter ai:
|
|
|
|
|
if (ai.SignalsConnected) break;
|
|
|
|
|
//GD.Print("Connected laser signal for: ", ai.Name);
|
|
|
|
|
|
|
|
|
|
ai.LaserShot += OnAILaserShot;
|
|
|
|
|
ai.OnDeath += OnAIDeath;
|
|
|
|
|
ai.SignalsConnected = true;
|
|
|
|
|
break;
|
2025-04-18 23:21:19 +00:00
|
|
|
}
|
|
|
|
|
}
|
2025-04-22 04:43:03 +00:00
|
|
|
}
|
2025-04-18 23:21:19 +00:00
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private void NewWave()
|
|
|
|
|
{
|
|
|
|
|
_waveController.CurrWave++;
|
|
|
|
|
_waveController.StartWave();
|
|
|
|
|
UpdateWaveCounterLabel();
|
|
|
|
|
SetupAISignals();
|
|
|
|
|
|
|
|
|
|
if (_waveController.CurrWave % 2 == 0)
|
|
|
|
|
{
|
2025-04-23 01:16:21 +00:00
|
|
|
_player.HealShip(100); // heal ship by 100 at the start of each 2nd round
|
2025-04-22 04:43:03 +00:00
|
|
|
}
|
2023-12-08 14:21:45 +00:00
|
|
|
}
|
2025-04-23 01:16:21 +00:00
|
|
|
|
2024-08-12 18:47:47 +00:00
|
|
|
public override void _Process(double delta)
|
|
|
|
|
{
|
|
|
|
|
if (Input.IsActionJustPressed("reset"))
|
2023-12-09 07:49:33 +00:00
|
|
|
{
|
|
|
|
|
GetTree().ReloadCurrentScene();
|
|
|
|
|
}
|
2024-08-15 21:55:44 +00:00
|
|
|
|
|
|
|
|
if (Input.IsActionJustPressed("toggle_fa"))
|
|
|
|
|
{
|
|
|
|
|
UpdateFALabel();
|
|
|
|
|
}
|
2025-04-23 01:16:21 +00:00
|
|
|
|
2025-04-19 22:24:46 +00:00
|
|
|
//AUTO SPAWN AFTER CLEAR
|
2025-04-19 22:33:53 +00:00
|
|
|
if (_asteroids.GetChildCount() == 0)
|
2024-08-16 10:18:44 +00:00
|
|
|
{
|
|
|
|
|
Random rand = new Random();
|
|
|
|
|
for (int i = 0; i < rand.Next(1, 5); i++)
|
|
|
|
|
{
|
|
|
|
|
SpawnAsteroid(new Vector2(rand.Next(10, 800), rand.Next(10, 800)), (int)asteroid.AsteroidSize.LARGE);
|
|
|
|
|
}
|
2025-04-19 22:24:46 +00:00
|
|
|
}
|
2025-04-22 04:43:03 +00:00
|
|
|
|
|
|
|
|
if (_enemies.GetChildCount() == 0)
|
|
|
|
|
{
|
|
|
|
|
NewWave();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//if enemies == 0 -> spawn new wave, connect signals for new ships
|
|
|
|
|
|
2024-08-12 18:47:47 +00:00
|
|
|
}
|
2023-12-09 07:49:33 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void SpawnAsteroid(Vector2 position, int size)
|
2023-12-08 14:21:45 +00:00
|
|
|
{
|
|
|
|
|
var a = new asteroid();
|
2025-04-19 22:24:46 +00:00
|
|
|
a = _asteroidScene.Instantiate<asteroid>();
|
2023-12-08 14:21:45 +00:00
|
|
|
a.GlobalPosition = position;
|
2025-04-19 22:24:46 +00:00
|
|
|
a.Size = (asteroid.AsteroidSize)size;
|
2023-12-08 14:21:45 +00:00
|
|
|
a.Exploded += OnAsteroidExploded;
|
2025-04-19 22:33:53 +00:00
|
|
|
_asteroids.CallDeferred("add_child", a);
|
2023-11-20 09:35:59 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void UpdateScoreLabel(int score)
|
2023-12-09 07:49:33 +00:00
|
|
|
{
|
|
|
|
|
/*var h = new hud();
|
|
|
|
|
GD.Print(h.Score);
|
|
|
|
|
h.Score.Text = "SCORE: " + score.ToString();
|
|
|
|
|
GD.Print(h.Score.Text);*/
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
_scoreLabel.Text = "SCORE: " + score.ToString();
|
2024-08-12 18:47:47 +00:00
|
|
|
}
|
2023-12-09 07:49:33 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void UpdateHealthLabel(int health)
|
2024-08-15 17:12:48 +00:00
|
|
|
{
|
2025-04-22 04:43:03 +00:00
|
|
|
_healthLabel = GetNode<Label>("UI/HUD/Layout/Health");
|
2025-04-19 22:33:53 +00:00
|
|
|
_healthLabel.Text = "HEALTH: " + health.ToString();
|
2024-08-15 17:12:48 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void UpdateFALabel()
|
2024-08-15 21:55:44 +00:00
|
|
|
{
|
|
|
|
|
// Bit of a hacky implementation I think, but it works.
|
2025-04-19 22:33:53 +00:00
|
|
|
if (_flightAssistLabel.Text == "FA: OFF"){_flightAssistLabel.Text = "FA: ON";}
|
|
|
|
|
else if (_flightAssistLabel.Text == "FA: ON"){_flightAssistLabel.Text = "FA: OFF";}
|
2024-08-15 21:55:44 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private void UpdateWaveCounterLabel()
|
|
|
|
|
{
|
|
|
|
|
_healthLabel = GetNode<Label>("UI/HUD/Layout/WaveCounter");
|
|
|
|
|
_healthLabel.Text = "WAVE: " + _waveController.CurrWave.ToString();
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-08 14:21:45 +00:00
|
|
|
//Signals and Connections
|
2025-04-19 22:33:53 +00:00
|
|
|
private void OnAILaserShot(Area2D laser)
|
2025-04-18 23:21:19 +00:00
|
|
|
{
|
2025-04-19 22:33:53 +00:00
|
|
|
_lasers.AddChild(laser);
|
2025-04-18 23:21:19 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void OnPlayerLaserShot(Area2D laser)
|
2023-11-20 09:35:59 +00:00
|
|
|
{
|
2025-04-20 17:27:34 +00:00
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
_lasers.AddChild(laser);
|
2025-04-23 04:33:38 +00:00
|
|
|
//GD.Print(laser.Position);
|
|
|
|
|
//GD.Print(_player.Position);
|
2023-11-20 09:35:59 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void OnPlayerHealthUpdate(int health)
|
2024-08-15 17:12:48 +00:00
|
|
|
{
|
|
|
|
|
UpdateHealthLabel(health);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:33:53 +00:00
|
|
|
private void OnPlayerDeath()
|
2024-08-16 10:18:44 +00:00
|
|
|
{
|
2025-04-23 15:11:14 +00:00
|
|
|
GetTree().Paused = true;
|
|
|
|
|
GetNode<game_over>("UI/PauseControl/GameOver").Visible = true;
|
2025-04-23 16:20:00 +00:00
|
|
|
GetNode<AudioStreamPlayer2D>("UI/PauseControl/GameOver/ExplodeSFX").Play();
|
2025-04-19 22:24:46 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-22 04:43:03 +00:00
|
|
|
private void OnAIDeath(int factionInt)
|
|
|
|
|
{
|
|
|
|
|
ship.ShipFaction faction = (ship.ShipFaction)factionInt;
|
|
|
|
|
switch (faction)
|
|
|
|
|
{
|
|
|
|
|
case ship.ShipFaction.ENEMY:
|
|
|
|
|
_score += 500;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ship.ShipFaction.FRIENDLY:
|
|
|
|
|
_score -= 150;
|
|
|
|
|
if (_score < 0) _score = 0;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ship.ShipFaction.ACE:
|
|
|
|
|
_score += 1000;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
UpdateScoreLabel(_score);
|
|
|
|
|
}
|
|
|
|
|
|
2025-04-19 22:24:46 +00:00
|
|
|
private void SafeReloadScene()
|
|
|
|
|
{
|
|
|
|
|
GD.Print("Reloading scene");
|
|
|
|
|
GetTree().ReloadCurrentScene();
|
2024-08-16 10:18:44 +00:00
|
|
|
}
|
|
|
|
|
|
2025-04-21 18:07:15 +00:00
|
|
|
private void OnAsteroidExploded(Vector2 pos, int size, ship shooter)
|
2023-12-08 14:21:45 +00:00
|
|
|
{
|
2025-04-23 04:33:38 +00:00
|
|
|
//GD.Print($"DEBUG: Asteroid exploded at {pos}, size: {size}");
|
2025-04-21 18:07:15 +00:00
|
|
|
|
|
|
|
|
switch (size)
|
2025-04-16 17:57:16 +00:00
|
|
|
{
|
2025-04-21 18:07:15 +00:00
|
|
|
case 0:
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 2; i++){
|
|
|
|
|
SpawnAsteroid(pos, (int)asteroid.AsteroidSize.MEDIUM);
|
|
|
|
|
}
|
|
|
|
|
if (shooter is not player) return;
|
|
|
|
|
_score += 60;
|
|
|
|
|
break;
|
2023-12-08 14:21:45 +00:00
|
|
|
}
|
2025-04-21 18:07:15 +00:00
|
|
|
case 1:
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < 2; i++){
|
|
|
|
|
SpawnAsteroid(pos, (int)asteroid.AsteroidSize.SMALL);
|
|
|
|
|
}
|
|
|
|
|
if (shooter is not player) return;
|
|
|
|
|
_score += 40;
|
|
|
|
|
break;
|
2023-12-08 14:21:45 +00:00
|
|
|
}
|
2025-04-21 18:07:15 +00:00
|
|
|
case 2:
|
|
|
|
|
if (shooter is not player) return;
|
|
|
|
|
_score += 20;
|
|
|
|
|
break;
|
2023-12-08 14:21:45 +00:00
|
|
|
}
|
2025-04-19 22:33:53 +00:00
|
|
|
GD.Print(_score);
|
|
|
|
|
UpdateScoreLabel(_score);
|
2023-12-08 14:21:45 +00:00
|
|
|
}
|
2023-11-20 09:35:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|