-feat: implement ai laser collision and health, add health display to ai ships, player takes dmg from ai ships.

This commit is contained in:
rsxri 2025-04-19 23:24:46 +01:00
parent 3799687ae5
commit 4c561f7e02
13 changed files with 230 additions and 120 deletions

View file

@ -1,16 +1,20 @@
[gd_scene load_steps=4 format=3 uid="uid://3e6fmds2x8q5"] [gd_scene load_steps=6 format=3 uid="uid://3e6fmds2x8q5"]
[ext_resource type="Texture2D" uid="uid://soden53qtfxf" path="res://assets/Ships/Fighters/Enemy/enemyFighter.png" id="1_4l75b"] [ext_resource type="Texture2D" uid="uid://soden53qtfxf" path="res://assets/Ships/Fighters/Enemy/enemyFighter.png" id="1_4l75b"]
[ext_resource type="Script" path="res://script/ai_fighter.cs" id="1_kyds1"] [ext_resource type="Script" path="res://script/ai_fighter.cs" id="1_kyds1"]
[ext_resource type="FontFile" uid="uid://ryhimaxr7tr4" path="res://assets/Fonts/Kenney Mini Square.ttf" id="3_8bw2f"]
[sub_resource type="CircleShape2D" id="CircleShape2D_6vq6f"] [sub_resource type="CircleShape2D" id="CircleShape2D_6vq6f"]
radius = 41.0488 radius = 41.0488
[sub_resource type="LabelSettings" id="LabelSettings_lim1q"]
font = ExtResource("3_8bw2f")
font_size = 40
[node name="AI_Fighter" type="CharacterBody2D"] [node name="AI_Fighter" type="CharacterBody2D"]
collision_mask = 13
motion_mode = 1 motion_mode = 1
script = ExtResource("1_kyds1") script = ExtResource("1_kyds1")
type = 1
faction = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_6vq6f") shape = SubResource("CircleShape2D_6vq6f")
@ -22,3 +26,24 @@ texture = ExtResource("1_4l75b")
position = Vector2(0, -58) position = Vector2(0, -58)
[node name="EffectSpawn" type="Node2D" parent="."] [node name="EffectSpawn" type="Node2D" parent="."]
[node name="HealthDisplay" type="Node2D" parent="."]
position = Vector2(-30, 90)
scale = Vector2(1.2, 1.2)
[node name="HealthLabel" type="Label" parent="HealthDisplay"]
offset_right = 65.0
offset_bottom = 50.0
text = "100"
label_settings = SubResource("LabelSettings_lim1q")
horizontal_alignment = 1
[node name="HPLabel" type="Label" parent="HealthDisplay"]
offset_left = 62.0
offset_top = -2.0
offset_right = 127.0
offset_bottom = 48.0
scale = Vector2(0.5, 0.5)
text = "HP"
label_settings = SubResource("LabelSettings_lim1q")
horizontal_alignment = 1

View file

