102 lines
3.8 KiB
C#
102 lines
3.8 KiB
C#
using Godot;
|
|
|
|
namespace GodotspaceShooter.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) {
|
|
if (GameManager.Instance.GameOver) return;
|
|
|
|
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.Play(SoundManager.Sound.Laser, PlayerRb.Position);
|
|
}
|
|
}
|
|
|
|
public override void _PhysicsProcess(double delta) {
|
|
//Movement
|
|
if (moveDir != Vector3.Zero) {
|
|
jet.Visible = true;
|
|
KinematicCollision3D collision = PlayerRb.MoveAndCollide(moveDir * (float)delta);
|
|
if (collision?.GetCollider() is Node3D collider) {
|
|
Node3D parent = collider.GetParent<Node3D>();
|
|
Vector3 collisionPosition = collision.GetPosition();
|
|
switch (parent) {
|
|
case GameArea:
|
|
GD.Print($"PlayerShip hits GameArea");
|
|
break;
|
|
case Asteroid asteroid:
|
|
Explode(collisionPosition);
|
|
asteroid.Explode(collisionPosition);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
jet.Visible = false;
|
|
}
|
|
|
|
//Rotation
|
|
PlayerRb.RotationDegrees = rotDir;
|
|
}
|
|
|
|
public void Explode(Vector3 collisionPosition) {
|
|
if (explosion?.Instantiate() is GpuParticles3D ex) {
|
|
GetParent().AddChild(ex);
|
|
ex.Position = collisionPosition;
|
|
ex.Emitting = true;
|
|
}
|
|
|
|
SoundManager.Instance.Play(SoundManager.Sound.PlayerExplosion, collisionPosition);
|
|
GameManager.Instance.Lives--;
|
|
}
|
|
} |