初次提交

This commit is contained in:
m0_75251201
2025-07-12 11:30:22 +08:00
commit 7700703099
1156 changed files with 21532 additions and 0 deletions

4
.editorconfig Normal file
View File

@ -0,0 +1,4 @@
root = true
[*]
charset = utf-8

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Normalize EOL for all files that Git considers text files.
* text=auto eol=lf

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Godot 4+ specific ignores
.godot/
/android/

BIN
Font/Uranus_Pixel_11Px.ttf Normal file

Binary file not shown.

View File

@ -0,0 +1,35 @@
[remap]
importer="font_data_dynamic"
type="FontFile"
uid="uid://cjfdun63bo72f"
path="res://.godot/imported/Uranus_Pixel_11Px.ttf-9deb139e327f1dcf0754100708d26028.fontdata"
[deps]
source_file="res://Font/Uranus_Pixel_11Px.ttf"
dest_files=["res://.godot/imported/Uranus_Pixel_11Px.ttf-9deb139e327f1dcf0754100708d26028.fontdata"]
[params]
Rendering=null
antialiasing=1
generate_mipmaps=false
disable_embedded_bitmaps=true
multichannel_signed_distance_field=false
msdf_pixel_range=8
msdf_size=48
allow_system_fallback=true
force_autohinter=false
hinting=1
subpixel_positioning=4
keep_rounding_remainders=true
oversampling=0.0
Fallbacks=null
fallbacks=[]
Compress=null
compress=true
preload=[]
language_support={}
script_support={}
opentype_features={}

12
Resource/Item/gress.tres Normal file
View File

@ -0,0 +1,12 @@
[gd_resource type="Resource" script_class="ItemResource" load_steps=3 format=3 uid="uid://byyba456mf86l"]
[ext_resource type="Texture2D" uid="uid://c6sgy6n73g1c7" path="res://图片/Item/gress.png" id="1_7esax"]
[ext_resource type="Script" uid="uid://d02in2v01dbtb" path="res://Script/Item/ItemResource.cs" id="1_gj5v6"]
[resource]
script = ExtResource("1_gj5v6")
ItemName = "草"
Description = "这是草,一种草本植物"
Icon = ExtResource("1_7esax")
Stackable = true
metadata/_custom_type_script = "uid://d02in2v01dbtb"

10
Script/Base/IThing.cs Normal file
View File

@ -0,0 +1,10 @@
using Godot;
using System;
namespace Cosmobox
{
public interface IThing
{
public void Update(double delta);
}
}

View File

@ -0,0 +1 @@
uid://m301eht3eac3

View File

@ -0,0 +1,9 @@
using Godot;
using System;
namespace Cosmobox
{
public interface IThingPhysics
{
public void PhysicsUpdate(double delta);
}
}

View File

@ -0,0 +1 @@
uid://c6hg67pd2oxuc

9
Script/Base/IThingUI.cs Normal file
View File

@ -0,0 +1,9 @@
using Godot;
using System;
namespace Cosmobox
{
public interface IThingUI
{
public void UpdateUI();
}
}

View File

@ -0,0 +1 @@
uid://bqkle0sd1vwbk

View File

@ -0,0 +1,89 @@
using Godot;
using System;
namespace Cosmobox
{
public partial class InputControl : Node
{
[Export] public TickControl tickControl; // 控制游戏暂停的节点
[Export] public Player player; // 玩家节点
[Export] public BagUI bagUI; // 背包 UI
[Export] public Control devUI; // 开发者 UI
public override void _Ready()
{
// 初始化状态
UpdatePauseState();
}
public override void _Process(double delta)
{
// 监听 "bag" 按键
if (Input.IsActionJustPressed("bag"))
{
ToggleBagUI();
}
// 监听开发者 UI 的切换(假设通过某个按键触发)
if (Input.IsActionJustPressed("dev_ui"))
{
ToggleDevUI();
}
}
/// <summary>
/// 切换背包 UI 的打开/关闭状态
/// </summary>
private void ToggleBagUI()
{
if (bagUI.IsOpen)
{
bagUI.CloseBag(); // 关闭背包
}
else
{
// 如果开发者 UI 已打开,则先关闭开发者 UI
if (devUI.Visible)
{
devUI.Visible = false;
}
bagUI.OpenBag(); // 打开背包
}
// 更新暂停状态
UpdatePauseState();
}
/// <summary>
/// 切换开发者 UI 的可见性
/// </summary>
private void ToggleDevUI()
{
if (devUI.Visible)
{
devUI.Visible = false; // 关闭开发者 UI
}
else
{
// 如果背包已打开,则先关闭背包
if (bagUI.IsOpen)
{
bagUI.CloseBag();
}
devUI.Visible = true; // 打开开发者 UI
}
// 更新暂停状态
UpdatePauseState();
}
/// <summary>
/// 更新游戏的暂停状态
/// </summary>
private void UpdatePauseState()
{
// 如果背包或开发者 UI 任一打开,则暂停游戏
tickControl.pause = bagUI.IsOpen || devUI.Visible;
}
}
}

View File

@ -0,0 +1 @@
uid://cgesjwgws6bmr

View File

@ -0,0 +1,67 @@
using Godot;
using System;
using System.Collections.Generic;
namespace Cosmobox
{
public static class ItemResourceManager
{
private static Dictionary<string, ItemResource> _items;
private static bool _initialized = false;
// 初始化物品数据
private static void Initialize()
{
if (_initialized) return;
_items = new Dictionary<string, ItemResource>();
// 加载 res://Resource/Item/ 目录下的所有 ItemResource
var dir = DirAccess.Open("res://Resource/Item/");
if (dir != null)
{
dir.ListDirBegin();
string fileName = dir.GetNext();
while (fileName != "")
{
if (!dir.CurrentIsDir() && fileName.EndsWith(".tres"))
{
var resourcePath = $"res://Resource/Item/{fileName}";
var item = GD.Load<ItemResource>(resourcePath);
if (item != null)
{
_items[item.ItemName] = item;
}
}
fileName = dir.GetNext();
}
}
_initialized = true;
}
// 获取所有物品
public static Dictionary<string, ItemResource> GetAllItems()
{
Initialize();
return _items;
}
// 通过名称获取物品
public static ItemResource GetItem(string itemName)
{
Initialize();
if (_items.TryGetValue(itemName, out var item))
{
return item;
}
return null;
}
// 获取物品数量
public static int GetItemCount()
{
Initialize();
return _items.Count;
}
}
}

View File

@ -0,0 +1 @@
uid://cla8a7157wf4v

135
Script/Base/PerlinNoise.cs Normal file
View File