@ -22,11 +22,9 @@ position = Vector2(1228, 195)
[node name="Asteroid2" parent="Asteroids" instance=ExtResource("3_b8wlr")] [node name="Asteroid2" parent="Asteroids" instance=ExtResource("3_b8wlr")]
position = Vector2(332, 661) position = Vector2(332, 661)
size = 1
[node name="Asteroid3" parent="Asteroids" instance=ExtResource("3_b8wlr")] [node name="Asteroid3" parent="Asteroids" instance=ExtResource("3_b8wlr")]
position = Vector2(1450, 641) position = Vector2(1450, 641)
size = 2
[node name="Asteroid4" parent="Asteroids" instance=ExtResource("3_b8wlr")] [node name="Asteroid4" parent="Asteroids" instance=ExtResource("3_b8wlr")]
position = Vector2(769, 202) position = Vector2(769, 202)
@ -41,20 +39,20 @@ position = Vector2(387, 230)
[node name="Player" parent="Ships/Friendly" instance=ExtResource("1_1w06w")] [node name="Player" parent="Ships/Friendly" instance=ExtResource("1_1w06w")]
position = Vector2(959, 539) position = Vector2(959, 539)
scale = Vector2(0.6, 0.6) scale = Vector2(0.6, 0.6)
collision_layer = 8
type = 2
[node name="AI_Fighter" parent="Ships/Friendly" instance=ExtResource("5_nkk10")] [node name="AI_Fighter" parent="Ships/Friendly" instance=ExtResource("5_nkk10")]
position = Vector2(1151, 378) position = Vector2(1229, 430)
scale = Vector2(0.6, 0.6) scale = Vector2(0.6, 0.6)
faction = 1 type = 0
Faction = 1
[node name="Enemy" type="Node" parent="Ships"] [node name="Enemy" type="Node" parent="Ships"]
[node name="AI_Fighter" parent="Ships/Enemy" instance=ExtResource("5_nkk10")] [node name="AI_Fighter" parent="Ships/Enemy" instance=ExtResource("5_nkk10")]
position = Vector2(992, 205) position = Vector2(952, 214)
scale = Vector2(0.6, 0.6) scale = Vector2(0.6, 0.6)
type = 0 type = 0
Faction = 2
[connection signal="Exploded" from="Asteroids/Asteroid" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid" to="." method="OnAsteroidExploded"]
[connection signal="Exploded" from="Asteroids/Asteroid2" to="." method="OnAsteroidExploded"] [connection signal="Exploded" from="Asteroids/Asteroid2" to="." method="OnAsteroidExploded"]

View file

@ -8,10 +8,9 @@
radius = 41.0488 radius = 41.0488
[node name="Player" type="CharacterBody2D"] [node name="Player" type="CharacterBody2D"]
collision_mask = 5 collision_mask = 13
motion_mode = 1 motion_mode = 1
script = ExtResource("1_lhmq0") script = ExtResource("1_lhmq0")
color = 1
[node name="CollisionShape2D" type="CollisionShape2D" parent="."] [node name="CollisionShape2D" type="CollisionShape2D" parent="."]
shape = SubResource("CircleShape2D_btpq3") shape = SubResource("CircleShape2D_btpq3")

View file

@ -7,6 +7,7 @@
radius = 41.0488 radius = 41.0488
[node name="Ship" type="CharacterBody2D"] [node name="Ship" type="CharacterBody2D"]
collision_mask = 13
motion_mode = 1 motion_mode = 1
script = ExtResource("1_u8ww1") script = ExtResource("1_u8ww1")

View file

@ -6,6 +6,8 @@ public partial class Laser : Area2D
[Export] [Export]
public int Speed { get; set;} = 2000; public int Speed { get; set;} = 2000;
public ship Shooter;
public Vector2 MovementVector { get; set; } = new Vector2(0, -1); public Vector2 MovementVector { get; set; } = new Vector2(0, -1);
@ -13,6 +15,11 @@ public partial class Laser : Area2D
{ {
QueueFree(); QueueFree();
} }
public override void _Ready()
{
Connect("body_entered", new Callable(this, nameof(OnBodyEntered)));
}
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
GlobalPosition += MovementVector.Rotated(Rotation) * Speed * (float)delta; GlobalPosition += MovementVector.Rotated(Rotation) * Speed * (float)delta;
@ -26,4 +33,37 @@ public partial class Laser : Area2D
QueueFree(); QueueFree();
} }
} }
private bool ValidTargetFaction(ship body)
{
return Shooter.Faction switch
{
ship.ShipFaction.PLAYER => body.Faction is ship.ShipFaction.ENEMY or ship.ShipFaction.ACE,
ship.ShipFaction.ENEMY => body.Faction is ship.ShipFaction.FRIENDLY or ship.ShipFaction.PLAYER,
ship.ShipFaction.FRIENDLY => body.Faction is ship.ShipFaction.ENEMY or ship.ShipFaction.ACE,
ship.ShipFaction.ACE => body.Faction is ship.ShipFaction.FRIENDLY or ship.ShipFaction.PLAYER,
_ => throw new ArgumentOutOfRangeException() // thank you rider very cool
};
}
private void OnBodyEntered(Node body)
{
GD.Print("Laser hit something: ", body.Name);
if (body is ship target)
{
if (Shooter != null && !ValidTargetFaction(target))
{
GD.Print("friendly fire");
QueueFree();
return; // prevent friendly fire
}
else
{
GD.Print("Hit type: ", body.GetType());
target.ShipDamage(Shooter.Damage);
QueueFree();
}
}
}
} }

