Files
godot-------/Script/Item/Projectile.cs
m0_75251201 7700703099 初次提交
2025-07-12 11:30:22 +08:00

125 lines
3.2 KiB
C#

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;
}
/// <summary>
/// 设置子弹视觉表现
/// </summary>
private void SetupVisualRepresentation()
{
// 尝试获取现有的精灵节点
_visualSprite = GetNodeOrNull<Sprite2D>("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);
}
}
/// <summary>
/// 设置生命周期计时器
/// </summary>
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;
}
/// <summary>
/// 生命周期计时器回调
/// </summary>
private void OnLifeTimerTimeout()
{
// 子弹超时自动销毁
Destroy();
}
/// <summary>
/// 碰撞检测回调
/// </summary>
private void OnBodyEntered(Node2D body)
{
// 忽略所有者
if (body == From) return;
// 对可伤害实体造成伤害
if (body is IDamageable damageable)
{
damageable.TakeDamage(Damage);
}
// 销毁子弹
Destroy();
}
/// <summary>
/// 销毁子弹
/// </summary>
private void Destroy()
{
// 实际应用中应该:
// 1. 播放爆炸/命中效果
// 2. 播放音效
// 3. 可选: 留下弹痕/痕迹
QueueFree();
}
}
// 可伤害接口
public interface IDamageable
{
void TakeDamage(float amount);
}