✨ Turret shooting and damaing
This commit is contained in:
@@ -1,22 +1,43 @@
|
||||
using System.Linq;
|
||||
using AceFieldNewHorizon.Scripts.Entities;
|
||||
using Godot;
|
||||
|
||||
namespace AceFieldNewHorizon.Scripts.Tiles;
|
||||
|
||||
public partial class TurretTile : BaseTile
|
||||
{
|
||||
private Sprite2D _spriteBarrel;
|
||||
[Export] public PackedScene BulletScene;
|
||||
|
||||
[Export] public float RotationSpeed = 2.0f; // Radians per second
|
||||
[Export] public float AttackRange = 300.0f;
|
||||
[Export] public float AttackCooldown = 0.5f;
|
||||
[Export] public int Damage = 10;
|
||||
[Export] public float BulletSpeed = 400.0f;
|
||||
[Export] public NodePath BarrelTipPath;
|
||||
|
||||
private Node2D _spriteBarrel;
|
||||
private Node2D _barrelTip;
|
||||
private float _attackTimer = 0;
|
||||
private bool _hasTarget = false;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
_spriteBarrel = GetNodeOrNull<Node2D>("Barrel");
|
||||
_barrelTip = GetNodeOrNull<Node2D>(BarrelTipPath);
|
||||
|
||||
_spriteBarrel = GetNodeOrNull<Sprite2D>("Barrel");
|
||||
if (_barrelTip == null && _spriteBarrel != null)
|
||||
{
|
||||
// If no barrel tip is specified, use the end of the barrel sprite
|
||||
_barrelTip = _spriteBarrel.GetNodeOrNull<Node2D>("BarrelTip");
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetGhostMode(bool canPlace)
|
||||
{
|
||||
base.SetGhostMode(canPlace);
|
||||
|
||||
|
||||
if (_spriteBarrel != null)
|
||||
_spriteBarrel.Modulate = canPlace
|
||||
? new Color(0, 1, 0, 0.5f)
|
||||
@@ -26,8 +47,81 @@ public partial class TurretTile : BaseTile
|
||||
public override void FinalizePlacement()
|
||||
{
|
||||
base.FinalizePlacement();
|
||||
|
||||
|
||||
if (_spriteBarrel != null)
|
||||
_spriteBarrel.Modulate = Colors.White;
|
||||
}
|
||||
|
||||
public override void _Process(double delta)
|
||||
{
|
||||
if (!IsConstructed) return;
|
||||
|
||||
// Update attack cooldown
|
||||
if (_attackTimer > 0)
|
||||
{
|
||||
_attackTimer -= (float)delta;
|
||||
}
|
||||
|
||||
// Find the nearest enemy
|
||||
var enemies = GetTree().GetNodesInGroup(Enemy.EnemyGroupName)
|
||||
.OfType<Enemy>()
|
||||
.Where(e => e.GlobalPosition.DistanceTo(GlobalPosition) <= AttackRange)
|
||||
.OrderBy(e => e.GlobalPosition.DistanceTo(GlobalPosition))
|
||||
.ToList();
|
||||
|
||||
if (enemies.Count > 0)
|
||||
{
|
||||
var nearestEnemy = enemies[0];
|
||||
_hasTarget = true;
|
||||
|
||||
// Calculate target angle
|
||||
var direction = (nearestEnemy.GlobalPosition - _spriteBarrel.GlobalPosition).Normalized();
|
||||
var targetAngle = Mathf.Atan2(direction.Y, direction.X);
|
||||
|
||||
// Smoothly rotate towards target
|
||||
_spriteBarrel.Rotation = Mathf.LerpAngle(_spriteBarrel.Rotation, targetAngle, (float)delta * RotationSpeed);
|
||||
|
||||
// Check if we're facing the target and can attack
|
||||
if (Mathf.Abs(Mathf.Wrap(targetAngle - _spriteBarrel.Rotation, -Mathf.Pi, Mathf.Pi)) < 0.1f)
|
||||
TryAttack(nearestEnemy.GlobalPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
_hasTarget = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void TryAttack(Vector2 targetPosition)
|
||||
{
|
||||
if (_attackTimer <= 0 && BulletScene != null && _barrelTip != null)
|
||||
{
|
||||
// Create bullet instance
|
||||
var bullet = BulletScene.Instantiate<Bullet>();
|
||||
|
||||
// Calculate direction and rotation
|
||||
var direction = (targetPosition - _barrelTip.GlobalPosition).Normalized();
|
||||
var bulletRotation = direction.Angle();
|
||||
|
||||
// Set bullet position and rotation
|
||||
GetTree().CurrentScene.AddChild(bullet);
|
||||
bullet.GlobalPosition = _barrelTip.GlobalPosition;
|
||||
bullet.Rotation = bulletRotation; // Use the calculated rotation
|
||||
|
||||
// Initialize bullet with direction and damage
|
||||
bullet.Initialize(
|
||||
direction,
|
||||
bullet.GlobalPosition,
|
||||
bulletRotation, // Pass the calculated rotation
|
||||
1 // Pass the turret's collision layer to ignore
|
||||
);
|
||||
bullet.Damage = Damage;
|
||||
bullet.Speed = BulletSpeed;
|
||||
bullet.MaxDistance = AttackRange * 1.5f; // Bullets can travel slightly further than attack range
|
||||
|
||||
// Reset attack cooldown
|
||||
_attackTimer = AttackCooldown;
|
||||
|
||||
GD.Print("Turret attacking enemy!");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user