自定义房间生成规则, 开发中
This commit is contained in:
parent
ce45ec6d6a
commit
eb4a25a7f7
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -19,3 +19,4 @@
|
|||
/DungeonShooting_ExcelTool/bin
|
||||
/DungeonShooting_Godot/DungeonShooting.sln.DotSettings.user
|
||||
/DungeonShooting_Godot/.VSCodeCounter
|
||||
**/*.txt
|
||||
|
|
|
@ -2,11 +2,7 @@
|
|||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
<<<<<<< HEAD
|
||||
uid="uid://wew7xnxc4d50"
|
||||
=======
|
||||
uid="uid://c08d7xo84ssqp"
|
||||
>>>>>>> faff39f870b1097c233b529865b4f3ee2311c8a3
|
||||
uid="uid://b72ww741x2t0w"
|
||||
path="res://.godot/imported/Preview.png-e48e389971aff40736b911be53ae62ea.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://mnc7p56vjvd2"
|
||||
path="res://.godot/imported/gun10.png-f740f5104fd9c145ecc2e63b27a6fb04.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/weapon0011/gun10.png"
|
||||
dest_files=["res://.godot/imported/gun10.png-f740f5104fd9c145ecc2e63b27a6fb04.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
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b4exgoa8t0wny"
|
||||
path="res://.godot/imported/bow.png-9ae685914082766e6dbcd1eaddb43b40.ctex"
|
||||
path="res://.godot/imported/bow.png-88942d9562b550ee90573ad2cdb4bb92.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/bow.png"
|
||||
dest_files=["res://.godot/imported/bow.png-9ae685914082766e6dbcd1eaddb43b40.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0012/bow.png"
|
||||
dest_files=["res://.godot/imported/bow.png-88942d9562b550ee90573ad2cdb4bb92.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cphawlk2w0w6w"
|
||||
path="res://.godot/imported/weapon0013.png-ebf877c1ae1b135ec79dd1b6a7ae1165.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/weapon0013/weapon0013.png"
|
||||
dest_files=["res://.godot/imported/weapon0013.png-ebf877c1ae1b135ec79dd1b6a7ae1165.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
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cuivqyq32tjan"
|
||||
path="res://.godot/imported/weapon0014-export.png-f1691475edd2682499f71dfe7d46110d.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/weapon0013/weapon0014-export.png"
|
||||
dest_files=["res://.godot/imported/weapon0014-export.png-f1691475edd2682499f71dfe7d46110d.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
|
|
@ -0,0 +1,34 @@
|
|||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://deqflkjkgkebd"
|
||||
path="res://.godot/imported/weapon0014.png-231a4437579a4dfcadef71f1a72de1ed.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/weapon0013/weapon0014.png"
|
||||
dest_files=["res://.godot/imported/weapon0014.png-231a4437579a4dfcadef71f1a72de1ed.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
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c1tnh6laf172u"
|
||||
path="res://.godot/imported/gun3.png-d2428e7c1819cfb8a78ef87505aee0a3.ctex"
|
||||
path="res://.godot/imported/gun3.png-3eceb0c7c64a7bf84605307efa15f7f3.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/gun3.png"
|
||||
dest_files=["res://.godot/imported/gun3.png-d2428e7c1819cfb8a78ef87505aee0a3.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0015/gun3.png"
|
||||
dest_files=["res://.godot/imported/gun3.png-3eceb0c7c64a7bf84605307efa15f7f3.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://xafbhgrxmosy"
|
||||
path="res://.godot/imported/gun4.png-f47ef44de364483b033f38a2d031303c.ctex"
|
||||
path="res://.godot/imported/gun4.png-3a854e99c328550ec802a641bed4ce89.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/gun4.png"
|
||||
dest_files=["res://.godot/imported/gun4.png-f47ef44de364483b033f38a2d031303c.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0016/gun4.png"
|
||||
dest_files=["res://.godot/imported/gun4.png-3a854e99c328550ec802a641bed4ce89.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c2eber1v7nb4j"
|
||||
path="res://.godot/imported/gun5.png-da05c9e18ddc46a7f72168cb9c25449c.ctex"
|
||||
path="res://.godot/imported/gun5.png-dde9a0cdc02e2378517e9d271797761c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/gun5.png"
|
||||
dest_files=["res://.godot/imported/gun5.png-da05c9e18ddc46a7f72168cb9c25449c.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0017/gun5.png"
|
||||
dest_files=["res://.godot/imported/gun5.png-dde9a0cdc02e2378517e9d271797761c.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://rlp8f2rgxlbf"
|
||||
path="res://.godot/imported/gun6.png-698dacce2603c9d452b55702363db8fc.ctex"
|
||||
path="res://.godot/imported/gun6.png-661eed06db2d1504a8e43f81aca88938.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/gun6.png"
|
||||
dest_files=["res://.godot/imported/gun6.png-698dacce2603c9d452b55702363db8fc.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0018/gun6.png"
|
||||
dest_files=["res://.godot/imported/gun6.png-661eed06db2d1504a8e43f81aca88938.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bs6ukbtcmxuiw"
|
||||
path="res://.godot/imported/gun7.png-9068807109603150cd0529909f81d6c1.ctex"
|
||||
path="res://.godot/imported/gun7.png-f1428c4b8a1ac62dafacd70a35e5813b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/gun7.png"
|
||||
dest_files=["res://.godot/imported/gun7.png-9068807109603150cd0529909f81d6c1.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0019/gun7.png"
|
||||
dest_files=["res://.godot/imported/gun7.png-f1428c4b8a1ac62dafacd70a35e5813b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://2lcc20olyi5d"
|
||||
path="res://.godot/imported/gun8.png-a936b61cfb3713c19173bfa954b35ecd.ctex"
|
||||
path="res://.godot/imported/gun8.png-981667783ada37a774730057971adda6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://resource/sprite/weapon/gun8.png"
|
||||
dest_files=["res://.godot/imported/gun8.png-a936b61cfb3713c19173bfa954b35ecd.ctex"]
|
||||
source_file="res://resource/sprite/weapon/weapon0020/gun8.png"
|
||||
dest_files=["res://.godot/imported/gun8.png-981667783ada37a774730057971adda6.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
|
|
|
@ -41,6 +41,11 @@ public class DungeonConfig
|
|||
/// </summary>
|
||||
public int RoomCount => BattleRoomCount + RewardRoomCount + ShopRoomCount + OutRoomCount + BossRoomCount;
|
||||
|
||||
/// <summary>
|
||||
/// 房间最大层级
|
||||
/// </summary>
|
||||
public int MaxLayer = 5;
|
||||
|
||||
//----------------------- 地牢编辑使用 -------------------------
|
||||
/// <summary>
|
||||
/// 是否指定了房间
|
||||
|
|
|
@ -65,7 +65,7 @@ public class DungeonGenerator
|
|||
private int _id;
|
||||
|
||||
//下一个房间类型
|
||||
private DungeonRoomType _nextRoomType = DungeonRoomType.Battle;
|
||||
private DungeonRoomType _nextRoomType = DungeonRoomType.None;
|
||||
|
||||
//间隔
|
||||
private int _roomMinInterval = 2;
|
||||
|
@ -78,9 +78,6 @@ public class DungeonGenerator
|
|||
//房间纵轴分散程度
|
||||
private float _roomVerticalMinDispersion = -0.6f;
|
||||
private float _roomVerticalMaxDispersion = 0.6f;
|
||||
|
||||
//房间最大层级
|
||||
private int _maxLayer = 5;
|
||||
|
||||
//区域限制
|
||||
private bool _enableLimitRange = true;
|
||||
|
@ -97,19 +94,9 @@ public class DungeonGenerator
|
|||
|
||||
//地牢房间规则处理类
|
||||
private DungeonRule _rule;
|
||||
|
||||
private enum GenerateRoomErrorCode
|
||||
{
|
||||
NoError,
|
||||
//超出区域
|
||||
OutArea,
|
||||
//没有合适的位置
|
||||
NoSuitableLocation
|
||||
// //碰到其他房间或过道
|
||||
// HasCollision,
|
||||
// //没有合适的门
|
||||
// NoProperDoor,
|
||||
}
|
||||
|
||||
//上一个房间
|
||||
private RoomInfo prevRoomInfo = null;
|
||||
|
||||
public DungeonGenerator(DungeonConfig config, SeedRandom seedRandom)
|
||||
{
|
||||
|
@ -180,62 +167,23 @@ public class DungeonGenerator
|
|||
if (StartRoomInfo != null) return false;
|
||||
_rule = rule;
|
||||
|
||||
_nextRoomType = _rule.GetNextRoomType(null);
|
||||
//用于排除上一级房间
|
||||
var excludePrevRoom = new List<RoomInfo>();
|
||||
//上一个房间
|
||||
RoomInfo prevRoomInfo = null;
|
||||
|
||||
var chainTryCount = 0;
|
||||
var chainMaxTryCount = 3;
|
||||
|
||||
//最大尝试次数
|
||||
var maxTryCount = 1000;
|
||||
var maxTryCount = 2000;
|
||||
|
||||
//当前尝试次数
|
||||
var currTryCount = 0;
|
||||
|
||||
//如果房间数量不够, 就一直生成
|
||||
while (!_rule.CanOverGenerator() || EndRoomInfos.Count == 0)
|
||||
while (!_rule.CanOverGenerator())
|
||||
{
|
||||
if (_nextRoomType == DungeonRoomType.None)
|
||||
{
|
||||
_nextRoomType = _rule.GetNextRoomType(prevRoomInfo);
|
||||
}
|
||||
var nextRoomType = _nextRoomType;
|
||||
|
||||
//上一个房间
|
||||
RoomInfo tempPrevRoomInfo;
|
||||
if (nextRoomType == DungeonRoomType.Inlet)
|
||||
{
|
||||
tempPrevRoomInfo = null;
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Boss)
|
||||
{
|
||||
tempPrevRoomInfo = FindMaxLayerRoom(excludePrevRoom);
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Outlet || nextRoomType == DungeonRoomType.Reward || nextRoomType == DungeonRoomType.Shop || nextRoomType == DungeonRoomType.Event)
|
||||
{
|
||||
tempPrevRoomInfo = prevRoomInfo;
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Battle)
|
||||
{
|
||||
if (chainTryCount < chainMaxTryCount)
|
||||
{
|
||||
if (prevRoomInfo != null && prevRoomInfo.Layer >= _maxLayer - 1) //层数太高, 下一个房间生成在低层级
|
||||
{
|
||||
tempPrevRoomInfo = RoundRoomLessThanLayer(Mathf.Max(1, _maxLayer / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
tempPrevRoomInfo = prevRoomInfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempPrevRoomInfo = Random.RandomChoose(RoomInfos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempPrevRoomInfo = Random.RandomChoose(RoomInfos);
|
||||
}
|
||||
var tempPrevRoomInfo = _rule.GetConnectPrevRoom(prevRoomInfo, nextRoomType);
|
||||
|
||||
//生成下一个房间
|
||||
var errorCode = GenerateRoom(tempPrevRoomInfo, nextRoomType, out var nextRoom);
|
||||
|
@ -250,7 +198,6 @@ public class DungeonGenerator
|
|||
else if (nextRoomType == DungeonRoomType.Boss) //boss房间
|
||||
{
|
||||
BossRoomInfos.Add(nextRoom);
|
||||
excludePrevRoom.Clear();
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Outlet)
|
||||
{
|
||||
|
@ -259,8 +206,6 @@ public class DungeonGenerator
|
|||
else if (nextRoomType == DungeonRoomType.Battle)
|
||||
{
|
||||
BattleRoomInfos.Add(nextRoom);
|
||||
chainTryCount = 0;
|
||||
chainMaxTryCount = Random.RandomRangeInt(1, 3);
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Reward)
|
||||
{
|
||||
|
@ -270,37 +215,14 @@ public class DungeonGenerator
|
|||
{
|
||||
ShopRoomInfos.Add(nextRoom);
|
||||
}
|
||||
var prev = prevRoomInfo;
|
||||
prevRoomInfo = nextRoom;
|
||||
_nextRoomType = _rule.GetNextRoomType(prevRoomInfo);
|
||||
_rule.GenerateRoomSuccess(prev, nextRoom);
|
||||
_nextRoomType = _rule.GetNextRoomType(nextRoom);
|
||||
}
|
||||
else //生成失败
|
||||
{
|
||||
if (nextRoomType == DungeonRoomType.Boss)
|
||||
{
|
||||
//生成boss房间成功
|
||||
excludePrevRoom.Add(tempPrevRoomInfo);
|
||||
if (excludePrevRoom.Count >= RoomInfos.Count)
|
||||
{
|
||||
//全都没找到合适的, 那就再来一遍
|
||||
excludePrevRoom.Clear();
|
||||
}
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Outlet)
|
||||
{
|
||||
//生成结束房间失败, 那么只能回滚boss房间
|
||||
if (prevRoomInfo != null)
|
||||
{
|
||||
var bossPrev = prevRoomInfo.Prev;
|
||||
BossRoomInfos.Remove(prevRoomInfo);
|
||||
RollbackRoom(prevRoomInfo);
|
||||
_nextRoomType = _rule.GetNextRoomType(bossPrev);
|
||||
prevRoomInfo = null;
|
||||
}
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Battle)
|
||||
{
|
||||
chainTryCount++;
|
||||
}
|
||||
_rule.GenerateRoomFail(prevRoomInfo, nextRoomType);
|
||||
|
||||
//Debug.Log("生成第" + (_count + 1) + "个房间失败! 失败原因: " + errorCode);
|
||||
if (errorCode == GenerateRoomErrorCode.OutArea)
|
||||
|
@ -348,7 +270,7 @@ public class DungeonGenerator
|
|||
{
|
||||
//随机选择一个房间
|
||||
var list = RoomGroup.GetRoomList(roomType);
|
||||
if (list.Count == 0) //如果没有指定类型的房间, 就生成战斗房间
|
||||
if (list.Count == 0) //如果没有指定类型的房间, 或者房间数量不够, 就生成战斗房间
|
||||
{
|
||||
roomSplit = RoomGroup.GetRandomRoom(DungeonRoomType.Battle);
|
||||
}
|
||||
|
@ -483,8 +405,18 @@ public class DungeonGenerator
|
|||
return GenerateRoomErrorCode.NoError;
|
||||
}
|
||||
|
||||
//回滚一个房间
|
||||
private bool RollbackRoom(RoomInfo roomInfo)
|
||||
/// <summary>
|
||||
/// 设置上一个房间
|
||||
/// </summary>
|
||||
public void SetPrevRoom(RoomInfo roomInfo)
|
||||
{
|
||||
prevRoomInfo = roomInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 回滚一个房间
|
||||
/// </summary>
|
||||
public bool RollbackRoom(RoomInfo roomInfo)
|
||||
{
|
||||
if (roomInfo.Next.Count > 0)
|
||||
{
|
||||
|
@ -512,8 +444,33 @@ public class DungeonGenerator
|
|||
}
|
||||
|
||||
RoomInfos.Remove(roomInfo);
|
||||
switch (roomInfo.RoomType)
|
||||
{
|
||||
case DungeonRoomType.Battle:
|
||||
BattleRoomInfos.Remove(roomInfo);
|
||||
break;
|
||||
case DungeonRoomType.Inlet:
|
||||
StartRoomInfo = null;
|
||||
break;
|
||||
case DungeonRoomType.Outlet:
|
||||
EndRoomInfos.Remove(roomInfo);
|
||||
break;
|
||||
case DungeonRoomType.Boss:
|
||||
BossRoomInfos.Remove(roomInfo);
|
||||
break;
|
||||
case DungeonRoomType.Reward:
|
||||
RewardRoomInfos.Remove(roomInfo);
|
||||
break;
|
||||
case DungeonRoomType.Shop:
|
||||
ShopRoomInfos.Remove(roomInfo);
|
||||
break;
|
||||
case DungeonRoomType.Event:
|
||||
break;
|
||||
}
|
||||
|
||||
roomInfo.Destroy();
|
||||
_id--;
|
||||
_nextRoomType = DungeonRoomType.None;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -521,7 +478,7 @@ public class DungeonGenerator
|
|||
/// 寻找层级最高的房间
|
||||
/// </summary>
|
||||
/// <param name="exclude">排除的房间</param>
|
||||
private RoomInfo FindMaxLayerRoom(List<RoomInfo> exclude)
|
||||
public RoomInfo FindMaxLayerRoom(List<RoomInfo> exclude = null)
|
||||
{
|
||||
RoomInfo temp = null;
|
||||
foreach (var roomInfo in RoomInfos)
|
||||
|
@ -541,7 +498,7 @@ public class DungeonGenerator
|
|||
/// <summary>
|
||||
/// 随机抽取层级小于 layer 的房间
|
||||
/// </summary>
|
||||
private RoomInfo RoundRoomLessThanLayer(int layer)
|
||||
public RoomInfo RoundRoomLessThanLayer(int layer)
|
||||
{
|
||||
var list = new List<RoomInfo>();
|
||||
foreach (var roomInfo in RoomInfos)
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
/// </summary>
|
||||
public enum DungeonRoomType
|
||||
{
|
||||
/// <summary>
|
||||
/// 无
|
||||
/// </summary>
|
||||
None,
|
||||
/// <summary>
|
||||
/// 普通战斗房间, 进入该房间时会关上门, 并刷出若干波敌人, 消灭所有敌人后开门
|
||||
/// </summary>
|
||||
|
|
|
@ -10,20 +10,38 @@ public abstract class DungeonRule
|
|||
|
||||
public SeedRandom Random { get; }
|
||||
|
||||
public DungeonRoomGroup RoomGroup { get; }
|
||||
|
||||
public DungeonRule(DungeonGenerator generator)
|
||||
{
|
||||
Generator = generator;
|
||||
Config = generator.Config;
|
||||
Random = generator.Random;
|
||||
RoomGroup = generator.RoomGroup;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否可以结束生成了
|
||||
/// </summary>
|
||||
public abstract bool CanOverGenerator();
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定房间类型与之相连的上一个房间对象
|
||||
/// </summary>
|
||||
public abstract RoomInfo GetConnectPrevRoom(RoomInfo prevRoomInfo, DungeonRoomType nextRoomType);
|
||||
|
||||
/// <summary>
|
||||
/// 计算下一个房间类型
|
||||
/// </summary>
|
||||
public abstract DungeonRoomType GetNextRoomType(RoomInfo prev);
|
||||
public abstract DungeonRoomType GetNextRoomType(RoomInfo prevRoomInfo);
|
||||
|
||||
/// <summary>
|
||||
/// 执行生成指定房间成功
|
||||
/// </summary>
|
||||
public abstract void GenerateRoomSuccess(RoomInfo prevRoomInfo, RoomInfo roomInfo);
|
||||
|
||||
/// <summary>
|
||||
/// 执行生成指定类型房间失败
|
||||
/// </summary>
|
||||
public abstract void GenerateRoomFail(RoomInfo prevRoomInfo, DungeonRoomType roomType);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
public enum GenerateRoomErrorCode
|
||||
{
|
||||
NoError,
|
||||
//超出区域
|
||||
OutArea,
|
||||
//没有合适的位置
|
||||
NoSuitableLocation
|
||||
// //碰到其他房间或过道
|
||||
// HasCollision,
|
||||
// //没有合适的门
|
||||
// NoProperDoor,
|
||||
}
|
|
@ -139,6 +139,12 @@ public class RoomInfo : IDestroy
|
|||
/// 导航网格对象
|
||||
/// </summary>
|
||||
public NavigationRegion2D NavigationRegion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 在 DungeonGenerator 中是否可以回滚, 如果可以回滚, 那么当前房间就只会有一个 NextRoom
|
||||
/// </summary>
|
||||
public bool CanRollback { get; set; } = false;
|
||||
|
||||
public bool IsDestroyed { get; private set; }
|
||||
|
||||
private bool _openDoorFlag = true;
|
||||
|
|
|
@ -160,6 +160,7 @@ public class DungeonRoomGroup : IClone<DungeonRoomGroup>
|
|||
|
||||
foreach (var roomType in Enum.GetValues<DungeonRoomType>())
|
||||
{
|
||||
if (roomType == DungeonRoomType.None) continue;
|
||||
InitAdRewardWeight(roomType, random);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ public partial class GameApplication : Node2D, ICoroutine
|
|||
|
||||
DungeonConfig = new DungeonConfig();
|
||||
DungeonConfig.GroupName = "Test1";
|
||||
DungeonConfig.BattleRoomCount = 20;
|
||||
DungeonConfig.BattleRoomCount = 5;
|
||||
}
|
||||
|
||||
public override void _EnterTree()
|
||||
|
|
|
@ -61,12 +61,12 @@ public partial class Player : Role
|
|||
ActivePropsPack.SetCapacity(1);
|
||||
|
||||
// debug用
|
||||
// RoleState.Acceleration = 3000;
|
||||
// RoleState.Friction = 3000;
|
||||
// RoleState.MoveSpeed = 500;
|
||||
// CollisionLayer = 0;
|
||||
// CollisionMask = 0;
|
||||
// GameCamera.Main.Zoom = new Vector2(0.5f, 0.5f);
|
||||
RoleState.Acceleration = 3000;
|
||||
RoleState.Friction = 3000;
|
||||
RoleState.MoveSpeed = 500;
|
||||
CollisionLayer = 0;
|
||||
CollisionMask = 0;
|
||||
GameCamera.Main.Zoom = new Vector2(0.5f, 0.5f);
|
||||
//GameCamera.Main.Zoom = new Vector2(0.2f, 0.2f);
|
||||
// this.CallDelay(0.5f, () =>
|
||||
// {
|
||||
|
|
|
@ -1,19 +1,65 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
|
||||
/// <summary>
|
||||
/// 默认实现地牢房间规则
|
||||
/// </summary>
|
||||
public class DefaultDungeonRule : DungeonRule
|
||||
{
|
||||
//用于排除上一级房间
|
||||
private List<RoomInfo> excludePrevRoom = new List<RoomInfo>();
|
||||
private int chainTryCount = 0;
|
||||
private int chainMaxTryCount = 3;
|
||||
|
||||
public DefaultDungeonRule(DungeonGenerator generator) : base(generator)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool CanOverGenerator()
|
||||
{
|
||||
return Generator.BattleRoomInfos.Count >= Config.BattleRoomCount;
|
||||
return Generator.BattleRoomInfos.Count >= Config.BattleRoomCount && Generator.EndRoomInfos.Count > 0;
|
||||
}
|
||||
|
||||
public override DungeonRoomType GetNextRoomType(RoomInfo prev)
|
||||
public override RoomInfo GetConnectPrevRoom(RoomInfo prevRoomInfo, DungeonRoomType nextRoomType)
|
||||
{
|
||||
if (nextRoomType == DungeonRoomType.Inlet)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Boss)
|
||||
{
|
||||
return Generator.FindMaxLayerRoom(excludePrevRoom);
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Outlet || nextRoomType == DungeonRoomType.Reward || nextRoomType == DungeonRoomType.Shop || nextRoomType == DungeonRoomType.Event)
|
||||
{
|
||||
return prevRoomInfo;
|
||||
}
|
||||
else if (nextRoomType == DungeonRoomType.Battle)
|
||||
{
|
||||
if (chainTryCount < chainMaxTryCount)
|
||||
{
|
||||
if (prevRoomInfo != null && prevRoomInfo.Layer >= Config.MaxLayer - 1) //层数太高, 下一个房间生成在低层级
|
||||
{
|
||||
return Generator.RoundRoomLessThanLayer(Mathf.Max(1, Config.MaxLayer / 2));
|
||||
}
|
||||
else
|
||||
{
|
||||
return prevRoomInfo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Random.RandomChoose(Generator.RoomInfos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return Random.RandomChoose(Generator.RoomInfos);
|
||||
}
|
||||
}
|
||||
|
||||
public override DungeonRoomType GetNextRoomType(RoomInfo prevRoomInfo)
|
||||
{
|
||||
if (Generator.StartRoomInfo == null) //生成第一个房间
|
||||
{
|
||||
|
@ -23,18 +69,64 @@ public class DefaultDungeonRule : DungeonRule
|
|||
// {
|
||||
// return DungeonRoomType.Reward;
|
||||
// }
|
||||
else if (Generator.BattleRoomInfos.Count == Config.BattleRoomCount - 1) //最后一个房间是boss房间
|
||||
{
|
||||
return DungeonRoomType.Boss;
|
||||
}
|
||||
else if (Generator.BattleRoomInfos.Count >= Config.BattleRoomCount) //结束房间
|
||||
else if (prevRoomInfo.RoomType == DungeonRoomType.Boss) //boss房间后生成结束房间
|
||||
{
|
||||
return DungeonRoomType.Outlet;
|
||||
}
|
||||
else if (prev.RoomType == DungeonRoomType.Boss) //生成结束房间
|
||||
else if (Generator.BattleRoomInfos.Count >= Config.BattleRoomCount) //战斗房间已满
|
||||
{
|
||||
return DungeonRoomType.Outlet;
|
||||
if (Generator.BossRoomInfos.Count < Config.BossRoomCount) //最后一个房间是boss房间
|
||||
{
|
||||
if (RoomGroup.BossList.Count == 0) //没有预设boss房间
|
||||
{
|
||||
return DungeonRoomType.Battle;
|
||||
}
|
||||
//生成boss房间
|
||||
return DungeonRoomType.Boss;
|
||||
}
|
||||
}
|
||||
return DungeonRoomType.Battle;
|
||||
}
|
||||
|
||||
public override void GenerateRoomSuccess(RoomInfo prevRoomInfo, RoomInfo roomInfo)
|
||||
{
|
||||
if (roomInfo.RoomType == DungeonRoomType.Boss) //boss房间
|
||||
{
|
||||
roomInfo.CanRollback = true;
|
||||
excludePrevRoom.Clear();
|
||||
}
|
||||
else if (roomInfo.RoomType == DungeonRoomType.Battle)
|
||||
{
|
||||
chainTryCount = 0;
|
||||
chainMaxTryCount = Random.RandomRangeInt(1, 3);
|
||||
}
|
||||
}
|
||||
|
||||
public override void GenerateRoomFail(RoomInfo prevRoomInfo, DungeonRoomType roomType)
|
||||
{
|
||||
if (roomType == DungeonRoomType.Boss)
|
||||
{
|
||||
//生成boss房间成功
|
||||
excludePrevRoom.Add(prevRoomInfo);
|
||||
if (excludePrevRoom.Count >= Generator.RoomInfos.Count)
|
||||
{
|
||||
//全都没找到合适的, 那就再来一遍
|
||||
excludePrevRoom.Clear();
|
||||
}
|
||||
}
|
||||
else if (roomType == DungeonRoomType.Outlet)
|
||||
{
|
||||
//生成结束房间失败, 那么只能回滚boss房间
|
||||
if (prevRoomInfo != null)
|
||||
{
|
||||
var bossPrev = prevRoomInfo.Prev;
|
||||
Generator.RollbackRoom(prevRoomInfo);
|
||||
Generator.SetPrevRoom(bossPrev);
|
||||
}
|
||||
}
|
||||
else if (roomType == DungeonRoomType.Battle)
|
||||
{
|
||||
chainTryCount++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ public partial class World : CanvasModulate, ICoroutine
|
|||
|
||||
public override void _Ready()
|
||||
{
|
||||
Color = Colors.Black;
|
||||
//Color = Colors.Black;
|
||||
//TileRoot.YSortEnabled = false;
|
||||
NormalLayer = GetNode<Node2D>("TileRoot/NormalLayer");
|
||||
YSortLayer = GetNode<Node2D>("TileRoot/YSortLayer");
|
||||
|
|
Loading…
Reference in New Issue
Block a user