@ -0,0 +1,135 @@
using System;
namespace Cosmobox
{
public class PerlinNoise
{
private int[] p; // 混淆表
// 构造函数:初始化混淆表
public PerlinNoise(int seed)
{
// 初始化为0-255的随机排列
p = new int[512]; // 混淆表加倍以方便使用
int[] permutation = new int[256];
Random random = new Random(seed);
// 填充数组为0-255
for (int i = 0; i < 256; i++)
{
permutation[i] = i;
}
// 使用Fisher-Yates算法打乱数组
for (int i = 0; i < 256; i++)
{
int swapIndex = random.Next(256);
int temp = permutation[i];
permutation[i] = permutation[swapIndex];
permutation[swapIndex] = temp;
}
// 将打乱后的数组复制两次生成512个元素的混淆表
for (int i = 0; i < 256; i++)
{
p[i] = permutation[i];
p[i + 256] = permutation[i];
}
}
// 平滑函数 (6t^5 - 15t^4 + 10t^3)
private double Fade(double t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
// 线性插值
private double Lerp(double t, double a, double b)
{
return a + t * (b - a);
}
// 计算梯度向量和距离向量的点积
private double Grad(int hash, double x, double y, double z)
{
// 根据hash值确定使用哪个梯度向量
// 12个梯度向量由以下组合构成(+/-1, +/-1, 0), (+/-1, 0, +/-1), (0, +/-1, +/-1)
switch (hash & 0xF) // 取hash值的最后4位
{
case 0x0: return x + y;
case 0x1: return -x + y;
case 0x2: return x - y;
case 0x3: return -x - y;
case 0x4: return x + z;
case 0x5: return -x + z;
case 0x6: return x - z;
case 0x7: return -x - z;
case 0x8: return y + z;
case 0x9: return -y + z;
case 0xA: return y - z;
case 0xB: return -y - z;
case 0xC: return y + x; // 这四个是重复的但Ken Perlin的原始实现中包含它们。
case 0xD: return -y + x; // 它们对噪声质量影响不大,但保持了表格的一致性。
case 0xE: return y - x;
case 0xF: return -y - x;
default: return 0; // 不应该发生
}
}
/// <summary>
/// 为给定的(x, y, z)坐标生成3D Perlin噪声。
/// 输出值通常在-1到1之间。
/// </summary>
public double Noise(double x, double y, double z)
{
// 找到包含该点的单位立方体
int X = (int)Math.Floor(x) & 255;
int Y = (int)Math.Floor(y) & 255;
int Z = (int)Math.Floor(z) & 255;
// 找到该点在立方体内的相对x, y, z坐标
x -= Math.Floor(x);
y -= Math.Floor(y);
z -= Math.Floor(z);
// 计算x, y, z的平滑曲线
double u = Fade(x);
double v = Fade(y);
double w = Fade(z);
// 对立方体的8个角进行哈希计算
int A = p[X] + Y;
int AA = p[A] + Z;
int AB = p[A + 1] + Z;
int B = p[X + 1] + Y;
int BA = p[B] + Z;
int BB = p[B + 1] + Z;
// 获取所有8个角的哈希值
int H000 = p[AA];
int H100 = p[BA];
int H010 = p[AB];
int H110 = p[BB];
int H001 = p[AA + 1];
int H101 = p[BA + 1];
int H011 = p[AB + 1];
int H111 = p[BB + 1];
// 计算所有8个角的点积并插值
double x0, x1, y0, y1;
x0 = Lerp(u, Grad(H000, x, y, z), // (0,0,0)
Grad(H100, x - 1, y, z)); // (1,0,0)
x1 = Lerp(u, Grad(H010, x, y - 1, z), // (0,1,0)
Grad(H110, x - 1, y - 1, z)); // (1,1,0)
y0 = Lerp(v, x0, x1);
x0 = Lerp(u, Grad(H001, x, y, z - 1), // (0,0,1)
Grad(H101, x - 1, y, z - 1)); // (1,0,1)
x1 = Lerp(u, Grad(H011, x, y - 1, z - 1), // (0,1,1)
Grad(H111, x - 1, y - 1, z - 1)); // (1,1,1)
y1 = Lerp(v, x0, x1);
return Lerp(w, y0, y1);
}
}
}

View File

@ -0,0 +1 @@
uid://cnom22n5jbp2

View File

@ -0,0 +1,74 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Cosmobox
{
public partial class TickControl : Node
{
[Export] public bool pause = false;
private List<IThing> things = new List<IThing>();
private List<IThingPhysics> thingsPhysics = new List<IThingPhysics>();
private List<IThingUI> thingsUI = new List<IThingUI>();
public override void _Ready()
{
// 从场景树的根节点开始查找实现了 IThing 接口的节点
FindThingsInScene(GetTree().GetRoot());
}
private void FindThingsInScene(Node node)
{
// 检查当前节点是否实现了 IThing 接口
if (node is IThing thing)
{
things.Add(thing);
}
// 检查当前节点是否实现了 IThingPhysics 接口
if (node is IThingPhysics physicsThing)
{
thingsPhysics.Add(physicsThing);
}
// 检查当前节点是否实现了 IThingUI 接口
if (node is IThingUI uiThing)
{
thingsUI.Add(uiThing);
}
// 递归查找子节点
foreach (Node child in node.GetChildren())
{
FindThingsInScene(child);
}
}
public override void _Process(double delta)
{
if (!pause)
{
foreach (var thing in things)
{
thing.Update(delta);
}
}
foreach (var thing in thingsUI)
{
thing.UpdateUI();
}
}
public override void _PhysicsProcess(double delta)
{
if (!pause)
{
foreach (var thing in thingsPhysics)
{
thing.PhysicsUpdate(delta);
}
}
}
}
}

View File

@ -0,0 +1 @@
uid://ctbyhk40owvej

View File

@ -0,0 +1,73 @@
using Cosmobox.Def;
using Godot;
using System;
using System.Linq;
namespace Cosmobox
{
public partial class PlayerGenerate : Node2D
{
public override void _Ready()
{
InitResource.instance.defines.TryGetValue("DrawingOrder", out var defines);
if (defines != null)
{
GenerateNode(defines.First().Value as DrawingOrder,this);
}
}
public bool GenerateNode(DrawingOrder drawingOrder, Node parentNode)
{
if (drawingOrder == null)
{
GD.PrintErr("DrawingOrder is null");
return false;
}
if (parentNode == null)
{
GD.PrintErr("Parent node is null");
return false;
}
// 遍历 DrawingOrder 的 DrawNodes 列表
foreach (var drawNode in drawingOrder.DrawNodes)
{
if (!CreateNode(drawNode, parentNode))
{
GD.PrintErr($"Failed to create node: {drawNode.NodeName}");
return false;
}
}
return true;
}
private bool CreateNode(DrawNode drawNode, Node parentNode)
{
if (string.IsNullOrEmpty(drawNode.NodeName))
{
GD.PrintErr("NodeName is null or empty");
return false;
}
// 创建新节点并添加到父节点
var newNode = new ColorRect();
newNode.Name = drawNode.NodeName;
parentNode.AddChild(newNode);
// 如果存在子节点,递归创建
foreach (var child in drawNode.Children)
{
if (!CreateNode(child, newNode))
{
GD.PrintErr($"Failed to create child node: {child.NodeName}");
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1 @@
uid://yl4050ru0ros

45
Script/Item/BagItem.cs Normal file
View File

@ -0,0 +1,45 @@
using Godot;
using System;
using System.Collections.Generic;
public partial class BagItem
{
public ItemResource itemResource;
public int amount;
public string ItemName
{
get
{
return itemResource?.ItemName ?? "Unknown"; // 防止空引用
}
}
public string Description
{
get
{
return itemResource?.Description ?? "No description"; // 防止空引用
}
}
public void AddAmount(int value)
{
if (value < 0)
{
GD.PrintErr("Cannot add negative amount to BagItem.");
return;
}
amount += value;
}
public void RemoveAmount(int value)
{
if (value < 0 || value > amount)
{
GD.PrintErr("Invalid amount to remove from BagItem.");
return;
}
amount -= value;
}
}

View File

@ -0,0 +1 @@
uid://bbwjvic0ilxan

View File

@ -0,0 +1,11 @@
using Godot;
using System;
[GlobalClass]
public partial class ItemResource : Resource
{
[Export] public string ItemName{ get; private set; }
[Export] public string Description{ get; private set; }
[Export] public Texture2D Icon{ get; private set; }
[Export] public bool Stackable{ get; private set; }
}

View File

@ -0,0 +1 @@
uid://d02in2v01dbtb

125
Script/Item/Projectile.cs Normal file
View File

@ -0,0 +1,125 @@
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);
}

View File

@ -0,0 +1 @@
uid://dg675fsx6dpv1

View File

@ -0,0 +1,6 @@
using System;
[AttributeUsage(AttributeTargets.Field)]
public class NeedTranslateAttribute : Attribute
{
}

View File

@ -0,0 +1 @@
uid://ikk1jy48d475

View File

@ -0,0 +1,13 @@
namespace Cosmobox.Def
{
public partial class Character : Define
{
public DrawingOrder
drawingOrder_down,
drawingOrder_up,
drawingOrder_left,
drawingOrder_right;
}
}

View File

@ -0,0 +1 @@
uid://criteyjl5dksn

View File

@ -0,0 +1,42 @@
using System.Xml.Linq;
namespace Cosmobox.Def
{
public class Define
{
public string defName;
[NeedTranslate]
public string label;
[NeedTranslate]
public string discription;
/// <summary>
/// 初始化方法,根据传入的 XML 元素 (<paramref name="xmlDef"/>) 进行处理。
/// </summary>
/// <param name="xmlDef">包含定义信息的 XML 元素。</param>
/// <returns>
/// 返回一个布尔值:
/// - 如果返回 <c>false</c>,表示按照默认方式处理(依次对 XML 进行变量名识别和赋值)。
/// - 如果返回 <c>true</c>,表示使用自定义方式处理,不进行额外的默认处理。
/// </returns>
/// <remarks>
/// <para>
/// 该方法的基类实现会自动识别并处理以下三个变量:
/// - <c>defName</c>
/// - <c>label</c>
/// - <c>description</c>
/// </para>
/// <para>
/// 如果需要覆盖默认行为,可以在派生类中重写此方法,并返回 <c>true</c>
/// 以指示框架跳过默认处理逻辑。
/// </para>
/// </remarks>
public virtual bool Init(XElement xmlDef)
{
defName = xmlDef.Element("defName")?.Value;
label = xmlDef.Element("label")?.Value;
discription = xmlDef.Element("discription")?.Value;
return false;
}
}
}

View File

@ -0,0 +1 @@
uid://btgw3kqfk2i6y

View File

@ -0,0 +1,24 @@
using System.Collections.Generic;
using System.Xml.Linq;
namespace Cosmobox.Def
{
public partial class DrawNode : Define
{
public string NodeName { get; set; }
public List<DrawNode> Children { get; set; } = [];
public override bool Init(XElement xmlDef)
{
base.Init(xmlDef);
NodeName = xmlDef.Element("NodeName")?.Value;
foreach (var childNode in xmlDef.Elements("DrawNode"))
{
DrawNode child = new DrawNode();
child.Init(childNode);
Children.Add(child);
}
return true;
}
}
}

View File

@ -0,0 +1 @@
uid://by1lt06g8xkiy

View File

@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Xml.Linq;
namespace Cosmobox.Def
{
public class DrawingOrder : Define
{
public List<DrawNode> DrawNodes { get; set; } = new List<DrawNode>();
public override bool Init(XElement xmlDef)
{
base.Init(xmlDef);
foreach (var node in xmlDef.Elements("DrawNodes"))
{
DrawNode drawNode = new DrawNode();
drawNode.Init(node);
DrawNodes.Add(drawNode);
}
return true;
}
}
}

View File

@ -0,0 +1 @@
uid://coat5tts3smlo

View File

@ -0,0 +1,177 @@
using Cosmobox.Def;
using Godot;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Xml.Linq;
namespace Cosmobox
{
public partial class InitResource : Node
{
public static InitResource instance;
#if DEBUG
static readonly string corePath = "D:\\godot_Project\\app\\打怪\\Data";
#else
static readonly string corePath = "Data";
#endif
static readonly string coreNamespace = "Cosmobox.Def.";
public Dictionary<string, Dictionary<string, Define>> defines = new();
public override void _Ready()
{
// 在节点准备就绪时调用初始化方法
Init();
instance = this;
}
public void Init()
{
// 获取程序所在的目录路径
string appDirectory = AppDomain.CurrentDomain.BaseDirectory;
// 构建Data目录的完整路径
string dataDirectory = Path.Combine(appDirectory, corePath);
try
{
// 检查Data目录是否存在
if (Directory.Exists(dataDirectory))
{
// 获取Data目录下的所有子文件夹
string[] subDirectories = Directory.GetDirectories(dataDirectory);
// 遍历并输出每个子文件夹的名称
foreach (string dir in subDirectories)
{
string[] xmlFiles = Directory.GetFiles(dir, "*.xml", SearchOption.AllDirectories);
foreach (string xmlFile in xmlFiles)
{
// GD.Print($"找到XML文件: {xmlFile}");
// 调用加载XML数据的方法
LoadXmlData(xmlFile);
}
}
}
else
{
GD.Print($"Data目录不存在: {dataDirectory}");
}
}
catch (Exception ex)
{
GD.Print($"发生错误: {ex.Message}");
}
}
public void LoadXmlData(string xmlFilePath)
{
// 检查文件是否存在
if (!File.Exists(xmlFilePath))
{
GD.Print($"XML文件不存在: {xmlFilePath}");
return;
}
XDocument xdoc = XDocument.Load(xmlFilePath);
// 解析Define节点
XElement rootElement = xdoc.Root;
if (rootElement != null)
{
if (rootElement.Name == "Define")
{
foreach (var element in rootElement.Elements())
{
var def = LoadDefine(element);
var className = element.Name.ToString();
var name = element.Element("defName")?.Value;
if (def != null && !string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(className))
{
defines.TryAdd(className, new Dictionary<string, Define>());
defines[className][name] = (Define)def;
}
GD.Print(name, " ", def);
}
}
}
}
public object LoadDefine(XElement xElement)
{
string className = xElement.Name.ToString();
Assembly assembly = Assembly.GetExecutingAssembly();
Type type;
if (!className.Contains('.'))
{
// 尝试拼接默认命名空间
string fullClassName = coreNamespace + className;
type = assembly.GetType(fullClassName);
// 如果拼接命名空间后仍找不到,尝试直接查找(可能是全局命名空间下的类)
if (type == null)
{
type = assembly.GetType(className);
}
}
else
{
// 直接查找
type = assembly.GetType(className);
}
if (type == null)
{
GD.PrintErr($"未定义的类型: {className}");
return null;
}
var constructor = type.GetConstructor(Type.EmptyTypes);
if (constructor == null)
{
GD.PrintErr($"{className} 必须包含无参构造函数");
return null;
}
// 3. 创建实例
object instance;
try
{
instance = Activator.CreateInstance(type);
}
catch (Exception ex)
{
GD.PrintErr($"创建 {className} 实例失败: {ex.Message}");
return null;
}
// 4. 检查是否继承自 Define
if (instance is not Define define)
{
GD.PrintErr($"{className} 必须继承自 Define");
return null;
}
define.Init(xElement);
return define;
// SetField(define, "Address", "123 Main St");
}
public static void SetField(object obj, string fieldName, object value)
{
Type type = obj.GetType();
FieldInfo field = type.GetField(fieldName);
if (field != null)
{
field.SetValue(obj, Convert.ChangeType(value, field.FieldType));
}
else
{
Console.WriteLine($"Field '{fieldName}' not found.");
}
}
}
}

View File

@ -0,0 +1 @@
uid://cxwpi2iikslsq

214
Script/Map/DoubleMap.cs Normal file
View File

@ -0,0 +1,214 @@
using Godot;
using System;
using System.Collections.Generic;
using System.Numerics;
using static Cosmobox.TileType;
namespace Cosmobox
{
public partial class DoubleMap : Node
{
[Export] TileMapLayer displayLayer;
[Export] TileMapLayer mapLayer;
PerlinNoise perlinNoise = new(1573);
readonly Dictionary<Tuple<TileType, TileType, TileType, TileType>, Vector3I> neighboursToAtlasCoord = new() {
{new (Grass, Grass, Grass, Grass), new Vector3I(2, 1,0)}, // All corners
{new (Dirt, Dirt, Dirt, Grass), new Vector3I(1, 3,0)}, // Outer bottom-right corner
{new (Dirt, Dirt, Grass, Dirt), new Vector3I(0, 0,0)}, // Outer bottom-left corner
{new (Dirt, Grass, Dirt, Dirt), new Vector3I(0, 2,0)}, // Outer top-right corner
{new (Grass, Dirt, Dirt, Dirt), new Vector3I(3, 3,0)}, // Outer top-left corner
{new (Dirt, Grass, Dirt, Grass), new Vector3I(1, 0,0)}, // Right edge
{new (Grass, Dirt, Grass, Dirt), new Vector3I(3, 2,0)}, // Left edge
{new (Dirt, Dirt, Grass, Grass), new Vector3I(3, 0,0)}, // Bottom edge
{new (Grass, Grass, Dirt, Dirt), new Vector3I(1, 2,0)}, // Top edge
{new (Dirt, Grass, Grass, Grass), new Vector3I(1, 1,0)}, // Inner bottom-right corner
{new (Grass, Dirt, Grass, Grass), new Vector3I(2, 0,0)}, // Inner bottom-left corner
{new (Grass, Grass, Dirt, Grass), new Vector3I(2, 2,0)}, // Inner top-right corner
{new (Grass, Grass, Grass, Dirt), new Vector3I(3, 1,0)}, // Inner top-left corner
{new (Dirt, Grass, Grass, Dirt), new Vector3I(2, 3,0)}, // Bottom-left top-right corners
{new (Grass, Dirt, Dirt, Grass), new Vector3I(0, 1,0)}, // Top-left down-right corners
{new (Dirt, Dirt, Dirt, Dirt), new Vector3I(0, 3,0)}, // No corners
// {new (Grass, Grass, Grass, Grass), new Vector3I(2, 1,1)}, // All corners
{new (Water, Water, Water, Grass), new Vector3I(1, 3,1)}, // Outer bottom-right corner
{new (Water, Water, Grass, Water), new Vector3I(0, 0,1)}, // Outer bottom-left corner
{new (Water, Grass, Water, Water), new Vector3I(0, 2,1)}, // Outer top-right corner
{new (Grass, Water, Water, Water), new Vector3I(3, 3,1)}, // Outer top-left corner
{new (Water, Grass, Water, Grass), new Vector3I(1, 0,1)}, // Right edge
{new (Grass, Water, Grass, Water), new Vector3I(3, 2,1)}, // Left edge
{new (Water, Water, Grass, Grass), new Vector3I(3, 0,1)}, // Bottom edge
{new (Grass, Grass, Water, Water), new Vector3I(1, 2,1)}, // Top edge
{new (Water, Grass, Grass, Grass), new Vector3I(1, 1,1)}, // Inner bottom-right corner
{new (Grass, Water, Grass, Grass), new Vector3I(2, 0,1)}, // Inner bottom-left corner
{new (Grass, Grass, Water, Grass), new Vector3I(2, 2,1)}, // Inner top-right corner
{new (Grass, Grass, Grass, Water), new Vector3I(3, 1,1)}, // Inner top-left corner
{new (Water, Grass, Grass, Water), new Vector3I(2, 3,1)}, // Bottom-left top-right corners
{new (Grass, Water, Water, Grass), new Vector3I(0, 1,1)}, // Top-left down-right corners
{new (Water, Water, Water, Water), new Vector3I(0, 3,1)}, // No corners
// {new (Dirt, Dirt, Dirt, Dirt), new Vector3I(2, 1,2)}, // All corners
{new (Water, Water, Water, Dirt), new Vector3I(1, 3,2)}, // Outer bottom-right corner
{new (Water, Water, Dirt, Water), new Vector3I(0, 0,2)}, // Outer bottom-left corner
{new (Water, Dirt, Water, Water), new Vector3I(0, 2,2)}, // Outer top-right corner
{new (Dirt, Water, Water, Water), new Vector3I(3, 3,2)}, // Outer top-left corner
{new (Water, Dirt, Water, Dirt), new Vector3I(1, 0,2)}, // Right edge
{new (Dirt, Water, Dirt, Water), new Vector3I(3, 2,2)}, // Left edge
{new (Water, Water, Dirt, Dirt), new Vector3I(3, 0,2)}, // Bottom edge
{new (Dirt, Dirt, Water, Water), new Vector3I(1, 2,2)}, // Top edge
{new (Water, Dirt, Dirt, Dirt), new Vector3I(1, 1,2)}, // Inner bottom-right corner
{new (Dirt, Water, Dirt, Dirt), new Vector3I(2, 0,2)}, // Inner bottom-left corner
{new (Dirt, Dirt, Water, Dirt), new Vector3I(2, 2,2)}, // Inner top-right corner
{new (Dirt, Dirt, Dirt, Water), new Vector3I(3, 1,2)}, // Inner top-left corner
{new (Water, Dirt, Dirt, Water), new Vector3I(2, 3,2)}, // Bottom-left top-right corners
{new (Dirt, Water, Water, Dirt), new Vector3I(0, 1,2)}, // Top-left down-right corners
{ new (Grass, Dirt, Water, Grass), new Vector3I(0, 0,3)},
{ new (Dirt, Water, Grass, Grass), new Vector3I(1, 0,3)},
{ new (Water, Dirt, Grass, Grass), new Vector3I(2, 0,3)},
{ new (Dirt, Grass, Grass, Water), new Vector3I(3, 0,3)},
{ new (Grass, Water, Grass, Dirt), new Vector3I(3, 1,3)},
{ new (Grass, Dirt, Grass, Water), new Vector3I(3, 2,3)},
{ new (Grass, Water, Dirt, Grass), new Vector3I(3, 3,3)},
{ new (Grass, Grass, Water, Dirt), new Vector3I(2, 3,3)},
{ new (Grass, Grass, Dirt, Water), new Vector3I(1, 3,3)},
{ new (Water, Grass, Grass, Dirt), new Vector3I(0, 3,3)},
{ new (Dirt, Grass, Water, Grass), new Vector3I(0, 2,3)},
{ new (Water, Grass, Dirt, Grass), new Vector3I(0, 1,3)},
{ new (Dirt, Grass, Water, Dirt), new Vector3I(0, 0,4)},
{ new (Grass, Water, Dirt, Dirt), new Vector3I(1, 0,4)},
{ new (Water, Grass, Dirt, Dirt), new Vector3I(2, 0,4)},
{ new (Grass, Dirt, Dirt, Water), new Vector3I(3, 0,4)},
{ new (Dirt, Water, Dirt, Grass), new Vector3I(3, 1,4)},
{ new (Dirt, Grass, Dirt, Water), new Vector3I(3, 2,4)},
{ new (Dirt, Water, Grass, Dirt), new Vector3I(3, 3,4)},
{ new (Dirt, Dirt, Water, Grass), new Vector3I(2, 3,4)},
{ new (Dirt, Dirt, Grass, Water), new Vector3I(1, 3,4)},
{ new (Water, Dirt, Dirt, Grass), new Vector3I(0, 3,4)},
{ new (Grass, Dirt, Water, Dirt), new Vector3I(0, 2,4)},
{ new (Water, Dirt, Grass, Dirt), new Vector3I(0, 1,4)},
{ new (Water, Grass, Dirt, Water), new Vector3I(0, 0,5)},
{ new (Grass, Dirt, Water, Water), new Vector3I(1, 0,5)},
{ new (Dirt, Grass, Water, Water), new Vector3I(2, 0,5)},
{ new (Grass, Water, Water, Dirt), new Vector3I(3, 0,5)},
{ new (Water, Dirt, Water, Grass), new Vector3I(3, 1,5)},
{ new (Water, Grass, Water, Dirt), new Vector3I(3, 2,5)},
{ new (Water, Dirt, Grass, Water), new Vector3I(3, 3,5)},
{ new (Water, Water, Dirt, Grass), new Vector3I(2, 3,5)},
{ new (Water, Water, Grass, Dirt), new Vector3I(1, 3,5)},
{ new (Dirt, Water, Water, Grass), new Vector3I(0, 3,5)},
{ new (Grass, Water, Dirt, Water), new Vector3I(0, 2,5)},
{ new (Dirt, Water, Grass, Water), new Vector3I(0, 1,5)},
};
private static readonly Vector2I[] _shifts =
[
new(0, 0),
new(1, 0),
new(0, 1),
new(1, 1)
];
public override void _Ready()
{
int wide = 100;
float scale = 0.1f; // 缩放因子
for (int i = 0; i < wide; i++)
{
for (int j = 0; j < wide; j++)
{
// 获取噪声值并归一化到 [0, 1]
var noiseValue = perlinNoise.Noise(i * scale, j * scale, 0);
var val = (noiseValue + 1) / 2;
// 根据噪声值设置地形类型
if (val > 0.3)
{
mapLayer.SetCell(new Vector2I(i, j), 0, TileTypeToAtlasCoord(Grass));
}
else if (val > 0.25)
{
mapLayer.SetCell(new Vector2I(i, j), 0, TileTypeToAtlasCoord(Dirt));
}
else
{
mapLayer.SetCell(new Vector2I(i, j), 0, TileTypeToAtlasCoord(Water));
}
}
}
UpdateDisplay();
}
public void UpdateDisplay()
{
var tilePos = mapLayer.GetUsedCells();
foreach (var pos in tilePos)
{
UpdateDisplay(pos);
// UpdateDisplay(pos - new Vector2I(1, 0));
// UpdateDisplay(pos - new Vector2I(1, 1));
// UpdateDisplay(pos - new Vector2I(0, 1));
}
}
public void UpdateDisplay(Vector2I coord)
{
var key = GetNearTileData(coord);
if (neighboursToAtlasCoord.TryGetValue(key, out Vector3I atlasCoord))
{
displayLayer.SetCell(coord, atlasCoord[2], new(atlasCoord[0], atlasCoord[1]));
}
else
{
displayLayer.SetCell(coord, 1, new(0, 3));
}
}
public TileType GetTileType(Vector2I pos)
{
var cell = mapLayer.GetCellAtlasCoords(pos);
return AtlasCoordToTileType(cell);
}
public static TileType AtlasCoordToTileType(Vector2I coord)
{
return coord switch
{
Vector2I(0, 0) => Grass,
Vector2I(1, 0) => Dirt,
Vector2I(2, 0) => Water,
_ => Water,
};
}
public static Vector2I TileTypeToAtlasCoord(TileType tileType)
{
return tileType switch
{
Grass => new(0, 0),
Dirt => new(1, 0),
Water => new(2, 0),
_ => new(0, 0),
};
}
public Tuple<TileType, TileType, TileType, TileType> GetNearTileData(Vector2I coord)
{
return new Tuple<TileType, TileType, TileType, TileType>(
GetTileType(coord + _shifts[0]),
GetTileType(coord + _shifts[1]),
GetTileType(coord + _shifts[2]),
GetTileType(coord + _shifts[3])
);
}
public void SetTile(Vector2I pos, TileType tileType)
{
mapLayer.SetCell(pos, 0, TileTypeToAtlasCoord(tileType));
}
}
}

View File

@ -0,0 +1 @@
uid://bc2ats1ib4dde

10
Script/Map/TileType.cs Normal file
View File

@ -0,0 +1,10 @@
namespace Cosmobox
{
public enum TileType
{
None,
Grass,
Water,
Dirt,
}
}

View File

@ -0,0 +1 @@
uid://dqd3d18u1e3r5

View File

@ -0,0 +1,71 @@
using Godot;
using System;
using System.Collections.Generic;
namespace Cosmobox
{
public partial class BagItemList
{
public List<BagItem> Items = new();
// 查找物品
public BagItem Find(string name)
{
foreach (var item in Items)
{
if (item.ItemName == name)
{
return item;
}
}
return null;
}
// 添加物品
public bool AddItem(ItemResource resource, int amount = 1)
{
if (resource == null || amount <= 0)
{
GD.PrintErr("Invalid item or amount.");
return false;
}
// 检查是否已有相同物品
var existingItem = Find(resource.ItemName);
if (existingItem != null && resource.Stackable)
{
existingItem.AddAmount(amount); // 堆叠物品
}
else
{
// 创建新物品条目
var newItem = new BagItem
{
itemResource = resource,
amount = amount
};
Items.Add(newItem);
}
return true;
}
// 移除物品
public bool RemoveItem(string name, int amount = 1)
{
var item = Find(name);
if (item == null)
{
GD.Print($"Item '{name}' not found in bag.");
return false;
}
if (amount >= item.amount)
{
Items.Remove(item); // 完全移除物品
return true;
}
item.RemoveAmount(amount); // 减少数量
return true;
}
}
}

View File

@ -0,0 +1 @@
uid://b1fsx76po5ksu

View File

@ -0,0 +1,225 @@
using Godot;
using System;
namespace Cosmobox
{
public partial class CameraControl : Camera2D
{
[Export] public Node2D Target; // 要跟随的目标(通常为玩家角色)
[Export] public bool EnableSmoothing = true; // 启用平滑跟随
[Export(PropertyHint.Range, "0.1,10,0.1")]
public float SmoothingSpeed = 2.5f; // 平滑跟随速度推荐值2.0-4.0
[Export] public bool EnableBounds = false; // 启用边界限制
[Export] public Rect2 CameraBounds; // 摄像机移动边界
[Export] public Vector2 PositionOffset = Vector2.Zero; // 目标位置偏移
[Export] public bool ScaleWithZoom = true; // 边界是否随缩放调整
[Export] public float DeadZoneRadius = 0; // 摄像机不移动的半径(减少微小移动)
[Export] public float ZoomSensitivity = 0.1f; // 缩放灵敏度
[Export] public Vector2 MinZoom = new Vector2(0.5f, 0.5f); // 最小缩放
[Export] public Vector2 MaxZoom = new Vector2(2.0f, 2.0f); // 最大缩放
private Vector2 _targetPosition;
private Vector2 _currentVelocity = Vector2.Zero; // 用于平滑插值
private Rect2 _effectiveBounds; // 实际使用的边界(考虑缩放)
public override void _Ready()
{
if (Target == null)
{
// 自动查找玩家作为目标
Target = GetTree().Root.GetNodeOrNull<Node2D>("Player");
if (Target == null)
{
GD.PrintErr("CameraControl: Failed to find Player node. Assign a Target manually.");
}
}
// 确保摄像机位置初始化
if (Target != null)
{
_targetPosition = Target.GlobalPosition + PositionOffset;
GlobalPosition = _targetPosition;
}
// 初始化有效边界
UpdateEffectiveBounds();
}
public override void _PhysicsProcess(double delta)
{
if (Target == null)
return;
float deltaFloat = (float)delta;
// 更新目标位置(考虑偏移)
Vector2 newTarget = Target.GlobalPosition + PositionOffset;
// 应用死区减少微小移动
if (DeadZoneRadius > 0 && newTarget.DistanceTo(_targetPosition) < DeadZoneRadius)
{
newTarget = _targetPosition;
}
else
{
_targetPosition = newTarget;
}
// 应用边界限制
if (EnableBounds)
{
UpdateEffectiveBounds();
_targetPosition = ClampPosition(_targetPosition);
}
// 应用平滑过渡或直接跟随
Vector2 newPosition;
if (EnableSmoothing && SmoothingSpeed > 0)
{
// 使用SmoothDamp获得更自然的缓动效果
newPosition = SmoothDamp(GlobalPosition, _targetPosition, ref _currentVelocity, 1 / SmoothingSpeed, deltaFloat);
}
else
{
newPosition = _targetPosition;
}
// 最终位置赋值
GlobalPosition = newPosition;
}
public override void _UnhandledInput(InputEvent @event)
{
// 鼠标滚轮缩放控制
if (@event is InputEventMouseButton mouseEvent)
{
if (mouseEvent.IsPressed())
{
Vector2 zoomFactor = Zoom;
// // 滚轮向上 - 放大
// if (mouseEvent.ButtonIndex == MouseButton.WheelUp)
// {
// zoomFactor -= Vector2.One * ZoomSensitivity;
// }
// // 滚轮向下 - 缩小
// else if (mouseEvent.ButtonIndex == MouseButton.WheelDown)
// {
// zoomFactor += Vector2.One * ZoomSensitivity;
// }
// // 钳制缩放值
// zoomFactor.X = Mathf.Clamp(zoomFactor.X, MinZoom.X, MaxZoom.X);
// zoomFactor.Y = Mathf.Clamp(zoomFactor.Y, MinZoom.Y, MaxZoom.Y);
if (zoomFactor != Zoom)
{
Zoom = zoomFactor;
UpdateEffectiveBounds();
}
}
}
}
/// <summary>
/// 平滑插值函数类似Unity的SmoothDamp
/// </summary>
private Vector2 SmoothDamp(Vector2 current, Vector2 target, ref Vector2 currentVelocity, float smoothTime, float deltaTime, float maxSpeed = float.MaxValue)
{
float omega = 2f / Mathf.Max(0.0001f, smoothTime);
float x = omega * deltaTime;
float exp = 1f / (1f + x + 0.48f * x * x + 0.235f * x * x * x);
Vector2 change = current - target;
Vector2 originalTarget = target;
float maxChange = maxSpeed * smoothTime;
// 使用自定义方法替代ClampMagnitude
float magnitude = change.Length();
if (magnitude > maxChange && maxChange > 0)
{
change = change.Normalized() * maxChange;
}
target = current - change;
Vector2 temp = (currentVelocity + omega * change) * deltaTime;
currentVelocity = (currentVelocity - omega * temp) * exp;
Vector2 result = target + (change + temp) * exp;
// 防止过冲
Vector2 toOriginalTarget = originalTarget - current;
Vector2 toResult = result - originalTarget;
if (toOriginalTarget.Dot(toResult) > 0)
{
result = originalTarget;
currentVelocity = (result - originalTarget) / deltaTime;
}
return result;
}
/// <summary>
/// 更新实际使用的边界(考虑缩放)
/// </summary>
private void UpdateEffectiveBounds()
{
if (!EnableBounds || !ScaleWithZoom)
{
_effectiveBounds = CameraBounds;
return;
}
// 根据缩放比例调整边界
Vector2 halfViewSize = GetViewportRect().Size * 0.5f / Zoom;
Vector2 min = CameraBounds.Position + halfViewSize;
Vector2 max = CameraBounds.End - halfViewSize;
// 确保有效边界有效
if (min.X > max.X) min.X = max.X = (min.X + max.X) * 0.5f;
if (min.Y > max.Y) min.Y = max.Y = (min.Y + max.Y) * 0.5f;
_effectiveBounds = new Rect2(min, max - min);
}
/// <summary>
/// 钳制位置在边界范围内
/// </summary>
private Vector2 ClampPosition(Vector2 position)
{
return new Vector2(
Mathf.Clamp(position.X, _effectiveBounds.Position.X, _effectiveBounds.End.X),
Mathf.Clamp(position.Y, _effectiveBounds.Position.Y, _effectiveBounds.End.Y)
);
}
// 调试:在编辑器中绘制边界可视化
public override void _Draw()
{
if (Engine.IsEditorHint() && EnableBounds)
{
// 绘制主边界
var rect = new Rect2(_effectiveBounds.Position - GlobalPosition, _effectiveBounds.Size);
DrawRect(rect, Colors.Red, false, 2.0f);
// 绘制原始边界参考线
var origRect = new Rect2(CameraBounds.Position - GlobalPosition, CameraBounds.Size);
DrawRect(origRect, Colors.Yellow, false, 1.0f);
}
}
/// <summary>
/// 设置摄像机边界简化API
/// </summary>
public void SetBounds(Rect2 bounds, bool updateImmediately = true)
{
CameraBounds = bounds;
EnableBounds = true;
if (updateImmediately)
UpdateEffectiveBounds();
}
}
}

View File

@ -0,0 +1 @@
uid://bhpimjcr0h66h

View File

@ -0,0 +1,232 @@
using Godot;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
namespace Cosmobox
{
public static class CharacterLoader
{
// 支持的部件目录列表
private static readonly string[] ComponentFolders = {
"body", "clothing", "hair", "hairBackground", "head", "leftEar", "rightEar"
};
// 方向关键词映射到索引位置
private static readonly Dictionary<string, int> DirectionMapping = new Dictionary<string, int>(System.StringComparer.OrdinalIgnoreCase)
{
{"south", 0}, // 南方向 - 索引0
{"north", 1}, // 北方向 - 索引1
{"east", 2}, // 东方向 - 索引2
{"west", 2} // 西方向也映射到索引2共用东方向的纹理
};
/// <summary>
/// 加载角色所有部件的纹理
/// </summary>
public static Dictionary<string, Texture2D[]> LoadCharacterTextures(string rootPath)
{
var textures = new Dictionary<string, Texture2D[]>();
// GD.Print($"开始加载角色纹理资源,根目录: {rootPath}");
// 检查根目录是否存在
if (!DirAccess.DirExistsAbsolute(rootPath))
{
// GD.PrintErr($"错误:资源根目录不存在 - {rootPath}");
return textures;
}
using (var dir = DirAccess.Open(rootPath))
{
if (dir == null)
{
GD.PrintErr($"错误:无法打开根目录 - {rootPath}");
return textures;
}
// GD.Print($"找到根目录,开始扫描部件文件夹...");
// 遍历所有支持的部件目录
foreach (string component in ComponentFolders)
{
string componentPath = Path.Combine(rootPath, component);
// GD.Print($"检查部件: {component},路径: {componentPath}");
if (DirAccess.DirExistsAbsolute(componentPath))
{
// GD.Print($"找到部件文件夹: {component}");
Texture2D[] componentTextures = LoadComponentTextures(componentPath);
if (componentTextures != null && componentTextures.Length == 3)
{
// GD.Print($"成功加载部件: {component},纹理数量: 3");
textures[component] = componentTextures;
}
else
{
GD.PrintErr($"警告:部件{component}纹理加载不完整,实际数量: {componentTextures?.Length ?? 0}");
}
}
else
{
// GD.Print($"部件文件夹不存在: {component}");
}
}
}
// GD.Print($"资源加载完成,成功部件: {textures.Count}/{ComponentFolders.Length}");
return textures;
}
/// <summary>
/// 加载单个部件的所有方向纹理
/// </summary>
private static Texture2D[] LoadComponentTextures(string folderPath)
{
Texture2D[] textures = new Texture2D[3];
var foundFiles = new List<(string path, int index)>();
// GD.Print($"加载部件文件夹: {folderPath}");
using (var dir = DirAccess.Open(folderPath))
{
if (dir == null)
{
GD.PrintErr($"错误:无法打开部件目录 - {folderPath}");
return textures;
}
var status = dir.ListDirBegin();
if (status != Error.Ok)
{
GD.PrintErr($"错误:无法开始文件列表 ({status}) - {folderPath}");
return textures;
}
string fileName = dir.GetNext();
int fileCount = 0;
int matchedCount = 0;
List<string> unmatchedFiles = new List<string>();
// GD.Print($"开始扫描文件...");
while (!string.IsNullOrEmpty(fileName))
{
fileCount++;
if (!dir.CurrentIsDir())
{
string filePath = Path.Combine(folderPath, fileName);
// GD.Print($"处理文件 #{fileCount}: {fileName}");
// 检查文件扩展名
if (!IsImageFile(fileName))
{
// GD.Print($"跳过非图片文件: {fileName}");
fileName = dir.GetNext();
continue;
}
bool matched = false;
// 检测方向关键词
foreach (var kv in DirectionMapping)
{
if (fileName.Contains(kv.Key, System.StringComparison.OrdinalIgnoreCase))
{
// GD.Print($"找到方向关键词 '{kv.Key}' -> 索引 {kv.Value}");
foundFiles.Add((filePath, kv.Value));
matched = true;
matchedCount++;
break;
}
}
if (!matched)
{
GD.PrintErr($"警告:无法识别的方向名称 - {fileName}");
unmatchedFiles.Add(fileName);
}
}
else
{
// GD.Print($"跳过子目录: {fileName}");
}
fileName = dir.GetNext();
}
dir.ListDirEnd();
// GD.Print($"文件夹扫描完成:");
// GD.Print($"- 总文件: {fileCount}");
// GD.Print($"- 匹配文件: {matchedCount}");
if (unmatchedFiles.Count > 0)
{
GD.PrintErr($"警告: {unmatchedFiles.Count} 个文件未包含方向关键词(south/north/east/west):");
foreach (var f in unmatchedFiles)
{
GD.PrintErr($" - {f}");
}
}
}
// 检查是否所有方向都找到了文件
bool[] foundDirections = new bool[3];
// 加载纹理
foreach (var (path, index) in foundFiles)
{
if (index >= 0 && index < textures.Length)
{
if (textures[index] == null)
{
// GD.Print($"加载纹理: {Path.GetFileName(path)} -> 方向索引 {index}");
textures[index] = ResourceLoader.Load<Texture2D>(path);
foundDirections[index] = true;
if (textures[index] == null)
{
GD.PrintErr($"错误:无法加载纹理资源 - {path}");
}
}
else
{
GD.Print($"跳过纹理: {Path.GetFileName(path)} -> 方向索引 {index}(已有更优先的纹理)");
}
}
else
{
GD.PrintErr($"错误:无效方向索引 {index} - {path}");
}
}
// 检查缺失的方向
for (int i = 0; i < foundDirections.Length; i++)
{
if (!foundDirections[i])
{
string direction;
if (i == 0) direction = "south";
else if (i == 1) direction = "north";
else direction = "east";
GD.PrintErr($"警告:缺少{direction}方向纹理");
}
}
return textures;
}
/// <summary>
/// 检查文件是否是图片格式
/// </summary>
private static bool IsImageFile(string fileName)
{
string ext = Path.GetExtension(fileName).ToLower();
return ext == ".png" || ext == ".jpg" || ext == ".jpeg" || ext == ".webp" || ext == ".bmp";
}
}
}

View File

@ -0,0 +1 @@
uid://cvdj4q7yvd85a

252
Script/Pawn/Pawn.cs Normal file
View File

@ -0,0 +1,252 @@
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;
}
}
}

1
Script/Pawn/Pawn.cs.uid Normal file
View File

@ -0,0 +1 @@
uid://doim6711upf0a

141
Script/Pawn/Player.cs Normal file
View File

@ -0,0 +1,141 @@
using Godot;
using System;
using System.Collections.Generic; // 使用 List 和 Dictionary 需要这个命名空间
namespace Cosmobox
{
public partial class Player : Pawn, IThing
{
// === 玩家属性 ===
[Export] public Camera2D PlayerCamera; // 玩家摄像机
[Export] public Sprite2D AimCursor; // 瞄准光标精灵
[Export] public Vector2 AimOffset = Vector2.Zero; // 瞄准点偏移量
public BagItemList bagItem = new();
public override void _Ready()
{
// 调用基类的_Ready方法
base._Ready();
// 尝试查找摄像机(如果未分配)
if (PlayerCamera == null)
{
PlayerCamera = GetViewport().GetCamera2D();
if (PlayerCamera == null)
{
GD.PrintErr("Player: 未分配摄像机且视口中没有活动摄像机!");
}
}
// 初始化瞄准光标
if (AimCursor != null)
{
AimCursor.Visible = true;
}
}
public void Update(double delta)
{
// 获取输入方向
Vector2 inputDirection = GetInputDirection();
// 处理移动调用Pawn基类方法
HandleMovement(inputDirection);
// 更新角色朝向(鼠标方向)
UpdateDirectionToMouse();
}
/// <summary>
/// 更新角色朝向鼠标方向
/// </summary>
private void UpdateDirectionToMouse()
{
if (PlayerCamera == null) return;
// 获取鼠标在游戏世界中的位置
Vector2 mousePosition = GetGlobalMousePosition();
// 计算从玩家位置到鼠标位置的方向向量
Vector2 directionToMouse = (mousePosition - GlobalPosition).Normalized();
// 调用基类方法更新视觉方向
UpdateDirection(directionToMouse);
}
/// <summary>
/// 更新瞄准光标位置
/// </summary>
private void UpdateAimCursor()
{
if (AimCursor == null || PlayerCamera == null) return;
// 获取鼠标位置
Vector2 mousePosition = GetGlobalMousePosition();
// 设置光标位置(带偏移)
AimCursor.GlobalPosition = mousePosition + AimOffset;
}
/// <summary>
/// 获取键盘输入方向
/// </summary>
/// <returns>归一化的移动方向向量</returns>
private Vector2 GetInputDirection()
{
Vector2 direction = Vector2.Zero;
// 处理上下左右输入(确保项目设置中已配置这些输入)
if (Input.IsActionPressed("ui_up"))
{
direction.Y -= 1; // 上移
}
if (Input.IsActionPressed("ui_down"))
{
direction.Y += 1; // 下移
}
if (Input.IsActionPressed("ui_left"))
{
direction.X -= 1; // 左移
}
if (Input.IsActionPressed("ui_right"))
{
direction.X += 1; // 右移
}
return direction.Normalized(); // 确保斜向移动速度一致
}
/// <summary>
/// 获取瞄准方向(从玩家指向鼠标位置)
/// </summary>
public Vector2 GetAimDirection()
{
if (PlayerCamera == null) return Vector2.Zero;
Vector2 mousePosition = GetGlobalMousePosition();
return (mousePosition - GlobalPosition).Normalized();
}
/// <summary>
/// 获取瞄准角度(弧度)
/// </summary>
public float GetAimAngle()
{
Vector2 aimDir = GetAimDirection();
return Mathf.Atan2(aimDir.Y, aimDir.X);
}
/// <summary>
/// 获取瞄准角度(度)
/// </summary>
public float GetAimAngleDegrees()
{
return Mathf.RadToDeg(GetAimAngle());
}
}
}

View File

@ -0,0 +1 @@
uid://c1g503q7yoy1s

45
Script/UI/BagItemUI.cs Normal file
View File

@ -0,0 +1,45 @@
using Godot;
using System;
namespace Cosmobox
{
public partial class BagItemUI : Button
{
[Export] public TextureRect icon;
[Export] public Label count, itemName;
[Export] public Control itemNamePanel;
[Export] public Texture2D emptyIcon;
public override void _Ready()
{
itemNamePanel.Visible = false;
}
public void SetItem(BagItem bagItem)
{
if (bagItem == null || bagItem.itemResource == null)
{
SetEmpty();
return;
}
itemName.Text = bagItem.itemResource.ItemName;
icon.Texture = bagItem.itemResource.Icon ?? emptyIcon;
count.Text = bagItem.amount > 0 ? bagItem.amount.ToString() : "空";
}
public void SetEmpty()
{
icon.Texture = emptyIcon;
count.Text = "空";
}
void _on_mouse_entered()
{
itemNamePanel.Visible = true;
// GD.Print("鼠标进入");
}
void _on_mouse_exited()
{
itemNamePanel.Visible = false;
}
}
}

View File

@ -0,0 +1 @@
uid://cc7chrmpuw4vu

101
Script/UI/BagUI.cs Normal file
View File

@ -0,0 +1,101 @@
using Godot;
using System;
namespace Cosmobox
{
public partial class BagUI : Control
{
[Export] public Player player;
[Export] public Label text;
[Export] public Panel background;
[Export] public Control itemContainer;
[Export] public float animationTime = 0.5f;
[Export] public PackedScene itemUI;
private float animationTimeRun = 0;
private bool isOpen = false;
private Vector2 labelOriginalPosition;
private Vector2 backgroundOriginalPosition;
public bool IsOpen
{
get { return isOpen; }
}
public override void _Ready()
{
labelOriginalPosition = text.Position;
backgroundOriginalPosition = background.Position;
// animationTimeRun = 0.01f;
text.Position = new Vector2(text.Position.X, labelOriginalPosition.Y - text.Size.Y);
background.Position = new Vector2(background.Position.X, backgroundOriginalPosition.Y + (background.Size.Y + 50));
isOpen = false;
}
public override void _Process(double delta)
{
if (animationTimeRun > 0)
{
animationTimeRun -= (float)delta;
if (isOpen)
{
text.Position = new Vector2(text.Position.X, labelOriginalPosition.Y - (animationTimeRun / animationTime) * text.Size.Y);
background.Position = new Vector2(background.Position.X, backgroundOriginalPosition.Y + (animationTimeRun / animationTime) * (background.Size.Y + 50));
if (animationTimeRun <= 0)
{
text.Position = labelOriginalPosition;
background.Position = backgroundOriginalPosition;
}
}
else
{
text.Position = new Vector2(text.Position.X, labelOriginalPosition.Y - (1 - animationTimeRun / animationTime) * text.Size.Y);
background.Position = new Vector2(background.Position.X, backgroundOriginalPosition.Y + (1 - animationTimeRun / animationTime) * (background.Size.Y + 50));
if (animationTimeRun <= 0)
{
Visible = false;
}
}
}
}
public void OpenBag()
{
Visible = true;
isOpen = true;
UpdateUI();
animationTimeRun = animationTime - animationTimeRun;
isOpen = true;
}
public void CloseBag()
{
isOpen = false;
animationTimeRun = animationTime - animationTimeRun;
isOpen = false;
}
public void UpdateUI()
{
// 清除容器中现有的所有子节点
foreach (Node child in itemContainer.GetChildren())
{
child.QueueFree();
}
var bagItems = player.bagItem.Items;
foreach (BagItem item in bagItems)
{
// 实例化新的物品UI
BagItemUI itemInstance = (BagItemUI)itemUI.Instantiate();
// 设置物品数据
itemInstance.SetItem(item);
// 将实例添加到容器中
itemContainer.AddChild(itemInstance);
}
}
}
}

1
Script/UI/BagUI.cs.uid Normal file
View File

@ -0,0 +1 @@
uid://dry2x5otnbedt

73
Script/UI/DevUi.cs Normal file
View File

@ -0,0 +1,73 @@
using Godot;
using System;
namespace Cosmobox
{
public partial class DevUi : Control
{
[Export] public Player player;
[Export] public Container itemDevList; // 改为Container类型更准确
public override void _Ready()
{
InitializeItemButtons();
}
private void InitializeItemButtons()
{
// // 清空现有按钮(如果有)
// foreach (Node child in itemDevList.GetChildren())
// {
// child.QueueFree();
// }
// 获取所有物品
var items = ItemResourceManager.GetAllItems();
// 为每个物品创建按钮
foreach (var itemPair in items)
{
var button = new Button();
button.Text = $"{itemPair.Key}"; // 显示物品名称
// 绑定点击事件,使用闭包捕获当前物品名称
string currentItemName = itemPair.Key;
button.Pressed += () => OnItemButtonPressed(currentItemName);
itemDevList.AddChild(button);
}
}
private void OnItemButtonPressed(string itemName)
{
// 添加物品到背包
bool success = AddItem(itemName);
if (success)
{
GD.Print($"成功添加物品: {itemName}");
}
else
{
GD.PrintErr($"添加物品失败: {itemName}");
}
}
public bool AddItem(string itemName, int amount = 1)
{
var item = ItemResourceManager.GetItem(itemName);
if (item == null)
{
GD.PrintErr($"物品不存在: {itemName}");
return false;
}
return player.bagItem.AddItem(item, amount);
}
public bool ClearItems()
{
player.bagItem.Items.Clear();
return true;
}
}
}

1
Script/UI/DevUi.cs.uid Normal file
View File

@ -0,0 +1 @@
uid://bpaoua3tyv5ju

69
export_presets.cfg Normal file
View File

@ -0,0 +1,69 @@
[preset.0]
name="Windows Desktop"
platform="Windows Desktop"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../app/打怪/肉鸽.exe"
patches=PackedStringArray()
encryption_include_filters=""
encryption_exclude_filters=""
seed=0
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
codesign/enable=false
codesign/timestamp=true
codesign/timestamp_server_url=""
codesign/digest_algorithm=1
codesign/description=""
codesign/custom_options=PackedStringArray()
application/modify_resources=false
application/icon=""
application/console_wrapper_icon=""
application/icon_interpolation=4
application/file_version=""
application/product_version=""
application/company_name=""
application/product_name=""
application/file_description=""
application/copyright=""
application/trademarks=""
application/export_angle=0
application/export_d3d12=0
application/d3d12_agility_sdk_multiarch=true
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="Expand-Archive -LiteralPath '{temp_dir}\\{archive_name}' -DestinationPath '{temp_dir}'
$action = New-ScheduledTaskAction -Execute '{temp_dir}\\{exe_name}' -Argument '{cmd_args}'
$trigger = New-ScheduledTaskTrigger -Once -At 00:00
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries
$task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings
Register-ScheduledTask godot_remote_debug -InputObject $task -Force:$true
Start-ScheduledTask -TaskName godot_remote_debug
while (Get-ScheduledTask -TaskName godot_remote_debug | ? State -eq running) { Start-Sleep -Milliseconds 100 }
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue"
ssh_remote_deploy/cleanup_script="Stop-ScheduledTask -TaskName godot_remote_debug -ErrorAction:SilentlyContinue
Unregister-ScheduledTask -TaskName godot_remote_debug -Confirm:$false -ErrorAction:SilentlyContinue
Remove-Item -Recurse -Force '{temp_dir}'"
dotnet/include_scripts_content=false
dotnet/include_debug_symbols=true
dotnet/embed_build_outputs=false

1
icon.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128"><rect width="124" height="124" x="2" y="2" fill="#363d52" stroke="#212532" stroke-width="4" rx="14"/><g fill="#fff" transform="translate(12.322 12.322)scale(.101)"><path d="M105 673v33q407 354 814 0v-33z"/><path fill="#478cbf" d="m105 673 152 14q12 1 15 14l4 67 132 10 8-61q2-11 15-15h162q13 4 15 15l8 61 132-10 4-67q3-13 15-14l152-14V427q30-39 56-81-35-59-83-108-43 20-82 47-40-37-88-64 7-51 8-102-59-28-123-42-26 43-46 89-49-7-98 0-20-46-46-89-64 14-123 42 1 51 8 102-48 27-88 64-39-27-82-47-48 49-83 108 26 42 56 81zm0 33v39c0 276 813 276 814 0v-39l-134 12-5 69q-2 10-14 13l-162 11q-12 0-16-11l-10-65H446l-10 65q-4 11-16 11l-162-11q-12-3-14-13l-5-69z"/><path d="M483 600c0 34 58 34 58 0v-86c0-34-58-34-58 0z"/><circle cx="725" cy="526" r="90"/><circle cx="299" cy="526" r="90"/></g><g fill="#414042" transform="translate(12.322 12.322)scale(.101)"><circle cx="307" cy="532" r="60"/><circle cx="717" cy="532" r="60"/></g></svg>

After

Width:  |  Height:  |  Size: 994 B

37
icon.svg.import Normal file
View File

@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://u3du2w54mu65"
path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://icon.svg"
dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
svg/scale=1.0
editor/scale_with_editor_scale=false
editor/convert_colors_with_editor_theme=false

94
project.godot Normal file
View File

@ -0,0 +1,94 @@
; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=5
[application]
config/name="苍穹沙盘"
run/main_scene="uid://8u0ex56qvckx"
config/features=PackedStringArray("4.4", "C#", "Forward Plus")
config/icon="res://icon.svg"
[autoload]
InitResource="*res://Script/Loader/InitResource.cs"
[display]
window/size/viewport_width=1280
window/size/viewport_height=720
window/stretch/mode="viewport"
[dotnet]
project/assembly_name="肉鸽"
[input]
ui_left={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null)
]
}
ui_right={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null)
]
}
ui_up={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null)
]
}
ui_down={
"deadzone": 0.5,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null)
, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null)
, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null)
]
}
fire={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
next_weapon={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":5,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
prev_weapon={
"deadzone": 0.2,
"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":4,"canceled":false,"pressed":false,"double_click":false,"script":null)
]
}
bag={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":66,"location":0,"echo":false,"script":null)
]
}
dev_ui={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194332,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
]
}
[rendering]
textures/canvas_textures/default_texture_filter=0

