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