View file

@ -11,6 +11,9 @@ public partial class ai_fighter : ship
[Export] [Export]
public float EngageDistance = 300f; public float EngageDistance = 300f;
private Label HealthLabel;
private Label HPLabel;
//retreat logic //retreat logic
private float previousDistance = 0f; private float previousDistance = 0f;
private float stuckTime = 0f; private float stuckTime = 0f;
@ -24,10 +27,19 @@ public partial class ai_fighter : ship
SetShipStats(); SetShipStats();
SetupVisual(); SetupVisual();
Sprite.Texture = GD.Load<Texture2D>(spritePath); Sprite.Texture = GD.Load<Texture2D>(spritePath);
HealthLabel = GetNode<Label>("HealthDisplay/HealthLabel");
UpdateHealthLabel(Health);
LaserSpawn = GetNode<Node2D>("LaserSpawn"); LaserSpawn = GetNode<Node2D>("LaserSpawn");
} }
public override void _Process(double delta)
{
base._Process(delta);
HealthLabel.GetParent<Node2D>().GlobalRotation = 0f;
}
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
UpdateMovement(delta); UpdateMovement(delta);
@ -41,7 +53,27 @@ public partial class ai_fighter : ship
return; return;
} }
private void UpdateHealthLabel(int health)
{
HealthLabel.Text = health.ToString();
float percentage = (float)Health / MaxHealth;
HealthLabel.Modulate = percentage switch
{
<= 0.25f => new Color(1f, 0f, 0f),
<= 0.5f => new Color(1f, 0.5f, 0f),
<= 0.75f => new Color(1f, 1f, 0f),
_ => new Color(0.07f,0.6f, 0.07f)
}; // thank you rider
}
// COMBAT // COMBAT
public override void ShipDamage(int damage)
{
base.ShipDamage(damage);
UpdateHealthLabel(Health);
}
private void HandleFiring(double delta) private void HandleFiring(double delta)
{ {
//GD.Print(Name, ": checking fire"); //GD.Print(Name, ": checking fire");
@ -78,11 +110,11 @@ public partial class ai_fighter : ship
float closestDistance = Mathf.Inf; float closestDistance = Mathf.Inf;
Node shipParent = null; Node shipParent = null;
if (faction == ShipFaction.FRIENDLY) if (Faction == ShipFaction.FRIENDLY)
{ {
shipParent = GetTree().Root.GetNode("Game/Ships/Enemy"); shipParent = GetTree().Root.GetNode("Game/Ships/Enemy");
} }
else if (faction == ShipFaction.ENEMY || faction == ShipFaction.ACE) else if (Faction == ShipFaction.ENEMY || Faction == ShipFaction.ACE)
{ {
shipParent = GetTree().Root.GetNode("Game/Ships/Friendly"); shipParent = GetTree().Root.GetNode("Game/Ships/Friendly");
} }
@ -133,7 +165,7 @@ public partial class ai_fighter : ship
private void HandleThrust(float angleDiff, float distance) private void HandleThrust(float angleDiff, float distance)
{ {
GD.Print(Name, " | angleDiff: ", Mathf.RadToDeg(angleDiff), " | velocity: ", Velocity.Length()); //GD.Print(Name, " | angleDiff: ", Mathf.RadToDeg(angleDiff), " | velocity: ", Velocity.Length());
float retreatThreshold = EngageDistance * 0.75f; // retreat distance float retreatThreshold = EngageDistance * 0.75f; // retreat distance

View file

@ -8,61 +8,62 @@ public partial class asteroid : Area2D
public enum AsteroidSize {LARGE, MEDIUM, SMALL}; public enum AsteroidSize {LARGE, MEDIUM, SMALL};
private string[] LargeAsteroidTexture = new string[] {"res://assets/PNG/Meteors/meteorBrown_big1.png", private string[] _largeAsteroidTexture = new string[] {"res://assets/PNG/Meteors/meteorBrown_big1.png",
"res://assets/PNG/Meteors/meteorBrown_big4.png", "res://assets/PNG/Meteors/meteorBrown_big4.png",
"res://assets/PNG/Meteors/meteorGrey_big4.png"}; "res://assets/PNG/Meteors/meteorGrey_big4.png"};
private string[] MediumAsteroidTexture = new string[] {"res://assets/PNG/Meteors/meteorGrey_med1.png", private string[] _mediumAsteroidTexture = new string[] {"res://assets/PNG/Meteors/meteorGrey_med1.png",
"res://assets/PNG/Meteors/meteorBrown_med3.png", "res://assets/PNG/Meteors/meteorBrown_med3.png",
"res://assets/PNG/Meteors/meteorBrown_med1.png"}; "res://assets/PNG/Meteors/meteorBrown_med1.png"};
private string[] SmallAsteroidTexture = new string[] {"res://assets/PNG/Meteors/meteorBrown_small1.png", private string[] _smallAsteroidTexture = new string[] {"res://assets/PNG/Meteors/meteorBrown_small1.png",
"res://assets/PNG/Meteors/meteorBrown_small2.png", "res://assets/PNG/Meteors/meteorBrown_small2.png",
"res://assets/PNG/Meteors/meteorGrey_small1.png"}; "res://assets/PNG/Meteors/meteorGrey_small1.png"};
[Export] [Export]
public AsteroidSize size; public AsteroidSize Size;
public int Speed = 200;
public Vector2 MovementVector; private int _speed = 200;
public Sprite2D Sprite = new Sprite2D(); private Vector2 _movementVector;
public CollisionShape2D ColShape = null; private Sprite2D _sprite = new Sprite2D();
private CollisionShape2D _colShape;
public override void _Ready() public override void _Ready()
{ {
Sprite = GetNode<Sprite2D>("Sprite2D"); _sprite = GetNode<Sprite2D>("Sprite2D");
ColShape = GetNode<CollisionShape2D>("CollisionShape2D"); _colShape = GetNode<CollisionShape2D>("CollisionShape2D");
var rand = new Random(); var rand = new Random();
Rotation = (float)rand.NextDouble(); Rotation = (float)rand.NextDouble();
Rotation = (float)((Rotation * 2) * 3.14); Rotation = (float)((Rotation * 2) * 3.14);
MovementVector = new Vector2(0, -1); _movementVector = new Vector2(0, -1);
CircleShape2D ColShapeL; CircleShape2D colShapeL;
switch (size) switch (Size)
{ {
case AsteroidSize.LARGE: case AsteroidSize.LARGE:
Speed = rand.Next(5, 15); _speed = rand.Next(5, 15);
Sprite.Texture = GD.Load<Texture2D>(LargeAsteroidTexture[rand.Next(3)]); _sprite.Texture = GD.Load<Texture2D>(_largeAsteroidTexture[rand.Next(3)]);
ColShapeL = GD.Load<CircleShape2D>("res://assets/CollisionShapes/asteroid_cshape_big.tres"); colShapeL = GD.Load<CircleShape2D>("res://assets/CollisionShapes/asteroid_cshape_big.tres");
ColShape.SetDeferred("shape", ColShapeL); _colShape.SetDeferred("shape", colShapeL);
break; break;
case AsteroidSize.MEDIUM: case AsteroidSize.MEDIUM:
Speed = rand.Next(25, 50); _speed = rand.Next(25, 50);
Sprite.Texture = GD.Load<Texture2D>(MediumAsteroidTexture[rand.Next(3)]); _sprite.Texture = GD.Load<Texture2D>(_mediumAsteroidTexture[rand.Next(3)]);
ColShapeL = GD.Load<CircleShape2D>("res://assets/CollisionShapes/asteroid_cshape_medcircle.tres"); colShapeL = GD.Load<CircleShape2D>("res://assets/CollisionShapes/asteroid_cshape_medcircle.tres");
ColShape.SetDeferred("shape", ColShapeL); _colShape.SetDeferred("shape", colShapeL);
break; break;
case AsteroidSize.SMALL: case AsteroidSize.SMALL:
Speed = rand.Next(50, 75); _speed = rand.Next(50, 75);
Sprite.Texture = GD.Load<Texture2D>(SmallAsteroidTexture[rand.Next(3)]); _sprite.Texture = GD.Load<Texture2D>(_smallAsteroidTexture[rand.Next(3)]);
ColShapeL = GD.Load<CircleShape2D>("res://assets/CollisionShapes/asteroid_cshape_smallcircle.tres"); colShapeL = GD.Load<CircleShape2D>("res://assets/CollisionShapes/asteroid_cshape_smallcircle.tres");
ColShape.SetDeferred("shape", ColShapeL); _colShape.SetDeferred("shape", colShapeL);
break; break;
} }
} }
@ -72,26 +73,31 @@ public partial class asteroid : Area2D
//DEBUG PRINT //DEBUG PRINT
GD.Print($"DEBUG: Explode() called for {Name} at {GlobalPosition}"); GD.Print($"DEBUG: Explode() called for {Name} at {GlobalPosition}");
GD.Print($"DEBUG: {Name} calling Explode()"); GD.Print($"DEBUG: {Name} calling Explode()");
EmitSignal(SignalName.Exploded, GlobalPosition, (int)size); EmitSignal(SignalName.Exploded, GlobalPosition, (int)Size);
QueueFree(); QueueFree();
} }
public void OnBodyEntered(CharacterBody2D body) private static void OnBodyEntered(CharacterBody2D body)
{ {
if (body is player player) /*if (body is player player)
{ {
player.ShipDamage(30); player.ShipDamage(30);
GD.Print("player asteroid collide"); GD.Print("player asteroid collide");
} }*/
if (body is not ship ship) return;
ship.ShipDamage((30));
GD.Print(("ship asteroid collide"));
GD.Print(ship.Name, ship.Health);
} }
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
GlobalPosition += MovementVector.Rotated(Rotation) * Speed * (float)delta; GlobalPosition += _movementVector.Rotated(Rotation) * _speed * (float)delta;
CircleShape2D circleshape = (CircleShape2D)ColShape.Shape; CircleShape2D circleShape = (CircleShape2D)_colShape.Shape;
var radius = circleshape.Radius; var radius = circleShape.Radius;
var ScreenSize = GetViewportRect().Size; var screenSize = GetViewportRect().Size;
/* /*
if (GlobalPosition.Y + radius < 0) if (GlobalPosition.Y + radius < 0)

View file

@ -7,18 +7,18 @@ public partial class camera : Camera2D
[Export] public float SmoothingSpeed = 0.05f; [Export] public float SmoothingSpeed = 0.05f;
// Called when the node enters the scene tree for the first time. // Called when the node enters the scene tree for the first time.
public CharacterBody2D Player; private CharacterBody2D _player;
public override void _Ready() public override void _Ready()
{ {
Player = GetParent<CharacterBody2D>(); _player = GetParent<CharacterBody2D>();
} }
public override void _Process(double delta) public override void _Process(double delta)
{ {
Vector2 playerPos = Player.GlobalPosition; Vector2 playerPos = _player.GlobalPosition;
Vector2 playerV = Player.Velocity; Vector2 playerV = _player.Velocity;
Vector2 direction = playerV.Normalized(); Vector2 direction = playerV.Normalized();
Vector2 cameraTargetPos = playerPos + OffsetAmount * direction; Vector2 cameraTargetPos = playerPos + OffsetAmount * direction;
GlobalPosition = GlobalPosition.Lerp(cameraTargetPos, SmoothingSpeed); GlobalPosition = GlobalPosition.Lerp(cameraTargetPos, SmoothingSpeed);

View file

@ -3,28 +3,28 @@ using System;
public partial class game : Node2D public partial class game : Node2D
{ {
public Node Lasers = null; public Node Lasers;
public CharacterBody2D Player = null; public CharacterBody2D Player;
public Node Asteroids = null; public Node Asteroids;
public Node Friendlies = null; public Node Friendlies;
public Node Enemies = null; public Node Enemies;
public Node Ships = null; public Node Ships;
public Control HUD = null; public Control HUD;
public Label ScoreLabel = null; public Label ScoreLabel;
public Label HealthLabel = null; public Label HealthLabel;
public Label FlightAssistLabel = null; public Label FlightAssistLabel;
public hud h; public hud H;
private readonly PackedScene AsteroidScene = GD.Load<PackedScene>("res://scenes/asteroid.tscn"); private readonly PackedScene _asteroidScene = GD.Load<PackedScene>("res://scenes/asteroid.tscn");
public int Score = 0; public int Score = 0;
@ -82,7 +82,7 @@ public partial class game : Node2D
UpdateFALabel(); UpdateFALabel();
} }
/* //AUTO SPAWN AFTER CLEAR //AUTO SPAWN AFTER CLEAR
if (Asteroids.GetChildCount() == 0) if (Asteroids.GetChildCount() == 0)
{ {
Random rand = new Random(); Random rand = new Random();
@ -90,15 +90,15 @@ public partial class game : Node2D
{ {
SpawnAsteroid(new Vector2(rand.Next(10, 800), rand.Next(10, 800)), (int)asteroid.AsteroidSize.LARGE); SpawnAsteroid(new Vector2(rand.Next(10, 800), rand.Next(10, 800)), (int)asteroid.AsteroidSize.LARGE);
} }
}*/ }
} }
public void SpawnAsteroid(Vector2 position, int size) public void SpawnAsteroid(Vector2 position, int size)
{ {
var a = new asteroid(); var a = new asteroid();
a = AsteroidScene.Instantiate<asteroid>(); a = _asteroidScene.Instantiate<asteroid>();
a.GlobalPosition = position; a.GlobalPosition = position;
a.size = (asteroid.AsteroidSize)size; a.Size = (asteroid.AsteroidSize)size;
a.Exploded += OnAsteroidExploded; a.Exploded += OnAsteroidExploded;
Asteroids.CallDeferred("add_child", a); Asteroids.CallDeferred("add_child", a);
} }
@ -135,10 +135,10 @@ public partial class game : Node2D
Lasers.AddChild(Laser); Lasers.AddChild(Laser);
} }
public void OnPlayerLaserShot(Area2D Laser) public void OnPlayerLaserShot(Area2D laser)
{ {
Lasers.AddChild(Laser); Lasers.AddChild(laser);
GD.Print(Laser.Position); GD.Print(laser.Position);
GD.Print(Player.Position); GD.Print(Player.Position);
} }
@ -149,7 +149,13 @@ public partial class game : Node2D
public void OnPlayerDeath() public void OnPlayerDeath()
{ {
GetTree().ReloadCurrentScene(); //Reload scene to act as restart CallDeferred(nameof(SafeReloadScene)); //Reload scene to act as restart
}
private void SafeReloadScene()
{
GD.Print("Reloading scene");
GetTree().ReloadCurrentScene();
} }
public void OnAsteroidExploded(Vector2 pos, int size) public void OnAsteroidExploded(Vector2 pos, int size)

