using Godot; using System; public partial class Projectile : Area2D { // === 子弹属性 === [Export] public float Speed = 500f; // 子弹速度(像素/秒) [Export] public float LifeTime = 2f; // 子弹存在时间(秒) [Export] public int Damage = 10; // 子弹伤害值 [Export] public Texture2D ProjectileTexture; // 子弹视觉纹理 // === 内部状态 === public Vector2 Direction = Vector2.Right; // 子弹方向(由武器设置) public Node2D From; // 子弹所有者(用于避免自伤) private Timer _lifeTimer; // 生命周期计时器 private Sprite2D _visualSprite; // 视觉精灵节点 public override void _Ready() { // === 初始化视觉表现 === SetupVisualRepresentation(); // === 初始化生命周期计时器 === SetupLifeTimer(); // === 连接碰撞信号 === BodyEntered += OnBodyEntered; } /// /// 设置子弹视觉表现 /// private void SetupVisualRepresentation() { // 尝试获取现有的精灵节点 _visualSprite = GetNodeOrNull("VisualSprite"); // 如果不存在则创建 if (_visualSprite == null && ProjectileTexture != null) { _visualSprite = new Sprite2D(); _visualSprite.Name = "VisualSprite"; AddChild(_visualSprite); } // 应用纹理到视觉精灵 if (_visualSprite != null && ProjectileTexture != null) { _visualSprite.Texture = ProjectileTexture; } // 根据方向旋转子弹 if (Direction != Vector2.Zero) { Rotation = Mathf.Atan2(Direction.Y, Direction.X); } } /// /// 设置生命周期计时器 /// private void SetupLifeTimer() { _lifeTimer = new Timer(); AddChild(_lifeTimer); _lifeTimer.WaitTime = LifeTime; _lifeTimer.OneShot = true; // 单次触发模式 _lifeTimer.Timeout += OnLifeTimerTimeout; _lifeTimer.Start(); } public override void _PhysicsProcess(double delta) { float deltaF = (float)delta; // 移动子弹 GlobalPosition += Direction * Speed * deltaF; } /// /// 生命周期计时器回调 /// private void OnLifeTimerTimeout() { // 子弹超时自动销毁 Destroy(); } /// /// 碰撞检测回调 /// private void OnBodyEntered(Node2D body) { // 忽略所有者 if (body == From) return; // 对可伤害实体造成伤害 if (body is IDamageable damageable) { damageable.TakeDamage(Damage); } // 销毁子弹 Destroy(); } /// /// 销毁子弹 /// private void Destroy() { // 实际应用中应该: // 1. 播放爆炸/命中效果 // 2. 播放音效 // 3. 可选: 留下弹痕/痕迹 QueueFree(); } } // 可伤害接口 public interface IDamageable { void TakeDamage(float amount); }