Turret shooting and damaing

This commit is contained in:
2025-08-30 13:05:50 +08:00
parent 1c6c03cd41
commit 7438ba407a
14 changed files with 410 additions and 14 deletions

View File

@@ -11,14 +11,52 @@ public partial class Enemy : CharacterBody2D
[Export] public float AttackRange = 50.0f;
[Export] public int Damage = 10;
[Export] public float AttackCooldown = 1.0f;
[Export] public int MaxHealth = 100;
[Export] public bool ShowDamageNumbers = true;
private Player _player;
private float _attackTimer = 0;
private bool _isPlayerInRange = false;
private Area2D _detectionArea;
private int _currentHealth;
private ProgressBar _healthBar;
public int CurrentHealth
{
get => _currentHealth;
private set
{
_currentHealth = Mathf.Clamp(value, 0, MaxHealth);
UpdateHealthBar();
if (_currentHealth <= 0)
{
Die();
}
}
}
public bool IsDead => _currentHealth <= 0;
public override void _Ready()
{
_currentHealth = MaxHealth;
// Create health bar
_healthBar = new ProgressBar
{
MaxValue = MaxHealth,
Value = _currentHealth,
Size = new Vector2(40, 4),
ShowPercentage = false,
Visible = false
};
var healthBarContainer = new Control();
healthBarContainer.AddChild(_healthBar);
AddChild(healthBarContainer);
healthBarContainer.Position = new Vector2(-20, -20); // Adjust position as needed
// Create detection area
_detectionArea = new Area2D();
var collisionShape = new CollisionShape2D();
@@ -37,6 +75,8 @@ public partial class Enemy : CharacterBody2D
public override void _Process(double delta)
{
if (IsDead) return;
if (_player != null && _isPlayerInRange)
{
// Face the player
@@ -60,8 +100,68 @@ public partial class Enemy : CharacterBody2D
}
}
public void TakeDamage(int damage, Vector2? hitPosition = null)
{
if (IsDead) return;
CurrentHealth -= damage;
// Show damage number (optional)
if (ShowDamageNumbers)
{
var damageLabel = new Label
{
Text = $"-{damage}",
Position = hitPosition ?? GlobalPosition,
ZIndex = 1000
};
GetTree().CurrentScene.AddChild(damageLabel);
// Animate and remove damage number
var tween = CreateTween();
tween.TweenProperty(damageLabel, "position:y", damageLabel.Position.Y - 30, 0.5f);
tween.TweenCallback(Callable.From(() => damageLabel.QueueFree())).SetDelay(0.5f);
}
// Visual feedback
var originalModulate = Modulate;
Modulate = new Color(1, 0.5f, 0.5f); // Flash red
var tweenFlash = CreateTween();
tweenFlash.TweenProperty(this, "modulate", originalModulate, 0.2f);
}
private void UpdateHealthBar()
{
if (_healthBar != null)
{
_healthBar.Value = _currentHealth;
_healthBar.Visible = _currentHealth < MaxHealth; // Only show when damaged
}
}
private void Die()
{
// Play death animation/sound
// You can add a death animation here
// Disable collisions and hide
SetProcess(false);
SetPhysicsProcess(false);
Hide();
// Queue free after a delay (for any death animation/sound to play)
var timer = new Timer();
AddChild(timer);
timer.Timeout += () => QueueFree();
timer.Start(0.5f);
}
private void TryAttackPlayer(double delta)
{
if (IsDead) return;
_attackTimer += (float)delta;
if (_attackTimer >= AttackCooldown)