Godot-SpaceShooter/Scripts/PlayerShip.cs

101 lines
3.7 KiB
C#

using Godot;
namespace Scripts;
public partial class PlayerShip : Node3D {
private const float jetTimerMax = 0.5f;
private const float laserTimerMax = 1f;
private const string PLAYER_MOVE_FORWARD = "Player_Move_Forward";
private const string PLAYER_MOVE_BACKWARDS = "Player_Move_Backwards";
private const string PLAYER_MOVE_LEFT = "Player_Move_Left";
private const string PLAYER_MOVE_RIGHT = "Player_Move_Right";
private const string PLAYER_FIRE = "Player_Fire";
[Export] private CpuParticles3D cpulaser;
[Export] private PackedScene explosion;
[Export] private GpuParticles3D gpulaser;
[Export] private Node3D jet;
private float jetTimer = jetTimerMax;
[Export] private PackedScene laser;
private float laserTimer = laserTimerMax;
private Vector3 moveDir;
[Export] private float moveVelocity = 10f;
[Export] public RigidBody3D PlayerRb;
private Vector3 rotDir;
[Export] private float rotVelocity = 15f;
private bool shooting;
[Export] private Node3D shots;
public static PlayerShip Instance { get; private set; }
public override void _Ready() {
Position = new(0, 0, 5);
Instance = this;
}
public override void _Process(double delta) {
moveDir = Vector3.Zero;
rotDir = Vector3.Zero;
//Movement
if (Input.IsActionPressed(PLAYER_MOVE_FORWARD)) moveDir.Z -= moveVelocity;
if (Input.IsActionJustPressed(PLAYER_MOVE_FORWARD)) rotDir.X = -rotVelocity;
if (Input.IsActionPressed(PLAYER_MOVE_BACKWARDS)) moveDir.Z += moveVelocity;
if (Input.IsActionJustPressed(PLAYER_MOVE_BACKWARDS)) rotDir.X = +rotVelocity;
if (Input.IsActionPressed(PLAYER_MOVE_LEFT)) moveDir.X -= moveVelocity;
if (Input.IsActionJustPressed(PLAYER_MOVE_LEFT)) rotDir.Z = -rotVelocity * 2;
if (Input.IsActionPressed(PLAYER_MOVE_RIGHT)) moveDir.X += moveVelocity;
if (Input.IsActionJustPressed(PLAYER_MOVE_RIGHT)) rotDir.Z = +rotVelocity * 2;
if (Input.IsActionJustReleased(PLAYER_MOVE_LEFT) || Input.IsActionJustReleased(PLAYER_MOVE_RIGHT)) rotDir = Vector3.Zero;
//Fire
if (Input.IsActionJustPressed(PLAYER_FIRE))
if (laser.Instantiate() is Node3D shot) {
shot.Position = PlayerRb.Position + new Vector3(0f, 0f, 0.74f);
shots.AddChild(shot);
SoundManager.Instance.PlayLaserSound(PlayerRb.Position);
}
}
public override void _PhysicsProcess(double delta) {
if (moveDir != Vector3.Zero) {
jet.Visible = true;
KinematicCollision3D collision = PlayerRb.MoveAndCollide(moveDir * (float)delta);
if (collision?.GetCollider() is Node3D collider) GD.Print($"{Name} collides with {collider.GetParentNode3D().Name}");
}
else {
jet.Visible = false;
}
PlayerRb.RotationDegrees = rotDir;
CheckBoundaries();
}
private void CheckBoundaries() {
Vector3 correctedPos = PlayerRb.Position;
correctedPos.X = Position.X switch {
< -3.3f => -3.3f,
> 3.3f => 3.3f,
_ => correctedPos.X
};
correctedPos.Z = Position.Z switch {
< -5.2f => -5.2f,
> 5.2f => 5.2f,
_ => correctedPos.Z
};
PlayerRb.Position = correctedPos;
}
public void Explode(Vector3 collisionPosition) {
if (explosion?.Instantiate() is GpuParticles3D ex) {
GetParent().AddChild(ex);
ex.Position = collisionPosition;
ex.Emitting = true;
}
SoundManager.Instance.PlayExplosion(collisionPosition);
GameManager.Instance.Lives--;
}
}