将Excel导出工具内嵌到项目工程中
Before Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 104 KiB |
Before Width: | Height: | Size: 2.6 MiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 94 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 18 KiB |
|
@ -1,347 +0,0 @@
|
|||
|
||||
前言: 该文档仅针对`DungeonShooting_Godot`目录下的Godot工程
|
||||
|
||||
**注意:** 新版文档编写中...
|
||||
|
||||
目录:
|
||||
|
||||
---
|
||||
## 1.启动项目
|
||||
**Godot版本:** Godot4x
|
||||
**.net版本:** .net6.0
|
||||
使用Godot打开`project.godot`, 如果是第一次打开项目会弹出一个找不到资源的提示, 这是因为项目没有编译过, 点击Godot右上角`build`, 然后打`开项目设置`, 在`插件`这一个页签下启用`DungeonShooting_plugin`这个插件, 然后项目就可以正常运行了
|
||||
|
||||
---
|
||||
## 2.项目资源
|
||||
|
||||
### 2.1.目录结构
|
||||
所有资源严格划分类别, 并放入指定的文件夹
|
||||
**项目目录结构如下:**
|
||||
* ./addons: 项目插件目录
|
||||
* ./prefab: 预制体资源目录
|
||||
* ./resource 美术,音乐,配置文件等资源放置路径
|
||||
* ./scene 场景资源
|
||||
* ./src 代码资源
|
||||
|
||||
### 2.2.脚本获取资源
|
||||
为了方便代码获取资源以及排除代码中引用丢失资源的情况, 项目中使用`ResourcePath`类来放置所有资源路径, 该类常量值即代表资源路径, 使用`ResourceManager.Load()`来加载资源
|
||||
举个例子, 某资源在编辑器中的路径为:
|
||||
```text
|
||||
res://resource/theme/mainTheme.tres
|
||||
```
|
||||
那么在`ResourcePath`中的代码就为:
|
||||
```csharp
|
||||
public const string resource_theme_mainTheme_tres = "res://resource/theme/mainTheme.tres";
|
||||
```
|
||||
加载该资源的代码为:
|
||||
```csharp
|
||||
var resource = ResourceManager.Load<Theme>(ResourcePath.resource_theme_mainTheme_tres);
|
||||
```
|
||||
|
||||
### 2.3.重新生成ResourcePath
|
||||
如果项目中有资源变动, 则可以使用`Tools`页签下的`重新生成ResourcePath.cs文件`
|
||||
![](文档资源/image_6.png)
|
||||
|
||||
---
|
||||
## 3.游戏框架
|
||||
### 3.1.简述
|
||||
游戏框架分为三部分:
|
||||
1. 游戏核心系统
|
||||
2. UI模块系统
|
||||
3. 代码生成系统
|
||||
|
||||
**游戏核心系统**: 以游戏玩法为中心的逻辑代码, 包括玩家, 敌人, 武器, 被动, 道具, 地牢生成, 房间规则, 存档逻辑等
|
||||
**UI模块系统**: 用户操作界面的逻辑代码
|
||||
**代码生成系统**: 自动生成便于开发的资源的逻辑代码
|
||||
**编辑器系统**: 用于用于自定义游戏内容
|
||||
|
||||
### 3.2.游戏核心系统
|
||||
|
||||
在`Main/ViewCanvas/SubViewportContainer/SubViewport`的子节点将开启4倍缩放, 并且启用完美像素
|
||||
该节点放置除UI以外的任何节点
|
||||
|
||||
#### 3.2.1.什么是ActivityObject
|
||||
定义: 游戏内所有可活动物体的基类叫做`ActivityObject`
|
||||
源代码: [ActivityObject.cs](../DungeonShooting_Godot/src/framework/activity/ActivityObject.cs)
|
||||
|
||||
`ActivityObject`的意由来: 为了方便统一管理物体, 并且减少子类代码沉积, 因此将所有活动物体都需要用到的逻辑抽到一个统一的类中, 并命名为`ActivityObject`, 所有的活动物体都需要继承该类
|
||||
|
||||
`ActivityObject`提供的基础功能:
|
||||
* `Component`组件管理
|
||||
* 协程功能
|
||||
* 外力控制运动
|
||||
* 纵轴运动模拟 (自由落体, 投抛物体等)
|
||||
* 数据标记
|
||||
* 对象归属区域
|
||||
* 互动逻辑接口
|
||||
|
||||
通过下面这张图可以了解游戏中的物体与`ActivityObject`的关系 (注意: 该图为早期开发版本的继承关系图, 后面开发可能会有修改)
|
||||
![](文档资源/2023-03-26_030144.png)
|
||||
|
||||
|
||||
#### 3.2.2.ActivityObject常用功能
|
||||
|
||||
##### 自定义组件
|
||||
这个功能类似于`Unity`的`MonoBehaviour`, 组件必须继承`Component`类, 组件的作用是拆分功能代码, 开发者可以将相同功能的代码放入同一个组件中, 与`Godot`的`Node`不同的是, 挂载到`ActivityObject`上的组件并不会生成一个`Node`节点, 它相比于`Node`更加轻量
|
||||
|
||||
自定义组件代码:
|
||||
```csharp
|
||||
public class MyComponent : Component
|
||||
{
|
||||
|
||||
}
|
||||
```
|
||||
调用`ActivityObject.AddComponent()`添加组件:
|
||||
```csharp
|
||||
var component = activityInstance.AddComponent<MyComponent>();
|
||||
```
|
||||
注意: 一个`ActivityObject`上不允许挂载多个相同的组件
|
||||
|
||||
##### 运动控制
|
||||
`ActivityObject`的移动由自身的`MoveController`组件控制, 非特殊情况下不要直接修改`ActivityObject`的位置, 而是使用`MoveController.AddConstantForce()`函数来添加外力
|
||||
```csharp
|
||||
//添加一个向右的外力, 速度为100
|
||||
var force = activityInstance.MoveController.AddConstantForce("ForceName"); //外力必须起名称, 而且在运动控制器中必须唯一
|
||||
force.Velocity = new Vector2(0, 100);
|
||||
//以下为精简写法
|
||||
var force = activityInstance.MoveController.AddConstantForce(new Vector2(0, 100), 0); //创建匿名外力, 但是与上面不同的是当速率变为 0 时自动销毁
|
||||
```
|
||||
物体的运动方向就是所有外力总和的方向, 通过`MoveController.Velocity`可以获取当前运动速度
|
||||
|
||||
##### 垂直方向运动
|
||||
当游戏中需要制作飞行物体或者模拟投抛运动时, 就需要控制物体纵轴所处高度, `ActivityObject`中提供了一系列控制纵轴方向运动的属性和函数, 以下列举几个关键属性和函数:
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 当前物体的海拔高度, 如果大于0, 则会做自由落体运动, 也就是执行投抛代码
|
||||
/// </summary>
|
||||
public float Altitude { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 物体纵轴移动速度, 如果设置大于0, 就可以营造向上投抛物体的效果, 该值会随着重力加速度衰减
|
||||
/// </summary>
|
||||
public float VerticalSpeed { get; set; } = 0;
|
||||
|
||||
/// <summary>
|
||||
/// 物体下坠回弹的强度
|
||||
/// </summary>
|
||||
public float BounceStrength { get; set; } = 0.5f;
|
||||
|
||||
/// <summary>
|
||||
/// 物体下坠回弹后的运动速度衰减量
|
||||
/// </summary>
|
||||
public float BounceSpeed { get; set; } = 0.75f;
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用垂直方向上的运动模拟, 默认开启, 如果禁用, 那么下落和投抛效果, 同样 Throw() 函数也将失效
|
||||
/// </summary>
|
||||
public bool EnableVerticalMotion { get; set; } = true;
|
||||
```
|
||||
垂直运动也提供了一些可供重写的虚函数:
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 开始投抛该物体时调用
|
||||
/// </summary>
|
||||
protected virtual void OnThrowStart()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 投抛该物体达到最高点时调用
|
||||
/// </summary>
|
||||
protected virtual void OnThrowMaxHeight(float height)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 投抛状态下第一次接触地面时调用, 之后的回弹落地将不会调用该函数
|
||||
/// </summary>
|
||||
protected virtual void OnFirstFallToGround()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 投抛状态下每次接触地面时调用
|
||||
/// </summary>
|
||||
protected virtual void OnFallToGround()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 投抛结束时调用
|
||||
/// </summary>
|
||||
protected virtual void OnThrowOver()
|
||||
{
|
||||
}
|
||||
```
|
||||
如果需要模拟飞行效果则需要设置`Altitude`值大于0, 并且将`EnableVerticalMotion`设置为`false`
|
||||
如果需要自由落体, 则直接设置`Altitude`值大于0
|
||||
如果需要上抛运动, 则直接设置`VerticalSpeed`值大于0
|
||||
如果值`BounceStrength`和`BounceSpeed`设置成1, 则投抛的物体在地上会一直朝一个方向弹跳
|
||||
如果需要投抛物体不需要每个关键值都设置一遍信息, 只需要调用`ActivityObject.Throw()`函数即可:
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 将该节点投抛出去
|
||||
/// </summary>
|
||||
/// <param name="altitude">初始高度</param>
|
||||
/// <param name="rotate">旋转速度</param>
|
||||
/// <param name="velocity">移动速率</param>
|
||||
/// <param name="verticalSpeed">纵轴速度</param>
|
||||
public void Throw(float altitude, float verticalSpeed, Vector2 velocity, float rotate);
|
||||
```
|
||||
调用示例, 模拟弹壳投抛落在地上弹跳的过程
|
||||
```csharp
|
||||
var startPos = GlobalPosition;
|
||||
var startHeight = 6;
|
||||
var direction = GlobalRotationDegrees + Utils.RandomRangeInt(-30, 30) + 180;
|
||||
var verticalSpeed = Utils.RandomRangeInt(60, 120);
|
||||
var velocity = new Vector2(Utils.RandomRangeInt(20, 60), 0).Rotated(direction * Mathf.Pi / 180);
|
||||
var rotate = Utils.RandomRangeInt(-720, 720);
|
||||
var shell = ActivityObject.Create<ShellCase>(ActivityIdPrefix.Shell + "0001");
|
||||
shell.Throw(startPos, startHeight, verticalSpeed, velocity, rotate);
|
||||
```
|
||||
|
||||
##### 协程
|
||||
该功能与`Unity`的协程功能类似, 在协程函数中通过`yield`关键字暂停执行后面的代码, 并将控制权返还给`ActivityObject`, 协程常被用在动画处理和资源异步加载
|
||||
`ActivityObject`中协程相关函数:
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 开启一个协程, 返回协程 id, 协程是在普通帧执行的, 支持: 协程嵌套, WaitForSeconds, WaitForFixedProcess
|
||||
/// </summary>
|
||||
public long StartCoroutine(IEnumerator able);
|
||||
|
||||
/// <summary>
|
||||
/// 根据协程 id 停止协程
|
||||
/// </summary>
|
||||
public void StopCoroutine(long coroutineId);
|
||||
|
||||
/// <summary>
|
||||
/// 停止所有协程
|
||||
/// </summary>
|
||||
public void StopAllCoroutine();
|
||||
```
|
||||
协程`yield return`返回特殊值类型如下:
|
||||
* **WaitForSeconds**: 当前协程等待秒数
|
||||
* **WaitForFixedProcess**: 当前协程等待帧数
|
||||
* **IEnumerator**: 嵌套执行子协程, 等子协程执行完毕后才会继续执行后面的代码
|
||||
|
||||
协程`yield return`如果返回除以上数据类型以外的数据, 将忽略返回值
|
||||
|
||||
调用实例, 以下代码在`ActivityInstance`初始化时执行协程`StartRotation`, 协程在60帧内让物体每帧角度加1
|
||||
```csharp
|
||||
public override void OnInit()
|
||||
{
|
||||
StartCoroutine(StartRotation());
|
||||
}
|
||||
|
||||
private IEnumerator StartRotation()
|
||||
{
|
||||
for (int i = 0; i < 60; i++)
|
||||
{
|
||||
RotationDegrees += 1;
|
||||
//结束这一帧, 返回0会被忽略返回值
|
||||
yield return 0;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3.地牢
|
||||
#### 3.3.1.地牢概述
|
||||
游戏中的地牢由若干层组成, 每一层地牢又由数个小房间随机拼接而成, 由起始房间开始, 成树状连接; 每一层地牢有一个起始房间, 和至少一个通向另一层的结束房间, 房间与房间之间由过道连接, 过道不会交叉和重叠
|
||||
|
||||
房间有以下类别 (目前代码还未完成区分类型的功能):
|
||||
* **起始房间**: 由上一层地牢的结束房间进入该房间, 每层包含一个起始房间
|
||||
* **结束房间**: 进入另一层地牢, 每层只是包含一个结束房间
|
||||
* **普通战斗房间**: 进入该房间时会关上门, 并刷出若干波敌人, 消灭所有敌人后开门
|
||||
* **boss战房间**: 进入房间时会关上没, 刷出boss, 消灭boss后开门
|
||||
* **奖励房间**: 给予玩家武器或者道具奖励的房间
|
||||
* **商店**: 玩家买卖道具装备的房间
|
||||
* **事件房间**: 触发剧情或者解锁NPC的房间
|
||||
|
||||
|
||||
|
||||
### 3.4.UI系统
|
||||
#### 3.4.1.UI系统概述
|
||||
游戏内的物体, 例如`ActivityObject`等都是在`Main/ViewCanvas/SubViewportContainer/SubViewport`节点下, 并且启用了完美像素, 但是UI恰恰相反,它们直接位于`Main`节点下, 既没有4倍缩放也没有完美像素
|
||||
游戏中的UI分为4个层级, 分别为
|
||||
* Bottom: 最底层, 层级为5
|
||||
* Middle: 中间层, 层级为15
|
||||
* Height: 较高层, 层级为25
|
||||
* Pop: 最顶层, 层级为35
|
||||
|
||||
UI场景根节点必须继承`UiBase`类, 并且生命周期由`UiManager`控制
|
||||
UI代码放置位置: `src/game/ui/**/**.cs`
|
||||
UI场景资源放置位置: `prefab/ui/**.tscn`
|
||||
源代码: [UiBase.cs](../DungeonShooting_Godot/src/framework/ui/UiBase.cs), [UiManager.cs](../DungeonShooting_Godot/src/framework/ui/UiManager.cs)
|
||||
打开指定UI:
|
||||
```csharp
|
||||
var ui = UiManager.OpenUi("UI名称");
|
||||
```
|
||||
关闭Ui
|
||||
```csharp
|
||||
UiManager.DisposeUi(ui);
|
||||
```
|
||||
|
||||
#### 3.4.2.UI代码生器
|
||||
为了减低开发者制作UI的复杂程度, 避免手写获取UI节点的代码, 我们设计了一套自动生成UI层级代码的功能, 该功能在编辑器中会监听开发者对于UI场景的修改, 并及时生成相应的UI代码, 并且开发者的UI逻辑类继承生成的UI类, 即可方便的获取UI节点, 可以节省大量时间, 因为代码是实时生成的, 因此一旦有节点改名或者移动位置, 重新生成UI代码后, 引用该节点的代码就会出现编译错误, 方便开发者修改
|
||||
|
||||
##### 创建UI
|
||||
在`Tools`页签下找到`创建游戏UI`, 输入UI名称即可点击创建UI
|
||||
![](文档资源/image_14.png)
|
||||
创建完毕后编辑器会离开打开该UI场景
|
||||
观察文件系统可以注意到, 编辑器为我创建并保存了场景和代码, 并且还生成了一个`MyUiPanel.cs`的文件, 该文件就是我们写UI逻辑代码的地方, 并且命名方式为`UI名称`+`Panel`, 这个Panel类继承了自动生成出来的UI类
|
||||
![](文档资源/image_15.png)
|
||||
![](文档资源/image_16.png)
|
||||
|
||||
动态生成的UI代码的节点对象由`IUiNode`包裹, 为了子节点与内助属性区分方便, 生成出来的代码会为每一层的名称加上前缀`L_`, 同理如果需要获取子节点则直接寻找以`L_`开始的属性
|
||||
例如节点在编辑器的路径为`Group/Button`, 那么在代码里就是`L_Group.L_Button`
|
||||
源代码: [IUiNode.cs](../DungeonShooting_Godot/src/framework/ui/IUiNode.cs)
|
||||
|
||||
通过以下这个gif就可以直观感受到该功能的便捷之处
|
||||
![](文档资源/gif_4.gif)
|
||||
|
||||
##### 打开UI
|
||||
创建完成UI后, 编辑器也会在`UiManager`中生成打开该UI和获取UI实例的Api
|
||||
![](文档资源/image_17.png)
|
||||
那么可以直接调用`UiManager`中的函数打开该UI
|
||||
```csharp
|
||||
UiManager.Open_MyUi();
|
||||
```
|
||||
|
||||
#### 3.4.3.常用功能
|
||||
|
||||
##### 生命周期
|
||||
`UiBase`包含4个生命周期函数:
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// 创建当前ui时调用
|
||||
/// </summary>
|
||||
public virtual void OnCreateUi()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前ui显示时调用
|
||||
/// </summary>
|
||||
public virtual void OnShowUi()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前ui隐藏时调用
|
||||
/// </summary>
|
||||
public virtual void OnHideUi()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 销毁当前ui时调用
|
||||
/// </summary>
|
||||
public virtual void OnDestroy()
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
#### 包裹UI节点的IUiNode
|
||||
获取`Node`实例: 使用例如`L_Group.L_Button`的代码获取的节点并不是`Godot`节点对象, 而是包裹对象, 需要从`Instance`属性中获取原生`Node`对象
|
||||
克隆节点: 使用`IUiNode.Clone()`可以完整的克隆当前节点以及子节点
|
||||
嵌套UI: 使用`IUiNode.OpenNestedUi()`即可以当前节点为根节点打开子级UI
|
|
@ -1,23 +0,0 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NPOI" Version="2.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="excelFile/**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="excelFile\Test.xlsx">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,16 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DungeonShooting_ExcelTool", "DungeonShooting_ExcelTool.csproj", "{F6A26370-A918-40F0-8D78-414213011172}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{F6A26370-A918-40F0-8D78-414213011172}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F6A26370-A918-40F0-8D78-414213011172}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F6A26370-A918-40F0-8D78-414213011172}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F6A26370-A918-40F0-8D78-414213011172}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -1,2 +0,0 @@
|
|||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/PencilsConfiguration/ActualSeverity/@EntryValue">WARNING</s:String></wpf:ResourceDictionary>
|
|
@ -1,26 +0,0 @@
|
|||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("准备导出excel表...");
|
||||
bool success;
|
||||
if (args.Length >= 3)
|
||||
{
|
||||
success = ExcelGenerator.ExportExcel(args[0], args[1], args[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = ExcelGenerator.ExportExcel();
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
Console.WriteLine("excel表导出成功!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("excel表导出失败!");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
|
||||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// 可序列化的 Color 对象
|
||||
/// </summary>
|
||||
public class SerializeColor
|
||||
{
|
||||
public SerializeColor(float r, float g, float b, float a)
|
||||
{
|
||||
R = r;
|
||||
G = g;
|
||||
B = b;
|
||||
A = a;
|
||||
}
|
||||
|
||||
public SerializeColor()
|
||||
{
|
||||
}
|
||||
|
||||
[JsonInclude]
|
||||
public float R { get; private set; }
|
||||
[JsonInclude]
|
||||
public float G { get; private set; }
|
||||
[JsonInclude]
|
||||
public float B { get; private set; }
|
||||
[JsonInclude]
|
||||
public float A { get; private set; }
|
||||
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// 可序列化的 Vector2 对象
|
||||
/// </summary>
|
||||
public class SerializeVector2
|
||||
{
|
||||
public SerializeVector2(float x, float y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public SerializeVector2(SerializeVector2 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
}
|
||||
|
||||
public SerializeVector2()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[JsonInclude]
|
||||
public float X { get; private set; }
|
||||
[JsonInclude]
|
||||
public float Y { get; private set; }
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
using System.Text.Json.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// 可序列化的 Vector3 对象
|
||||
/// </summary>
|
||||
public class SerializeVector3
|
||||
{
|
||||
public SerializeVector3(float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
public SerializeVector3(SerializeVector3 v)
|
||||
{
|
||||
X = v.X;
|
||||
Y = v.Y;
|
||||
}
|
||||
|
||||
public SerializeVector3()
|
||||
{
|
||||
}
|
||||
|
||||
[JsonInclude]
|
||||
public float X { get; private set; }
|
||||
[JsonInclude]
|
||||
public float Y { get; private set; }
|
||||
[JsonInclude]
|
||||
public float Z { get; private set; }
|
||||
|
||||
}
|
|
@ -1,16 +1,22 @@
|
|||
using System.Text.Json;
|
||||
#if TOOLS
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
using Config;
|
||||
using Godot;
|
||||
using NPOI.SS.UserModel;
|
||||
using NPOI.XSSF.UserModel;
|
||||
using Array = Godot.Collections.Array;
|
||||
using Environment = System.Environment;
|
||||
|
||||
namespace Generator;
|
||||
|
||||
public static class ExcelGenerator
|
||||
{
|
||||
private const string CodeOutPath = "src/config/";
|
||||
private const string JsonOutPath = "resource/config/";
|
||||
private const string ExcelFilePath = "excelFile";
|
||||
|
||||
private static HashSet<string> _excelNames = new HashSet<string>();
|
||||
|
||||
|
||||
private enum CollectionsType
|
||||
{
|
||||
|
@ -21,7 +27,6 @@ public static class ExcelGenerator
|
|||
|
||||
private class MappingData
|
||||
{
|
||||
|
||||
public string TypeStr;
|
||||
public string TypeName;
|
||||
public CollectionsType CollectionsType;
|
||||
|
@ -58,18 +63,31 @@ public static class ExcelGenerator
|
|||
public Dictionary<string, Type> ColumnType = new Dictionary<string, Type>();
|
||||
public List<Dictionary<string, object>> DataList = new List<Dictionary<string, object>>();
|
||||
}
|
||||
|
||||
public static bool ExportExcel()
|
||||
|
||||
/// <summary>
|
||||
/// 导出 Excel 表
|
||||
/// </summary>
|
||||
public static void ExportExcel()
|
||||
{
|
||||
return ExportExcel(ExcelFilePath, JsonOutPath, CodeOutPath);
|
||||
var excelPath = "excel/";
|
||||
var jsonPath = "resource/config/";
|
||||
var codePath = "src/config/";
|
||||
ExportExcel(excelPath, jsonPath, codePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 导出 Excel 表
|
||||
/// </summary>
|
||||
/// <param name="excelFilePath">excel文件路径</param>
|
||||
/// <param name="jsonOutPath">json配置输出路径</param>
|
||||
/// <param name="codeOutPath">代码输出路径</param>
|
||||
public static bool ExportExcel(string excelFilePath, string jsonOutPath, string codeOutPath)
|
||||
{
|
||||
Console.WriteLine("当前路径: " + Environment.CurrentDirectory);
|
||||
Console.WriteLine("excel路径: " + excelFilePath);
|
||||
Console.WriteLine("json输出路径: " + jsonOutPath);
|
||||
Console.WriteLine("cs代码输出路径: " + codeOutPath);
|
||||
_excelNames.Clear();
|
||||
Debug.Log("当前路径: " + Environment.CurrentDirectory);
|
||||
Debug.Log("excel路径: " + excelFilePath);
|
||||
Debug.Log("json输出路径: " + jsonOutPath);
|
||||
Debug.Log("cs代码输出路径: " + codeOutPath);
|
||||
try
|
||||
{
|
||||
var excelDataList = new List<ExcelData>();
|
||||
|
@ -93,13 +111,13 @@ public static class ExcelGenerator
|
|||
{
|
||||
throw new Exception("excel表文件名称不允许叫'ExcelConfig.xlsx'!");
|
||||
}
|
||||
Console.WriteLine("excel表: " + fileInfo.FullName);
|
||||
Debug.Log("excel表: " + fileInfo.FullName);
|
||||
excelDataList.Add(ReadExcel(fileInfo.FullName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine($"一共检测到excel表共{excelDataList.Count}张.");
|
||||
Debug.Log($"一共检测到excel表共{excelDataList.Count}张.");
|
||||
if (excelDataList.Count == 0)
|
||||
{
|
||||
return true;
|
||||
|
@ -119,6 +137,11 @@ public static class ExcelGenerator
|
|||
//保存配置和代码
|
||||
foreach (var excelData in excelDataList)
|
||||
{
|
||||
if (excelData.TableName == "ActivityBase")
|
||||
{
|
||||
//生成初始化 ActivityObject 代码
|
||||
GeneratorActivityObjectInit(excelData);
|
||||
}
|
||||
File.WriteAllText(codeOutPath + "ExcelConfig_" + excelData.TableName + ".cs", excelData.OutCode);
|
||||
var config = new JsonSerializerOptions();
|
||||
config.WriteIndented = true;
|
||||
|
@ -725,24 +748,42 @@ public static class ExcelGenerator
|
|||
|
||||
private static void PrintError(string message)
|
||||
{
|
||||
Console.ForegroundColor = ConsoleColor.Red;
|
||||
Console.WriteLine(message);
|
||||
Console.ResetColor();
|
||||
Debug.LogError(message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串首字母小写
|
||||
/// </summary>
|
||||
public static string FirstToLower(this string str)
|
||||
//生成 ActivityObject.Ids 代码
|
||||
private static void GeneratorActivityObjectInit(ExcelData activityExcelData)
|
||||
{
|
||||
return str.Substring(0, 1).ToLower() + str.Substring(1);
|
||||
var code1 = "";
|
||||
foreach (var item in activityExcelData.DataList)
|
||||
{
|
||||
var id = item["Id"];
|
||||
var name = item["Name"] + "";
|
||||
var intro = item["Intro"] + "";
|
||||
code1 += $" /// <summary>\n";
|
||||
code1 += $" /// 名称: {name} <br/>\n";
|
||||
code1 += $" /// 简介: {intro.Replace("\n", " <br/>\n /// ")}\n";
|
||||
code1 += $" /// </summary>\n";
|
||||
code1 += $" public const string Id_{id} = \"{id}\";\n";
|
||||
}
|
||||
|
||||
var str = $"using Config;\n\n";
|
||||
str += $"// 根据配置表注册物体, 该类是自动生成的, 请不要手动编辑!\n";
|
||||
str += $"public partial class ActivityObject\n";
|
||||
str += $"{{\n";
|
||||
|
||||
str += $" /// <summary>\n";
|
||||
str += $" /// 存放所有在表中注册的物体的id\n";
|
||||
str += $" /// </summary>\n";
|
||||
str += $" public static class Ids\n";
|
||||
str += $" {{\n";
|
||||
str += code1;
|
||||
str += $" }}\n";
|
||||
|
||||
str += $"}}\n";
|
||||
|
||||
File.WriteAllText("src/framework/activity/ActivityObject_Init.cs", str);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字符串首字母大写
|
||||
/// </summary>
|
||||
public static string FirstToUpper(this string str)
|
||||
{
|
||||
return str.Substring(0, 1).ToUpper() + str.Substring(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,7 +4,6 @@ using System;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Godot;
|
||||
|
||||
namespace Generator;
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Godot;
|
||||
|
||||
namespace Generator;
|
||||
|
|
@ -1,352 +0,0 @@
|
|||
{
|
||||
"runtimeTarget": {
|
||||
"name": ".NETCoreApp,Version=v7.0/win-x64",
|
||||
"signature": ""
|
||||
},
|
||||
"compilationOptions": {},
|
||||
"targets": {
|
||||
".NETCoreApp,Version=v7.0": {},
|
||||
".NETCoreApp,Version=v7.0/win-x64": {
|
||||
"DungeonShooting_ExcelTool/1.0.0": {
|
||||
"dependencies": {
|
||||
"NPOI": "2.6.0"
|
||||
},
|
||||
"runtime": {
|
||||
"DungeonShooting_ExcelTool.dll": {}
|
||||
}
|
||||
},
|
||||
"Enums.NET/4.0.0": {
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.0/Enums.NET.dll": {
|
||||
"assemblyVersion": "4.0.0.0",
|
||||
"fileVersion": "4.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"MathNet.Numerics.Signed/4.15.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/MathNet.Numerics.dll": {
|
||||
"assemblyVersion": "4.15.0.0",
|
||||
"fileVersion": "4.15.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.IO.RecyclableMemoryStream/2.2.0": {
|
||||
"runtime": {
|
||||
"lib/net5.0/Microsoft.IO.RecyclableMemoryStream.dll": {
|
||||
"assemblyVersion": "2.2.0.0",
|
||||
"fileVersion": "2.2.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents/6.0.0": {
|
||||
"runtime": {
|
||||
"runtimes/win/lib/net6.0/Microsoft.Win32.SystemEvents.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.21.52210"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NPOI/2.6.0": {
|
||||
"dependencies": {
|
||||
"Enums.NET": "4.0.0",
|
||||
"MathNet.Numerics.Signed": "4.15.0",
|
||||
"Microsoft.IO.RecyclableMemoryStream": "2.2.0",
|
||||
"Portable.BouncyCastle": "1.9.0",
|
||||
"SharpZipLib": "1.3.3",
|
||||
"SixLabors.Fonts": "1.0.0-beta18",
|
||||
"SixLabors.ImageSharp": "2.1.3",
|
||||
"System.Configuration.ConfigurationManager": "6.0.0",
|
||||
"System.Security.Cryptography.Xml": "6.0.1",
|
||||
"System.Text.Encoding.CodePages": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/NPOI.OOXML.dll": {
|
||||
"assemblyVersion": "2.6.0.0",
|
||||
"fileVersion": "2.6.0.0"
|
||||
},
|
||||
"lib/net6.0/NPOI.OpenXml4Net.dll": {
|
||||
"assemblyVersion": "2.6.0.0",
|
||||
"fileVersion": "2.6.0.0"
|
||||
},
|
||||
"lib/net6.0/NPOI.OpenXmlFormats.dll": {
|
||||
"assemblyVersion": "2.6.0.0",
|
||||
"fileVersion": "2.6.0.0"
|
||||
},
|
||||
"lib/net6.0/NPOI.dll": {
|
||||
"assemblyVersion": "2.6.0.0",
|
||||
"fileVersion": "2.6.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Portable.BouncyCastle/1.9.0": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.0/BouncyCastle.Crypto.dll": {
|
||||
"assemblyVersion": "1.9.0.0",
|
||||
"fileVersion": "1.9.0.1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SharpZipLib/1.3.3": {
|
||||
"runtime": {
|
||||
"lib/netstandard2.1/ICSharpCode.SharpZipLib.dll": {
|
||||
"assemblyVersion": "1.3.3.11",
|
||||
"fileVersion": "1.3.3.11"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SixLabors.Fonts/1.0.0-beta18": {
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.1/SixLabors.Fonts.dll": {
|
||||
"assemblyVersion": "1.0.0.0",
|
||||
"fileVersion": "1.0.0.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SixLabors.ImageSharp/2.1.3": {
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0",
|
||||
"System.Text.Encoding.CodePages": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/netcoreapp3.1/SixLabors.ImageSharp.dll": {
|
||||
"assemblyVersion": "2.0.0.0",
|
||||
"fileVersion": "2.1.3.0"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/6.0.0": {
|
||||
"dependencies": {
|
||||
"System.Security.Cryptography.ProtectedData": "6.0.0",
|
||||
"System.Security.Permissions": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/System.Configuration.ConfigurationManager.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.21.52210"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Drawing.Common/6.0.0": {
|
||||
"dependencies": {
|
||||
"Microsoft.Win32.SystemEvents": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"runtimes/win/lib/net6.0/System.Drawing.Common.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.21.52210"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Formats.Asn1/6.0.0": {},
|
||||
"System.Runtime.CompilerServices.Unsafe/6.0.0": {},
|
||||
"System.Security.AccessControl/6.0.0": {},
|
||||
"System.Security.Cryptography.Pkcs/6.0.1": {
|
||||
"dependencies": {
|
||||
"System.Formats.Asn1": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"runtimes/win/lib/net6.0/System.Security.Cryptography.Pkcs.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.522.21309"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/6.0.0": {
|
||||
"runtime": {
|
||||
"runtimes/win/lib/net6.0/System.Security.Cryptography.ProtectedData.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.21.52210"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Cryptography.Xml/6.0.1": {
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "6.0.0",
|
||||
"System.Security.Cryptography.Pkcs": "6.0.1"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/System.Security.Cryptography.Xml.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.822.36306"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Security.Permissions/6.0.0": {
|
||||
"dependencies": {
|
||||
"System.Security.AccessControl": "6.0.0",
|
||||
"System.Windows.Extensions": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"lib/net6.0/System.Security.Permissions.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.21.52210"
|
||||
}
|
||||
}
|
||||
},
|
||||
"System.Text.Encoding.CodePages/6.0.0": {
|
||||
"dependencies": {
|
||||
"System.Runtime.CompilerServices.Unsafe": "6.0.0"
|
||||
}
|
||||
},
|
||||
"System.Windows.Extensions/6.0.0": {
|
||||
"dependencies": {
|
||||
"System.Drawing.Common": "6.0.0"
|
||||
},
|
||||
"runtime": {
|
||||
"runtimes/win/lib/net6.0/System.Windows.Extensions.dll": {
|
||||
"assemblyVersion": "6.0.0.0",
|
||||
"fileVersion": "6.0.21.52210"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"DungeonShooting_ExcelTool/1.0.0": {
|
||||
"type": "project",
|
||||
"serviceable": false,
|
||||
"sha512": ""
|
||||
},
|
||||
"Enums.NET/4.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-d47SgeuGxKpalKhYoHqFkDPmO9SoE3amSwVNDoUdy4d675/tX7bLyZFHdjfo3Tobth9Y80VnjfasQ/PD4LqUuA==",
|
||||
"path": "enums.net/4.0.0",
|
||||
"hashPath": "enums.net.4.0.0.nupkg.sha512"
|
||||
},
|
||||
"MathNet.Numerics.Signed/4.15.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-LFjukMRatkg9dgRM7U/gM4uKgaWAX7E0lt3fsVDTPdtBIVuh7uPlksDie290br1/tv1a4Ar/Bz9ywCPSL8PhHg==",
|
||||
"path": "mathnet.numerics.signed/4.15.0",
|
||||
"hashPath": "mathnet.numerics.signed.4.15.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.IO.RecyclableMemoryStream/2.2.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-uyjY/cqomw1irT4L7lDeg4sJ36MsjHg3wKqpGrBAdzvZaxo85yMF+sAA9RIzTV92fDxuUzjqksMqA0+SNMkMgA==",
|
||||
"path": "microsoft.io.recyclablememorystream/2.2.0",
|
||||
"hashPath": "microsoft.io.recyclablememorystream.2.2.0.nupkg.sha512"
|
||||
},
|
||||
"Microsoft.Win32.SystemEvents/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A==",
|
||||
"path": "microsoft.win32.systemevents/6.0.0",
|
||||
"hashPath": "microsoft.win32.systemevents.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"NPOI/2.6.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-Pwjo65CUH3MiRnBEbVo8ff31ZrDGdGyyFJyAEncmbTQ0/gYgDkBUnGKm20aLpdwCpPNLzvapZm8v5tx4S6qAWg==",
|
||||
"path": "npoi/2.6.0",
|
||||
"hashPath": "npoi.2.6.0.nupkg.sha512"
|
||||
},
|
||||
"Portable.BouncyCastle/1.9.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-eZZBCABzVOek+id9Xy04HhmgykF0wZg9wpByzrWN7q8qEI0Qen9b7tfd7w8VA3dOeesumMG7C5ZPy0jk7PSRHw==",
|
||||
"path": "portable.bouncycastle/1.9.0",
|
||||
"hashPath": "portable.bouncycastle.1.9.0.nupkg.sha512"
|
||||
},
|
||||
"SharpZipLib/1.3.3": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-N8+hwhsKZm25tDJfWpBSW7EGhH/R7EMuiX+KJ4C4u+fCWVc1lJ5zg1u3S1RPPVYgTqhx/C3hxrqUpi6RwK5+Tg==",
|
||||
"path": "sharpziplib/1.3.3",
|
||||
"hashPath": "sharpziplib.1.3.3.nupkg.sha512"
|
||||
},
|
||||
"SixLabors.Fonts/1.0.0-beta18": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-evykNmy/kEE9EAEKgZm3MNUYXuMHFfmcLUNPw7Ho5q7OI96GFkkIxBm+QaKOTPBKw+L0AjKOs+ArVg8P40Ac9g==",
|
||||
"path": "sixlabors.fonts/1.0.0-beta18",
|
||||
"hashPath": "sixlabors.fonts.1.0.0-beta18.nupkg.sha512"
|
||||
},
|
||||
"SixLabors.ImageSharp/2.1.3": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-8yonNRWX3vUE9k29ta0Hbfa0AEc0hbDjSH/nZ3vOTJEXmY6hLnGsjDKoz96Z+AgOsrdkAu6PdL/Ebaf70aitzw==",
|
||||
"path": "sixlabors.imagesharp/2.1.3",
|
||||
"hashPath": "sixlabors.imagesharp.2.1.3.nupkg.sha512"
|
||||
},
|
||||
"System.Configuration.ConfigurationManager/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-7T+m0kDSlIPTHIkPMIu6m6tV6qsMqJpvQWW2jIc2qi7sn40qxFo0q+7mEQAhMPXZHMKnWrnv47ntGlM/ejvw3g==",
|
||||
"path": "system.configuration.configurationmanager/6.0.0",
|
||||
"hashPath": "system.configuration.configurationmanager.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Drawing.Common/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==",
|
||||
"path": "system.drawing.common/6.0.0",
|
||||
"hashPath": "system.drawing.common.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Formats.Asn1/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-T6fD00dQ3NTbPDy31m4eQUwKW84s03z0N2C8HpOklyeaDgaJPa/TexP4/SkORMSOwc7WhKifnA6Ya33AkzmafA==",
|
||||
"path": "system.formats.asn1/6.0.0",
|
||||
"hashPath": "system.formats.asn1.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Runtime.CompilerServices.Unsafe/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==",
|
||||
"path": "system.runtime.compilerservices.unsafe/6.0.0",
|
||||
"hashPath": "system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.AccessControl/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==",
|
||||
"path": "system.security.accesscontrol/6.0.0",
|
||||
"hashPath": "system.security.accesscontrol.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.Pkcs/6.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ynmbW2GjIGg9K1wXmVIRs4IlyDolf0JXNpzFQ8JCVgwM+myUC2JeUggl2PwQig2PNVMegKmN1aAx7WPQ8tI3vA==",
|
||||
"path": "system.security.cryptography.pkcs/6.0.1",
|
||||
"hashPath": "system.security.cryptography.pkcs.6.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.ProtectedData/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==",
|
||||
"path": "system.security.cryptography.protecteddata/6.0.0",
|
||||
"hashPath": "system.security.cryptography.protecteddata.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Cryptography.Xml/6.0.1": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-5e5bI28T0x73AwTsbuFP4qSRzthmU2C0Gqgg3AZ3KTxmSyA+Uhk31puA3srdaeWaacVnHhLdJywCzqOiEpbO/w==",
|
||||
"path": "system.security.cryptography.xml/6.0.1",
|
||||
"hashPath": "system.security.cryptography.xml.6.0.1.nupkg.sha512"
|
||||
},
|
||||
"System.Security.Permissions/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==",
|
||||
"path": "system.security.permissions/6.0.0",
|
||||
"hashPath": "system.security.permissions.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Text.Encoding.CodePages/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==",
|
||||
"path": "system.text.encoding.codepages/6.0.0",
|
||||
"hashPath": "system.text.encoding.codepages.6.0.0.nupkg.sha512"
|
||||
},
|
||||
"System.Windows.Extensions/6.0.0": {
|
||||
"type": "package",
|
||||
"serviceable": true,
|
||||
"sha512": "sha512-IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==",
|
||||
"path": "system.windows.extensions/6.0.0",
|
||||
"hashPath": "system.windows.extensions.6.0.0.nupkg.sha512"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"runtimeOptions": {
|
||||
"tfm": "net7.0",
|
||||
"framework": {
|
||||
"name": "Microsoft.NETCore.App",
|
||||
"version": "7.0.0"
|
||||
},
|
||||
"configProperties": {
|
||||
"System.Reflection.Metadata.MetadataUpdater.IsSupported": false
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ dedicated_server=false
|
|||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter="build/*"
|
||||
exclude_filter="excel/*,build/*"
|
||||
export_path="build/android/build.apk"
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
|
@ -22,7 +22,7 @@ gradle_build/use_gradle_build=true
|
|||
gradle_build/export_format=0
|
||||
gradle_build/min_sdk=""
|
||||
gradle_build/target_sdk=""
|
||||
architectures/armeabi-v7a=true
|
||||
architectures/armeabi-v7a=false
|
||||
architectures/arm64-v8a=true
|
||||
architectures/x86=false
|
||||
architectures/x86_64=false
|
||||
|
@ -215,8 +215,8 @@ dedicated_server=false
|
|||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
include_filter=""
|
||||
exclude_filter="resource/map/tileMaps/*"
|
||||
export_path="../../DungeonShooting_Export/windows/game.exe"
|
||||
exclude_filter="resource/map/tileMaps/*,excel/*,build/*"
|
||||
export_path="build/windows/game.exe"
|
||||
encryption_include_filters=""
|
||||
encryption_exclude_filters=""
|
||||
encrypt_pck=false
|
||||
|
|
|
@ -1 +1 @@
|
|||
[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":14,"Y":16},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":35,"Y":-27},"Size":{"X":30,"Y":12},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":8,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-50,"Y":7},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-63,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-31,"Y":-16},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-54,"Y":33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":-25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-76,"Y":21},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0008","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-87,"Y":46},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0009","Weight":100,"Attr":{"CurrAmmon":"1","ResidueAmmo":"25"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":-1},"Size":{"X":24,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":45,"Y":55},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0012","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":-26},"Size":{"X":13,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0013","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-91,"Y":-6},"Size":{"X":14,"Y":13},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-73,"Y":66},"Size":{"X":14,"Y":14},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":72,"Y":62},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":28},"Size":{"X":16,"Y":17},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":-12},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-24,"Y":8},"Size":{"X":18,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-20,"Y":34},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0},{"Id":"prop0006","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]},{"Name":"test2","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":0,"Y":0},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]}]]}]
|
||||
[{"Name":"test1","Weight":100,"Remark":"","WaveList":[[{"Position":{"X":0,"Y":0},"Size":{"X":14,"Y":16},"SpecialMarkType":1,"DelayTime":0,"MarkList":[]},{"Position":{"X":35,"Y":-27},"Size":{"X":30,"Y":12},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0001","Weight":100,"Attr":{"CurrAmmon":"30","ResidueAmmo":"210"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":8,"Y":32},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0002","Weight":100,"Attr":{"CurrAmmon":"7","ResidueAmmo":"70"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-50,"Y":7},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0004","Weight":100,"Attr":{"CurrAmmon":"180","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-63,"Y":-18},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0005","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"40"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-31,"Y":-16},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0003","Weight":100,"Attr":{"CurrAmmon":"12","ResidueAmmo":"90"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-54,"Y":33},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0006","Weight":100,"Attr":{"CurrAmmon":"20","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":2,"Y":-25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0007","Weight":100,"Attr":{"CurrAmmon":"60","ResidueAmmo":"300"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-76,"Y":21},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0008","Weight":100,"Attr":{"CurrAmmon":"10","ResidueAmmo":"120"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-87,"Y":46},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"weapon0009","Weight":100,"Attr":{"CurrAmmon":"1","ResidueAmmo":"25"},"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":34,"Y":-1},"Size":{"X":24,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0011","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":45,"Y":55},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0012","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-90,"Y":-26},"Size":{"X":13,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0013","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-91,"Y":-6},"Size":{"X":14,"Y":13},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0014","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-73,"Y":66},"Size":{"X":14,"Y":14},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}],[{"Position":{"X":72,"Y":62},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0003","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":28},"Size":{"X":16,"Y":17},"SpecialMarkType":0,"DelayTime":0.5,"MarkList":[{"Id":"prop5000","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":67,"Y":-12},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1,"MarkList":[{"Id":"prop5001","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":36,"Y":25},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":1.5,"MarkList":[{"Id":"prop0002","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-24,"Y":8},"Size":{"X":18,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]},{"Position":{"X":-20,"Y":34},"Size":{"X":16,"Y":16},"SpecialMarkType":0,"DelayTime":0,"MarkList":[{"Id":"prop0010","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0},{"Id":"prop0006","Weight":100,"Attr":null,"Altitude":8,"VerticalSpeed":0}]}]]}]
|
|
@ -1,6 +1,6 @@
|
|||
[gd_resource type="Theme" load_steps=61 format=3 uid="uid://ds668te2rph30"]
|
||||
|
||||
[ext_resource type="FontFile" uid="uid://cad0in7dtweo5" path="res://resource/font/VonwaonBitmap-16px.ttf" id="1_1e6k7"]
|
||||
[ext_resource type="FontFile" uid="uid://l2h5n3elepgp" path="res://resource/font/VonwaonBitmap-16px.ttf" id="1_1e6k7"]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="2"]
|
||||
content_margin_left = 6.0
|
||||
|
|
|
@ -1,255 +0,0 @@
|
|||
|
||||
#if TOOLS
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Godot;
|
||||
|
||||
namespace Generator;
|
||||
|
||||
/// <summary>
|
||||
/// 地牢房间数据生成器
|
||||
/// </summary>
|
||||
public static class DungeonRoomGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据名称在编辑器中创建地牢的预制房间, open 表示创建完成后是否在编辑器中打开这个房间
|
||||
/// </summary>
|
||||
public static bool CreateDungeonRoom(string groupName, string roomType, string roomName, bool open = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = GameConfig.RoomTileDir + groupName + "/" + roomType;
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
}
|
||||
//创建场景资源
|
||||
var prefabFile = path + "/" + roomName + ".tscn";
|
||||
var prefabResPath = "res://" + prefabFile;
|
||||
if (!Directory.Exists(GameConfig.RoomTileDir))
|
||||
{
|
||||
Directory.CreateDirectory(GameConfig.RoomTileDir);
|
||||
}
|
||||
|
||||
//加载脚本资源
|
||||
|
||||
// 这段代码在 Godot4.0.1rc1中会报错, 应该是个bug
|
||||
// var scriptRes = GD.Load<CSharpScript>("res://src/framework/map/DungeonRoomTemplate.cs");
|
||||
// var tileMap = new TileMap();
|
||||
// tileMap.Name = roomName;
|
||||
// tileMap.SetScript(scriptRes);
|
||||
// var scene = new PackedScene();
|
||||
// scene.Pack(tileMap); //报错在这一行, 报的是访问了被销毁的资源 scriptRes
|
||||
// ResourceSaver.Save(scene, prefabResPath);
|
||||
|
||||
//临时处理
|
||||
{
|
||||
var tscnCode = $"[gd_scene load_steps=2 format=3]\n" +
|
||||
$"\n" +
|
||||
$"[ext_resource type=\"Script\" path=\"res://src/framework/map/DungeonRoomTemplate.cs\" id=\"dungeonRoomTemplate\"]\n" +
|
||||
$"\n" +
|
||||
$"[node name=\"{roomName}\" type=\"TileMap\"]\n" +
|
||||
$"format = 2\n" +
|
||||
$"script = ExtResource(\"dungeonRoomTemplate\")\n";
|
||||
File.WriteAllText(prefabFile, tscnCode);
|
||||
//重新保存一遍, 以让编辑器生成资源Id
|
||||
var scene = GD.Load<PackedScene>(prefabResPath);
|
||||
ResourceSaver.Save(scene, prefabResPath);
|
||||
}
|
||||
|
||||
//打包房间配置
|
||||
GenerateRoomConfig();
|
||||
|
||||
//生成 UiManager_Methods.cs 代码
|
||||
UiManagerMethodsGenerator.Generate();
|
||||
//打开房间
|
||||
if (open)
|
||||
{
|
||||
Plugin.Plugin.Instance.GetEditorInterface().OpenSceneFromPath(prefabResPath);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e.ToString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行生成 RoomConfig.json 操作, 返回是否执行成功
|
||||
/// </summary>
|
||||
public static bool GenerateRoomConfig()
|
||||
{
|
||||
Debug.Log("生成RoomConfig.json流程得改");
|
||||
// try
|
||||
// {
|
||||
// //地图路径
|
||||
// var tileDir = GameConfig.RoomTileDir;
|
||||
// //地图描述数据路径
|
||||
// var tileDataDir = GameConfig.RoomTileDataDir;
|
||||
//
|
||||
// var tileGroup = new DirectoryInfo(tileDir).GetDirectories();
|
||||
// var tileDataGroup = new DirectoryInfo(tileDataDir).GetDirectories();
|
||||
//
|
||||
// //所有地图列表
|
||||
// var map = new Dictionary<string, FileInfo>();
|
||||
//
|
||||
// //地图场景
|
||||
// foreach (var groupDir in tileGroup)
|
||||
// {
|
||||
// var groupName = groupDir.Name;
|
||||
// var typeDirArray = groupDir.GetDirectories();
|
||||
// //遍历枚举, 获取指定路径文件
|
||||
// foreach (DungeonRoomType roomType in Enum.GetValues(typeof(DungeonRoomType)))
|
||||
// {
|
||||
// var typeName = DungeonManager.DungeonRoomTypeToString(roomType);
|
||||
//
|
||||
// //收集所有文件名称
|
||||
// var tempFileDataInfos = typeDirArray.FirstOrDefault(dirInfo => dirInfo.Name == typeName);
|
||||
// if (tempFileDataInfos != null)
|
||||
// {
|
||||
// foreach (var fileInfo in tempFileDataInfos.GetFiles())
|
||||
// {
|
||||
// if (fileInfo.Extension == ".tscn")
|
||||
// {
|
||||
// var pathInfo = new FileInfo(groupName, roomType, typeName, ResourceManager.RemoveExtension(fileInfo.Name));
|
||||
// map.TryAdd(pathInfo.GetPath(), pathInfo);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //地图配置数据
|
||||
// foreach (var groupDir in tileDataGroup)
|
||||
// {
|
||||
// var groupName = groupDir.Name;
|
||||
// var typeDirArray = groupDir.GetDirectories();
|
||||
// //遍历枚举, 获取指定路径文件
|
||||
// foreach (DungeonRoomType roomType in Enum.GetValues(typeof(DungeonRoomType)))
|
||||
// {
|
||||
// var typeName = DungeonManager.DungeonRoomTypeToString(roomType);
|
||||
//
|
||||
// //收集所有文件名称
|
||||
// var tempFileDataInfos = typeDirArray.FirstOrDefault(dirInfo => dirInfo.Name == typeName);
|
||||
// if (tempFileDataInfos != null)
|
||||
// {
|
||||
// foreach (var fileInfo in tempFileDataInfos.GetFiles())
|
||||
// {
|
||||
// if (fileInfo.Extension == ".json")
|
||||
// {
|
||||
// var pathInfo = new FileInfo(groupName, roomType, typeName, ResourceManager.RemoveExtension(fileInfo.Name));
|
||||
// map.TryAdd(pathInfo.GetPath(), pathInfo);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //剔除多余的 tile.json
|
||||
// foreach (var item in map)
|
||||
// {
|
||||
// var path = item.Key;
|
||||
// if (!File.Exists(tileDir + path + ".tscn"))
|
||||
// {
|
||||
// map.Remove(path);
|
||||
// var filePath = tileDataDir + path + ".json";
|
||||
// if (File.Exists(filePath))
|
||||
// {
|
||||
// Debug.Log($"未找到'{tileDir + path}.tscn', 删除配置文件: {filePath}");
|
||||
// File.Delete(filePath);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// //手动生成缺失的 tile.json
|
||||
// foreach (var item in map)
|
||||
// {
|
||||
// if (!File.Exists(tileDataDir + item.Key + ".json"))
|
||||
// {
|
||||
// var tscnName = tileDir + item.Key + ".tscn";
|
||||
// var packedScene = ResourceManager.Load<PackedScene>(tscnName, false);
|
||||
// if (packedScene != null)
|
||||
// {
|
||||
// var dungeonRoomTemplate = packedScene.Instantiate<DungeonRoomTemplate>();
|
||||
// var usedRect = dungeonRoomTemplate.GetUsedRect();
|
||||
// var dungeonTile = new DungeonTileMap(dungeonRoomTemplate);
|
||||
// dungeonTile.SetFloorAtlasCoords(new List<Vector2I>() { new Vector2I(0, 8) });
|
||||
// //计算导航网格
|
||||
// dungeonTile.GenerateNavigationPolygon(0);
|
||||
//
|
||||
// DungeonRoomInfo.SaveConfig(new List<DoorAreaInfo>(), usedRect.Position, usedRect.Size,
|
||||
// item.Value.GroupName, item.Value.RoomType, item.Value.FileName, dungeonRoomTemplate.Weight);
|
||||
// dungeonRoomTemplate.QueueFree();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// var roomGroupMap = new Dictionary<string, DungeonRoomGroup>();
|
||||
// //var list = new List<DungeonRoomSplit>();
|
||||
// //整合操作
|
||||
// foreach (var item in map)
|
||||
// {
|
||||
// var path = item.Key;
|
||||
// var configPath = tileDataDir + path + ".json";
|
||||
// var split = new DungeonRoomSplit();
|
||||
// split.ScenePath = ResourceManager.ToResPath(tileDir + path + ".tscn");
|
||||
// split.RoomPath = ResourceManager.ToResPath(configPath);
|
||||
//
|
||||
// if (!roomGroupMap.TryGetValue(item.Value.GroupName, out var group))
|
||||
// {
|
||||
// group = new DungeonRoomGroup();
|
||||
// group.GroupName = item.Value.GroupName;
|
||||
// roomGroupMap.Add(group.GroupName, group);
|
||||
// }
|
||||
//
|
||||
// group.GetRoomList(item.Value.RoomType).Add(split);
|
||||
// }
|
||||
//
|
||||
// //写出配置
|
||||
// var config = new JsonSerializerOptions();
|
||||
// config.WriteIndented = true;
|
||||
// var text = JsonSerializer.Serialize(roomGroupMap, config);
|
||||
// File.WriteAllText(GameConfig.RoomTileConfigFile, text);
|
||||
//
|
||||
// Debug.Log("地牢房间配置, 重新打包完成!");
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Debug.LogError(e.ToString());
|
||||
// return false;
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private class FileInfo
|
||||
{
|
||||
public FileInfo(string groupName, DungeonRoomType roomType, string typeName, string fileName)
|
||||
{
|
||||
GroupName = groupName;
|
||||
RoomType = roomType;
|
||||
TypeName = typeName;
|
||||
FileName = fileName;
|
||||
}
|
||||
|
||||
public string GroupName;
|
||||
public DungeonRoomType RoomType;
|
||||
public string TypeName;
|
||||
public string FileName;
|
||||
|
||||
public string GetPath()
|
||||
{
|
||||
return GroupName + "/" + TypeName + "/" + FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,76 +0,0 @@
|
|||
#if TOOLS
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using Config;
|
||||
using Godot;
|
||||
using Array = Godot.Collections.Array;
|
||||
|
||||
namespace Generator;
|
||||
|
||||
public static class ExcelGenerator
|
||||
{
|
||||
public static void ExportExcel()
|
||||
{
|
||||
var arr = new Array();
|
||||
var excelPath = "excel/excelFile/";
|
||||
var jsonPath = "resource/config/";
|
||||
var codePath = "src/config/";
|
||||
OS.Execute("excel/DungeonShooting_ExcelTool.exe", new string[] { excelPath, jsonPath, codePath }, arr);
|
||||
foreach (var message in arr)
|
||||
{
|
||||
Debug.Log(message);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
GeneratorActivityObjectInit();
|
||||
Debug.Log("生成'src/framework/activity/ActivityObject_Init.cs'成功!");
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Debug.LogError(e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
//生成初始化 ActivityObject 代码
|
||||
private static void GeneratorActivityObjectInit()
|
||||
{
|
||||
var text = File.ReadAllText($"resource/config/{nameof(ExcelConfig.ActivityBase)}.json");
|
||||
var array = JsonSerializer.Deserialize<System.Collections.Generic.Dictionary<string, object>[]>(text);
|
||||
|
||||
var code1 = "";
|
||||
|
||||
foreach (var item in array)
|
||||
{
|
||||
var id = item["Id"];
|
||||
var name = item["Name"] + "";
|
||||
var intro = item["Intro"] + "";
|
||||
code1 += $" /// <summary>\n";
|
||||
code1 += $" /// 名称: {name} <br/>\n";
|
||||
code1 += $" /// 简介: {intro.Replace("\n", " <br/>\n /// ")}\n";
|
||||
code1 += $" /// </summary>\n";
|
||||
code1 += $" public const string Id_{id} = \"{id}\";\n";
|
||||
}
|
||||
|
||||
var str = $"using Config;\n\n";
|
||||
str += $"// 根据配置表注册物体, 该类是自动生成的, 请不要手动编辑!\n";
|
||||
str += $"public partial class ActivityObject\n";
|
||||
str += $"{{\n";
|
||||
|
||||
str += $" /// <summary>\n";
|
||||
str += $" /// 存放所有在表中注册的物体的id\n";
|
||||
str += $" /// </summary>\n";
|
||||
str += $" public static class Ids\n";
|
||||
str += $" {{\n";
|
||||
str += code1;
|
||||
str += $" }}\n";
|
||||
|
||||
str += $"}}\n";
|
||||
|
||||
File.WriteAllText("src/framework/activity/ActivityObject_Init.cs", str);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -239,7 +239,7 @@ public partial class Player : Role
|
|||
|
||||
protected override void OnAffiliationChange(AffiliationArea prevArea)
|
||||
{
|
||||
//BrushPrevPosition = null;
|
||||
BrushPrevPosition = null;
|
||||
base.OnAffiliationChange(prevArea);
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ public partial class Knife : Weapon
|
|||
//播放挥刀特效
|
||||
SpecialEffectManager.Play(
|
||||
Master,
|
||||
ResourcePath.resource_sprite_weapon_weapon0004_KnifeHit1_png, "default",
|
||||
ResourcePath.resource_spriteFrames_weapon_Weapon0004_hit_tres, "default",
|
||||
Master.MountPoint.Position,
|
||||
Master.MountPoint.Rotation + Mathf.DegToRad(Attribute.UpliftAngle + 60),
|
||||
AnimatedSprite.Scale,
|
||||
|
|
|
@ -201,7 +201,7 @@ public partial class DungeonManager : Node2D
|
|||
World = GameApplication.Instance.CreateNewWorld();
|
||||
yield return 0;
|
||||
//生成地牢房间
|
||||
var random = new SeedRandom();
|
||||
var random = new SeedRandom(205371406);
|
||||
_dungeonGenerator = new DungeonGenerator(CurrConfig, random);
|
||||
_dungeonGenerator.Generate();
|
||||
yield return 0;
|
||||
|
|
|
@ -303,7 +303,7 @@ public partial class EditorToolsPanel : EditorTools
|
|||
/// </summary>
|
||||
private void OpenExportExcelFolder()
|
||||
{
|
||||
var path = Environment.CurrentDirectory + "\\excel\\excelFile";
|
||||
var path = Environment.CurrentDirectory + "\\excel";
|
||||
System.Diagnostics.Process.Start("explorer.exe", path);
|
||||
}
|
||||
|
||||
|
|
15
README.md
|
@ -1,5 +1,8 @@
|
|||
|
||||
一款由Godot开发的地牢射击类型的游戏, 脚本语言使用的是C#, 当前项目使用的Godot版本: Godot_v4.2
|
||||
## 一款由Godot开发的地牢射击类型的游戏
|
||||
|
||||
**Godot版本:** `4.2.1 mono`
|
||||
**.Net版本:** `8.0`
|
||||
|
||||
---
|
||||
### 游戏定义
|
||||
|
@ -9,24 +12,24 @@
|
|||
**游戏类型:** Roguelite, 俯视角, 地牢探索, 双摇杆射击
|
||||
**参考游戏:** 挺进地牢, 元气骑士, 废土之王
|
||||
**核心简介:** 游戏整体流程由数层地牢组成, 每层又由数个房间组成, 每个房间有一堵门隔开, 玩家每进入一个房间, 需要清理房间内所有的敌人, 方可离开和进入下一个房间,
|
||||
玩家需要在这些房间中探索, 战斗, 收集掉落的道具和被动, 一步步成长, 击败boss, 进入下一层, 如此往复, 直到击败最后一层boss即可通关.
|
||||
玩家需要在这些房间中探索, 战斗, 收集掉落的道具和被动, 一步步成长, 击败boss, 进入下一层, 如此往复, 直到击败最后一层boss即可通关.
|
||||
但本作与市面上常规地牢射击游戏不同的是, 玩家与敌人共用武器资源, 玩家击败敌人便可拾起敌人的武器, 并且更加注重环境互动要素
|
||||
**游戏背景:** 构思中
|
||||
|
||||
![gif](DungeonShooting_Document/文档资源/preview_gif.gif)
|
||||
|
||||
---
|
||||
|
||||
### 启动项目
|
||||
|
||||
git仓库的目录结构如下
|
||||
> ├ DungeonShooting_Document (项目帮助文档, 更新日志相关的目录)
|
||||
> ├ DungeonShooting_ExcelTool (项目excel配置表导出工具源代码)
|
||||
> ├ DungeonShooting_Document (更新日志相关的目录)
|
||||
> └ DungeonShooting_Godot (Godot工程目录)
|
||||
|
||||
下载好指定的Godot版本, 注意使用的是Godot_Mono版, 使用Godot打开`DungeonShooting_Godot/project.godot`, 如果是第一次打开项目会弹出一个找不到资源的提示, 这是因为项目没有编译过, 点击Godot右上角`build`, 然后打`开项目设置`, 在`插件`这一个页签下启用`DungeonShooting_plugin`这个插件, 然后项目就可以正常运行了
|
||||
使用GodotMono版打开`DungeonShooting_Godot/project.godot`, 如果是第一次打开项目会弹出一个找不到资源的提示, 这是因为项目没有编译过, 点击Godot右上角`build`, 然后打`开项目设置`, 在`插件`这一个页签下启用`DungeonShooting_plugin`这个插件, 然后项目就可以正常运行了
|
||||
|
||||
---
|
||||
### 其他
|
||||
|
||||
**开发日志:** [开发日志.md](DungeonShooting_Document/开发日志.md)
|
||||
**哔哩哔哩:** https://space.bilibili.com/259437820
|
||||
**项目Ui插件:** https://github.com/xlljc/Ds_Ui
|