View file

@ -3,16 +3,16 @@ using System;
public partial class hud : Control public partial class hud : Control
{ {
public Label Score = new(); private Label _score = new();
public Label FlightAssist = new(); private Label _flightAssist = new();
public override void _Ready() public override void _Ready()
{ {
Score = GetNode<Label>("Score"); _score = GetNode<Label>("Score");
Score.Text = "SCORE: 0"; _score.Text = "SCORE: 0";
// Keeping health being initialised in game.cs // Keeping health being initialised in game.cs
FlightAssist = GetNode<Label>("FlightAssist"); _flightAssist = GetNode<Label>("FlightAssist");
FlightAssist.Text = "FA: ON"; // Should be on by default _flightAssist.Text = "FA: ON"; // Should be on by default
} }
} }

View file

@ -21,7 +21,7 @@ public partial class main_menu : Control
GetTree().Quit(); GetTree().Quit();
} }
// Called every frame. 'delta' is the elapsed time since the previous frame. // Called every frame. 'delta' has been the elapsed time since the previous frame.
public override void _Process(double delta) public override void _Process(double delta)
{ {
} }

View file

@ -12,20 +12,20 @@ public partial class player : ship // Inherits from base ship class
public delegate void PlayerDeathEventHandler(); public delegate void PlayerDeathEventHandler();
[Export] [Export]
public ShipColor color; public ShipColor Color;
[Export] [Export]
public float FlightAssistValue { get; set; } = 2.5f; public float FlightAssistValue { get; set; } = 2.5f;
public void GetInput() private void GetInput()
{ {
/*LookAt(GetGlobalMousePosition()); //used for mouse-based rotation and movement /*LookAt(GetGlobalMousePosition()); //used for mouse-based rotation and movement
Velocity = Transform.X * Input.GetAxis("down", "up") * Speed; Velocity = Transform.X * Input.GetAxis("down", "up") * Speed;
*/ */
// Movement, could probably move into its own methods instead of GetInput() // Movement, could probably move into its own methods instead of GetInput()
_rotationDirection = (int)Input.GetAxis("left", "right"); RotationDirection = (int)Input.GetAxis("left", "right");
Velocity += (Transform.X * Input.GetAxis("strafe_left", "strafe_right") * StrafeSpeed) + (Transform.Y * Input.GetAxis("up", "down") * MainSpeed); Velocity += (Transform.X * Input.GetAxis("strafe_left", "strafe_right") * StrafeSpeed) + (Transform.Y * Input.GetAxis("up", "down") * MainSpeed);
Velocity = Velocity.LimitLength(MaxSpeed); Velocity = Velocity.LimitLength(MaxSpeed);
@ -48,9 +48,14 @@ public partial class player : ship // Inherits from base ship class
{ {
base.ShipDamage(damage); base.ShipDamage(damage);
EmitSignal(SignalName.HealthUpdate, Health); EmitSignal(SignalName.HealthUpdate, Health);
if (Health <= 0)
{
EmitSignal(SignalName.PlayerDeath);
}
} }
public void ToggleFlightAssist() private void ToggleFlightAssist()
{ {
if (FlightAssistValue == 0f){FlightAssistValue = 2.5f;} if (FlightAssistValue == 0f){FlightAssistValue = 2.5f;}
else {FlightAssistValue = 0;} else {FlightAssistValue = 0;}
@ -59,22 +64,15 @@ public partial class player : ship // Inherits from base ship class
public override void _Ready() public override void _Ready()
{ {
SetupVisual(); SetupVisual();
GD.Print(faction); GD.Print(Faction);
switch(color) this.spritePath = Color switch
{ {
case ShipColor.RED: ShipColor.RED => this.spritePath + "ShipRed.png",
this.spritePath = this.spritePath + "ShipRed.png"; ShipColor.GREEN => this.spritePath + "ShipGreen.png",
break; ShipColor.BLUE => this.spritePath + "ShipBlue.png",
_ => this.spritePath
case ShipColor.GREEN: };
this.spritePath = this.spritePath + "ShipGreen.png";
break;
case ShipColor.BLUE:
this.spritePath = this.spritePath + "ShipBlue.png";
break;
}
GD.Print(spritePath); GD.Print(spritePath);
Sprite.Texture = GD.Load<Texture2D>(spritePath); Sprite.Texture = GD.Load<Texture2D>(spritePath);
@ -90,23 +88,18 @@ public partial class player : ship // Inherits from base ship class
{ {
fireTimer -= (float)delta; fireTimer -= (float)delta;
if(Input.IsActionJustPressed("shoot")) if(Input.IsActionPressed("shoot"))
{ {
if (fireTimer > 0f) return; if (fireTimer > 0f) return;
ShootLaser(); ShootLaser();
fireTimer = FireCooldown; fireTimer = FireCooldown;
} }
if (Health <= 0)
{
EmitSignal(SignalName.PlayerDeath);
}
} }
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ // every frame { // every frame
GetInput(); GetInput();
Rotation += _rotationDirection * RotationSpeed * (float)delta; Rotation += RotationDirection * RotationSpeed * (float)delta;
Velocity.LimitLength(MaxSpeed); Velocity.LimitLength(MaxSpeed);
//GD.Print(MainSpeed); //GD.Print(MainSpeed);

View file

@ -1,4 +1,3 @@
using System.Collections;
using Godot; using Godot;
public partial class ship : CharacterBody2D public partial class ship : CharacterBody2D
@ -31,7 +30,7 @@ public partial class ship : CharacterBody2D
[Export] [Export]
public ShipType type; public ShipType type;
[Export] [Export]
public ShipFaction faction; public ShipFaction Faction;
public Sprite2D Sprite = new Sprite2D(); public Sprite2D Sprite = new Sprite2D();
@ -39,20 +38,21 @@ public partial class ship : CharacterBody2D
protected float fireTimer = 0f; protected float fireTimer = 0f;
protected string spritePath = ""; public string spritePath = "";
protected int _rotationDirection; protected int RotationDirection;
protected readonly PackedScene LaserScene = GD.Load<PackedScene>("res://scenes/laser.tscn"); protected readonly PackedScene LaserScene = GD.Load<PackedScene>("res://scenes/laser.tscn");
public virtual void ShootLaser() public virtual void ShootLaser()
{ {
GD.Print(Name, ": firing laser"); //GD.Print(Name, ": firing laser");
Node2D Laser = LaserScene.Instantiate<Node2D>(); Laser laser = LaserScene.Instantiate<Laser>();
Laser.Position = LaserSpawn.GlobalPosition; laser.Position = LaserSpawn.GlobalPosition + -Transform.Y * 25f;
Laser.Rotation = Rotation; laser.Shooter = this;
EmitSignal(SignalName.LaserShot, Laser); laser.Rotation = Rotation;
EmitSignal(SignalName.LaserShot, laser);
} }
protected virtual void SetupVisual() protected virtual void SetupVisual()
@ -60,7 +60,7 @@ public partial class ship : CharacterBody2D
Sprite = GetNode<Sprite2D>("ShipSprite"); Sprite = GetNode<Sprite2D>("ShipSprite");
spritePath = ""; // Have to initialise as "" because of switch statements spritePath = ""; // Have to initialise as "" because of switch statements
if (faction == ShipFaction.PLAYER) if (Faction == ShipFaction.PLAYER)
{ {
switch (type) switch (type)
{ {
@ -77,7 +77,7 @@ public partial class ship : CharacterBody2D
break; break;
} }
} }
else if (faction == ShipFaction.FRIENDLY) else if (Faction == ShipFaction.FRIENDLY)
{ {
switch (type) switch (type)
{ {
@ -95,7 +95,7 @@ public partial class ship : CharacterBody2D
} }
} }
else if (faction == ShipFaction.ENEMY) else if (Faction == ShipFaction.ENEMY)
{ {
switch (type) switch (type)
{ {
@ -112,7 +112,7 @@ public partial class ship : CharacterBody2D
break; break;
} }
} }
else if (faction == ShipFaction.ACE) else if (Faction == ShipFaction.ACE)
{ {
switch (type) switch (type)
{ {
@ -129,7 +129,7 @@ public partial class ship : CharacterBody2D
break; break;
} }
} }
if (faction == ShipFaction.ENEMY || faction ==ShipFaction.FRIENDLY) if (Faction == ShipFaction.ENEMY || Faction == ShipFaction.FRIENDLY)
{ {
Sprite.RotationDegrees = 180; Sprite.RotationDegrees = 180;
} }
@ -181,7 +181,17 @@ public partial class ship : CharacterBody2D
public virtual void ShipDamage(int damage) public virtual void ShipDamage(int damage)
{ {
Health -= damage; Health -= damage;
if (Health < 0){ Health = 0;} if (Health <= 0)
{
Explode();
}
GD.Print(Name, " health: ", Health);
}
public virtual void Explode()
{
GD.Print(Name, " exploded");
QueueFree();
} }
public override void _Ready() public override void _Ready()
@ -193,7 +203,7 @@ public partial class ship : CharacterBody2D
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
// Common movement logic for all ships // Common movement logic for all ships
Rotation += _rotationDirection * RotationSpeed * (float)delta; Rotation += RotationDirection * RotationSpeed * (float)delta;
Velocity.LimitLength(MaxSpeed); Velocity.LimitLength(MaxSpeed);
MoveAndSlide(); MoveAndSlide();