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

252 lines
9.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}