using Godot;
using System;
using System.Collections.Generic;
namespace Cosmobox
{
public partial class Pawn : Sprite2D, IThingPhysics
{
// 移动参数
[Export] protected float moveSpeed = 200f; // 每秒移动的世界单位数
// 角色属性
[Export] protected int attack = 10; // 攻击力
[Export] protected int health = 100; // 生命值
[Export] protected int defense = 5; // 防御力
// 部件节点
[Export] protected Sprite2D head; // 头部精灵
[Export] protected Sprite2D body; // 身体精灵
[Export] protected Sprite2D clothes; // 衣服精灵
[Export] protected Sprite2D hairBackground; // 头发背景精灵
[Export] protected Sprite2D hair; // 头发精灵
[Export] protected Sprite2D leftEar; // 左耳精灵
[Export] protected Sprite2D rightEar; // 右耳精灵
// 资源路径
[Export] protected string characterResourcesPath = null; // 角色资源文件夹路径
// 纹理数组(每个数组有3个方向:下/上/侧边)
[Export] protected Texture2D[] headTextures = new Texture2D[3]; // 头部纹理
[Export] protected Texture2D[] bodyTextures = new Texture2D[3]; // 身体纹理
[Export] protected Texture2D[] clothesTextures = new Texture2D[3]; // 衣服纹理
[Export] protected Texture2D[] hairBackgroundTextures = new Texture2D[3]; // 头发背景纹理
[Export] protected Texture2D[] hairTextures = new Texture2D[3]; // 头发纹理
[Export] protected Texture2D[] leftEarTextures = new Texture2D[3]; // 左耳纹理
[Export] protected Texture2D[] rightEarTextures = new Texture2D[3]; // 右耳纹理
// 物理相关
protected Vector2 currentMovementInput = Vector2.Zero; // 当前原始的输入方向
public bool Moving
{
get
{
return currentMovementInput != Vector2.Zero;
}
}
public override void _Ready()
{
if (!string.IsNullOrEmpty(characterResourcesPath))
{
// 加载角色纹理
var loadedTextures = CharacterLoader.LoadCharacterTextures(characterResourcesPath);
// 应用加载的纹理
ApplyLoadedTextures(loadedTextures);
}
SetDownDirection(); // 初始化为向下方向
}
void IThingPhysics.PhysicsUpdate(double delta)
{
float deltaF = (float)delta;
// 根据输入方向和移动速度直接应用移动
// 使用Normalized()确保斜向移动不会更快
Position += currentMovementInput.Normalized() * moveSpeed * deltaF;
}
///
/// 方向纹理设置方法
/// 每个方法设置角色在特定方向的纹理
///
public void SetDownDirection() => SetTextures(0, false); // 设置向下方向的纹理
public void SetUpDirection() => SetTextures(1, false); // 设置向上方向的纹理
public void SetRightDirection() => SetTextures(2, false); // 设置向右方向的纹理
public void SetLeftDirection() => SetTextures(2, true); // 设置向左方向的纹理(使用翻转)
///
/// 核心纹理设置方法
/// 为角色各部分设置纹理和水平翻转状态
///
/// 纹理索引:0=下, 1=上, 2=侧边
/// 是否水平翻转(用于左右方向)
private void SetTextures(int index, bool flipH)
{
// 为每个部件设置纹理
if (head != null) head.Texture = headTextures[index];
if (body != null) body.Texture = bodyTextures[index];
if (clothes != null) clothes.Texture = clothesTextures[index];
if (hairBackground != null) hairBackground.Texture = hairBackgroundTextures[index];
if (hair != null) hair.Texture = hairTextures[index];
// 武器纹理设置(需要时取消注释)
// if (weapon != null) weapon.Texture = weaponTextures[index];
// 设置每个部件的水平翻转状态
if (head != null) head.FlipH = flipH;
if (body != null) body.FlipH = flipH;
if (clothes != null) clothes.FlipH = flipH;
if (hairBackground != null) hairBackground.FlipH = flipH;
if (hair != null) hair.FlipH = flipH;
// 耳朵的特殊处理逻辑
if (leftEar != null && rightEar != null)
{
// 先设置耳朵纹理
leftEar.Texture = leftEarTextures[index];
rightEar.Texture = rightEarTextures[index];
// 当角色面向侧面时(左右方向)
if (index == 2)
{
if (flipH) // 面向左时
{
leftEar.Show(); // 显示左耳
rightEar.Hide(); // 隐藏右耳
}
else // 面向右时
{
leftEar.Hide(); // 隐藏左耳
rightEar.Show(); // 显示右耳
}
}
else // 上下方向,两个耳朵都显示
{
leftEar.Show();
rightEar.Show();
}
}
}
///
/// 简化版移动处理 - 直接存储输入方向
/// 实际移动在物理处理过程中完成
///
/// 输入方向向量
protected void HandleMovement(Vector2 inputDirection)
{
// 存储当前输入方向,移动计算在物理过程中处理
currentMovementInput = inputDirection;
}
///
/// 根据移动向量更新角色朝向
///
/// 移动方向向量
public void UpdateDirection(Vector2 direction)
{
if (direction == Vector2.Zero) return; // 没有移动时不改变方向
// 计算角度(0-360度)
float angle = Mathf.RadToDeg(Mathf.Atan2(direction.Y, direction.X));
if (angle < 0) angle += 360;
// 根据角度范围决定方向
if (angle >= 45 && angle < 135)
{
SetDownDirection(); // 下方(例如输入 (0, 1))
}
else if (angle >= 135 && angle < 225)
{
SetLeftDirection(); // 左方(例如输入 (-1, 0))
}
else if (angle >= 225 && angle < 315)
{
SetUpDirection(); // 上方(例如输入 (0, -1))
}
else
{
SetRightDirection(); // 右方(例如输入 (1, 0))
}
}
///
/// 应用加载的纹理到各个角色部件
///
/// 加载的纹理字典
private void ApplyLoadedTextures(Dictionary loadedTextures)
{
// 头部纹理
if (loadedTextures.TryGetValue("head", out var headTex) && headTex.Length == 3)
{
headTextures = headTex;
}
// 身体纹理
if (loadedTextures.TryGetValue("body", out var bodyTex) && bodyTex.Length == 3)
{
bodyTextures = bodyTex;
}
// 衣服纹理
if (loadedTextures.TryGetValue("clothing", out var clothesTex) && clothesTex.Length == 3)
{
clothesTextures = clothesTex;
}
// 头发纹理
if (loadedTextures.TryGetValue("hair", out var hairTex) && hairTex.Length == 3)
{
hairTextures = hairTex;
}
// 头发背景纹理
if (loadedTextures.TryGetValue("hairBackground", out var hairBGTextures) && hairBGTextures.Length == 3)
{
hairBackgroundTextures = hairBGTextures;
}
// 耳朵纹理 - 分别处理左右耳
if (loadedTextures.TryGetValue("leftEar", out var leftEarTex) && leftEarTex.Length == 3)
{
leftEarTextures = leftEarTex;
}
if (loadedTextures.TryGetValue("rightEar", out var rightEarTex) && rightEarTex.Length == 3)
{
rightEarTextures = rightEarTex;
}
}
///
/// 工具方法
///
// 瞬间传送角色到指定位置
public void Teleport(Vector2 position) => Position = position;
// 设置移动速度(确保不小于0)
public void SetMoveSpeed(float speed) => moveSpeed = Mathf.Max(speed, 0);
// 获取当前速度矢量(方向向量 × 速度)
public Vector2 GetVelocity()
{
return currentMovementInput.Normalized() * moveSpeed;
}
///
/// 添加瞬间冲量(直接改变位置)
/// 注意:对于持续的推动效果可能需要单独实现
///
public void AddImpulse(Vector2 impulse)
{
// 直接修改位置 - 适用于瞬间位移
// 如需持续推动效果,需单独实现冲量系统
Position += impulse;
}
}
}