252 lines
9.6 KiB
C#
252 lines
9.6 KiB
C#
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 方向纹理设置方法
|
||
/// 每个方法设置角色在特定方向的纹理
|
||
/// </summary>
|
||
public void SetDownDirection() => SetTextures(0, false); // 设置向下方向的纹理
|
||
public void SetUpDirection() => SetTextures(1, false); // 设置向上方向的纹理
|
||
public void SetRightDirection() => SetTextures(2, false); // 设置向右方向的纹理
|
||
public void SetLeftDirection() => SetTextures(2, true); // 设置向左方向的纹理(使用翻转)
|
||
|
||
/// <summary>
|
||
/// 核心纹理设置方法
|
||
/// 为角色各部分设置纹理和水平翻转状态
|
||
/// </summary>
|
||
/// <param name="index">纹理索引:0=下, 1=上, 2=侧边</param>
|
||
/// <param name="flipH">是否水平翻转(用于左右方向)</param>
|
||
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();
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 简化版移动处理 - 直接存储输入方向
|
||
/// 实际移动在物理处理过程中完成
|
||
/// </summary>
|
||
/// <param name="inputDirection">输入方向向量</param>
|
||
protected void HandleMovement(Vector2 inputDirection)
|
||
{
|
||
// 存储当前输入方向,移动计算在物理过程中处理
|
||
currentMovementInput = inputDirection;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据移动向量更新角色朝向
|
||
/// </summary>
|
||
/// <param name="direction">移动方向向量</param>
|
||
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))
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 应用加载的纹理到各个角色部件
|
||
/// </summary>
|
||
/// <param name="loadedTextures">加载的纹理字典</param>
|
||
private void ApplyLoadedTextures(Dictionary<string, Texture2D[]> 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;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工具方法
|
||
/// </summary>
|
||
|
||
// 瞬间传送角色到指定位置
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加瞬间冲量(直接改变位置)
|
||
/// 注意:对于持续的推动效果可能需要单独实现
|
||
/// </summary>
|
||
public void AddImpulse(Vector2 impulse)
|
||
{
|
||
// 直接修改位置 - 适用于瞬间位移
|
||
// 如需持续推动效果,需单独实现冲量系统
|
||
Position += impulse;
|
||
}
|
||
|
||
}
|
||
|
||
} |