Files
AceField-New-Horizon/Scripts/Entities/Bullet.cs
2025-08-30 13:05:50 +08:00

98 lines
2.6 KiB
C#

using Godot;
namespace AceFieldNewHorizon.Scripts.Entities;
public partial class Bullet : Area2D
{
[Export] public float Speed = 400.0f;
[Export] public int Damage = 10;
[Export] public float MaxDistance = 1000.0f;
private Vector2 _direction = Vector2.Right;
private Vector2 _startPosition;
private float _distanceTraveled = 0f;
private bool _hasHit = false;
private uint _ignoreCollisionLayer = 0; // Layer to ignore (will be set by turret)
public void Initialize(Vector2 direction, Vector2 position, float rotation, uint ignoreLayer = 0)
{
_direction = direction.Normalized();
Position = position;
Rotation = rotation;
_startPosition = position;
_ignoreCollisionLayer = ignoreLayer;
// Connect the area entered signal
BodyEntered += OnBodyEntered;
AreaEntered += OnAreaEntered;
}
public override void _PhysicsProcess(double delta)
{
if (_hasHit) return;
// Move the bullet
var movement = _direction * Speed * (float)delta;
Position += movement;
_distanceTraveled += movement.Length();
// Check if bullet has traveled max distance
if (_distanceTraveled >= MaxDistance)
{
QueueFree();
return;
}
}
private void OnBodyEntered(Node2D body)
{
HandleCollision(body);
}
private void OnAreaEntered(Area2D area)
{
HandleCollision(area);
}
private void HandleCollision(Node2D node)
{
if (_hasHit) return;
// Skip collision if it's on the ignore layer
if (node is PhysicsBody2D physicsBody &&
(physicsBody.CollisionLayer & _ignoreCollisionLayer) != 0)
{
return;
}
_hasHit = true;
// If we hit an enemy, deal damage
if (node is Enemy enemy)
{
// Get the global position where the bullet hit
var hitPosition = GlobalPosition;
enemy.TakeDamage(Damage, hitPosition);
}
// Optional: Add hit effect here
// CreateHitEffect();
// Remove the bullet
QueueFree();
}
private void CreateHitEffect()
{
// You can add a hit effect here if desired
// For example, a small explosion or impact sprite
}
public override void _ExitTree()
{
// Clean up signal connections
BodyEntered -= OnBodyEntered;
AreaEntered -= OnAreaEntered;
}
}