BIN
图片/Item/None.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://w54e0f3ya7js"
path="res://.godot/imported/None.png-1673d38dec04531aa4df4447579f8800.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Item/None.png"
dest_files=["res://.godot/imported/None.png-1673d38dec04531aa4df4447579f8800.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Item/gress.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 187 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://c6sgy6n73g1c7"
path="res://.godot/imported/gress.png-787f6c4d560db2c86436a579e70229ec.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Item/gress.png"
dest_files=["res://.godot/imported/gress.png-787f6c4d560db2c86436a579e70229ec.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://x6gjynrbk15s"
path="res://.godot/imported/GrassDirtDirtWater.png-dd99f0dc59981c6357749a73e0aa305b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/GrassDirtDirtWater.png"
dest_files=["res://.godot/imported/GrassDirtDirtWater.png-dd99f0dc59981c6357749a73e0aa305b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://s3fgr2wdr3ch"
path="res://.godot/imported/GrassDirtWaterWater.png-91e5c5460637dd29051723dede8d2956.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/GrassDirtWaterWater.png"
dest_files=["res://.godot/imported/GrassDirtWaterWater.png-91e5c5460637dd29051723dede8d2956.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://be4nredmg77id"
path="res://.godot/imported/GrassGrassDirtWater.png-7b17c61552a9e93ef33ddec03a115684.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/GrassGrassDirtWater.png"
dest_files=["res://.godot/imported/GrassGrassDirtWater.png-7b17c61552a9e93ef33ddec03a115684.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Map/GrassSoild.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1001 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bwkcydgr21obu"
path="res://.godot/imported/GrassSoild.png-d32d8df03f038815e08a49cb73bc79c3.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/GrassSoild.png"
dest_files=["res://.godot/imported/GrassSoild.png-d32d8df03f038815e08a49cb73bc79c3.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Map/GrassWater.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b07lrfhxsp5ix"
path="res://.godot/imported/GrassWater.png-10e785415d88d5ca2811d03f0677395f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/GrassWater.png"
dest_files=["res://.godot/imported/GrassWater.png-10e785415d88d5ca2811d03f0677395f.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Map/SoildWater.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dwnoufv3ysra5"
path="res://.godot/imported/SoildWater.png-64b003ede6dedea499537982faafa3cf.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/SoildWater.png"
dest_files=["res://.godot/imported/SoildWater.png-64b003ede6dedea499537982faafa3cf.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Map/mapType.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cd2e0hmqkwg43"
path="res://.godot/imported/mapType.png-6bb0d869802fe7ac656c5459efe416f1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Map/mapType.png"
dest_files=["res://.godot/imported/mapType.png-6bb0d869802fe7ac656c5459efe416f1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Object/bullet.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cqo4d16yxek4d"
path="res://.godot/imported/bullet.png-c6b7a42f90e838752364880488a15f62.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Object/bullet.png"
dest_files=["res://.godot/imported/bullet.png-c6b7a42f90e838752364880488a15f62.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

BIN
图片/Plyear/body/east.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://3jyj45tr880k"
path="res://.godot/imported/east.png-85556d23645cf691403da7a0f0ff414d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/body/east.png"
dest_files=["res://.godot/imported/east.png-85556d23645cf691403da7a0f0ff414d.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bjxgk4i2p5adw"
path="res://.godot/imported/north.png-9646ab1ad958f3526ed645aaf2fc948e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/body/north.png"
dest_files=["res://.godot/imported/north.png-9646ab1ad958f3526ed645aaf2fc948e.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bfb4jkr001yc3"
path="res://.godot/imported/south.png-a9b4095a928209aa6a4eef1cda7db05b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/body/south.png"
dest_files=["res://.godot/imported/south.png-a9b4095a928209aa6a4eef1cda7db05b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bwm7l6l5fjpm6"
path="res://.godot/imported/east.png-2611e6f195f82b0696e58df57a36574b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/clothing/east.png"
dest_files=["res://.godot/imported/east.png-2611e6f195f82b0696e58df57a36574b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://becluhw880l15"
path="res://.godot/imported/north.png-52dcfeca6042b2ee7688caba862094d7.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/clothing/north.png"
dest_files=["res://.godot/imported/north.png-52dcfeca6042b2ee7688caba862094d7.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://ddwe3fgpw6lws"
path="res://.godot/imported/south.png-9d4047e01ed71487c11eb4727a696aa1.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/clothing/south.png"
dest_files=["res://.godot/imported/south.png-9d4047e01ed71487c11eb4727a696aa1.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://btb5kfva4cil0"
path="res://.godot/imported/KiiroHair5_east.png-20bf8d448513adc6eb9347cd9bceed15.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/hair/KiiroHair5_east.png"
dest_files=["res://.godot/imported/KiiroHair5_east.png-20bf8d448513adc6eb9347cd9bceed15.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://6klx0iccsaqf"
path="res://.godot/imported/KiiroHair5_north.png-f6dd2b23d088b05b68ce0882b21dae1b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://图片/Plyear/hair/KiiroHair5_north.png"
dest_files=["res://.godot/imported/KiiroHair5_north.png-f6dd2b23d088b05b68ce0882b21dae1b.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

Some files were not shown because too many files have changed in this diff Show More