diff --git a/DungeonShooting_Godot/project.godot b/DungeonShooting_Godot/project.godot index 6d1d443..2588b93 100644 --- a/DungeonShooting_Godot/project.godot +++ b/DungeonShooting_Godot/project.godot @@ -30,6 +30,10 @@ project/assembly_name="DungeonShooting" +[editor_plugins] + +enabled=PackedStringArray("res://addons/dungeonShooting_plugin/plugin.cfg") + [file_customization] folder_colors={ diff --git a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs index 24516bd..90075e0 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs @@ -12,20 +12,39 @@ public string GroupName; /// - /// 房间数量 + /// 战斗房间数量 /// - public int RoomCount = 15; + public int BattleRoomCount = 15; /// + /// 奖励房间数量 + /// + public int RewardRoomCount = 2; + + /// + /// 商店数量 + /// + public int ShopRoomCount = 1; + + /// + /// 出口房间数量 + /// + public int OutRoomCount = 1; + + /// + /// Boss房间数量 + /// + public int BossRoomCount = 1; + + //----------------------- 地牢编辑使用 ------------------------- + /// /// 是否指定了房间 /// public bool HasDesignatedRoom => DesignatedRoom != null && DesignatedRoom.Count > 0; - /// /// 指定房间类型 /// public DungeonRoomType DesignatedType; - /// /// 指定房间列表 /// diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs index 5ff6d7c..ebb8306 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs @@ -30,9 +30,18 @@ public List BossRoom { get; } = new List(); /// + /// 地牢配置数据 + /// + public DungeonConfig Config { get; } + /// + /// 所属地牢组 + /// + public DungeonRoomGroup RoomGroup { get; } + + /// /// 随机数对象 /// - private SeedRandom _random; + public SeedRandom Random; //用于标记地图上的坐标是否被占用 private InfiniteGrid _roomGrid { get; } = new InfiniteGrid(); @@ -73,9 +82,8 @@ private int _maxTryCount = 10; private int _currMaxLayer = 0; - //地牢配置 - private DungeonConfig _config; - private DungeonRoomGroup _roomGroup; + //地牢房间规则处理类 + private DungeonRule _rule; private enum GenerateRoomErrorCode { @@ -92,9 +100,9 @@ public DungeonGenerator(DungeonConfig config, SeedRandom seedRandom) { - _config = config; - _random = seedRandom; - _roomGroup = GameApplication.Instance.RoomConfig[config.GroupName]; + Config = config; + Random = seedRandom; + RoomGroup = GameApplication.Instance.RoomConfig[config.GroupName]; //验证该组是否满足生成地牢的条件 var result = DungeonManager.CheckDungeon(config.GroupName); @@ -103,8 +111,8 @@ throw new Exception("当前组'" + config.GroupName + "'" + result.ErrorMessage + ", 不能生成地牢!"); } - Debug.Log("创建地牢生成器, 随机种子: " + _random.Seed); - _roomGroup.InitWeight(_random); + Debug.Log("创建地牢生成器, 随机种子: " + Random.Seed); + RoomGroup.InitWeight(Random); } /// @@ -154,9 +162,10 @@ /// /// 生成房间 /// - public bool Generate() + public bool Generate(DungeonRule rule) { if (StartRoomInfo != null) return false; + _rule = rule; CalcNextRoomType(null); //用于排除上一级房间 @@ -174,7 +183,7 @@ var currTryCount = 0; //如果房间数量不够, 就一直生成 - while (_count < _config.RoomCount || EndRoomInfo == null) + while (_count < Config.BattleRoomCount || EndRoomInfo == null) { var nextRoomType = GetNextRoomType(); @@ -188,11 +197,7 @@ { tempPrevRoomInfo = FindMaxLayerRoom(excludePrevRoom); } - else if (nextRoomType == DungeonRoomType.Outlet) - { - tempPrevRoomInfo = prevRoomInfo; - } - else if (nextRoomType == DungeonRoomType.Reward) + else if (nextRoomType == DungeonRoomType.Outlet || nextRoomType == DungeonRoomType.Reward || nextRoomType == DungeonRoomType.Shop || nextRoomType == DungeonRoomType.Event) { tempPrevRoomInfo = prevRoomInfo; } @@ -211,12 +216,12 @@ } else { - tempPrevRoomInfo = _random.RandomChoose(RoomInfos); + tempPrevRoomInfo = Random.RandomChoose(RoomInfos); } } else { - tempPrevRoomInfo = _random.RandomChoose(RoomInfos); + tempPrevRoomInfo = Random.RandomChoose(RoomInfos); } //生成下一个房间 @@ -241,7 +246,7 @@ else if (nextRoomType == DungeonRoomType.Battle) { chainTryCount = 0; - chainMaxTryCount = _random.RandomRangeInt(1, 3); + chainMaxTryCount = Random.RandomRangeInt(1, 3); } prevRoomInfo = nextRoom; CalcNextRoomType(prevRoomInfo); @@ -313,21 +318,21 @@ // } DungeonRoomSplit roomSplit; - if (_config.HasDesignatedRoom && _config.DesignatedType == roomType) //执行指定了房间 + if (Config.HasDesignatedRoom && Config.DesignatedType == roomType) //执行指定了房间 { - roomSplit = _random.RandomChoose(_config.DesignatedRoom); + roomSplit = Random.RandomChoose(Config.DesignatedRoom); } else //没有指定房间 { //随机选择一个房间 - var list = _roomGroup.GetRoomList(roomType); + var list = RoomGroup.GetRoomList(roomType); if (list.Count == 0) //如果没有指定类型的房间, 就生成战斗房间 { - roomSplit = _roomGroup.GetRandomRoom(DungeonRoomType.Battle); + roomSplit = RoomGroup.GetRandomRoom(DungeonRoomType.Battle); } else { - roomSplit = _roomGroup.GetRandomRoom(roomType); + roomSplit = RoomGroup.GetRandomRoom(roomType); } } @@ -357,9 +362,9 @@ for (; tryCount < maxTryCount; tryCount++) { //下一个房间方向 - var direction = _random.RandomRangeInt(0, 3); + var direction = Random.RandomRangeInt(0, 3); //房间间隔 - var space = _random.RandomRangeInt(_roomMinInterval, _roomMaxInterval); + var space = Random.RandomRangeInt(_roomMinInterval, _roomMaxInterval); if (direction == 0 || direction == 2) { space += 1; @@ -368,12 +373,12 @@ int offset; if (direction == 0 || direction == 2) { - offset = _random.RandomRangeInt((int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion), + offset = Random.RandomRangeInt((int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion), (int)(prevRoomInfo.Size.X * _roomVerticalMaxDispersion)); } else { - offset = _random.RandomRangeInt((int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion), + offset = Random.RandomRangeInt((int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion), (int)(prevRoomInfo.Size.Y * _roomHorizontalMaxDispersion)); } @@ -478,11 +483,11 @@ { _nextRoomType = DungeonRoomType.Reward; } - else if (_count == _config.RoomCount - 1) //最后一个房间是boss房间 + else if (_count == Config.BattleRoomCount - 1) //最后一个房间是boss房间 { _nextRoomType = DungeonRoomType.Boss; } - else if (_count >= _config.RoomCount) //结束房间 + else if (_count >= Config.BattleRoomCount) //结束房间 { _nextRoomType = DungeonRoomType.Outlet; } @@ -577,7 +582,7 @@ } } - return _random.RandomChoose(list); + return Random.RandomChoose(list); } /// @@ -597,7 +602,7 @@ nextRoomDoor.ConnectDoor = roomDoor; //先寻找直通门 - if (_random.RandomBoolean()) + if (Random.RandomBoolean()) { //直行通道, 优先横轴 if (TryConnectHorizontalDoor(roomInfo, roomDoor, nextRoomInfo, nextRoomDoor) @@ -637,8 +642,8 @@ while (rangeList.Count > 0) { //找到重叠区域 - var range = _random.RandomChooseAndRemove(rangeList); - var x = _random.RandomRangeInt(range.X, range.Y) + 2; + var range = Random.RandomChooseAndRemove(rangeList); + var x = Random.RandomRangeInt(range.X, range.Y) + 2; if (roomInfo.GetVerticalStart() < nextRoomInfo.GetVerticalStart()) //room在上, nextRoom在下 { @@ -689,8 +694,8 @@ while (rangeList.Count > 0) { //找到重叠区域 - var range = _random.RandomChooseAndRemove(rangeList); - var y = _random.RandomRangeInt(range.X, range.Y) + 3; + var range = Random.RandomChooseAndRemove(rangeList); + var y = Random.RandomRangeInt(range.X, range.Y) + 3; if (roomInfo.GetHorizontalStart() < nextRoomInfo.GetHorizontalStart()) //room在左, nextRoom在右 { @@ -736,7 +741,7 @@ { if (roomInfo.GetVerticalStart() > nextRoomInfo.GetVerticalStart()) { - if (_random.RandomBoolean()) //↑ //→ + if (Random.RandomBoolean()) //↑ //→ { if (!TryConnect_NE_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) && !TryConnect_WS_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross)) @@ -755,7 +760,7 @@ } else { - if (_random.RandomBoolean()) //↓ //→ + if (Random.RandomBoolean()) //↓ //→ { if (!TryConnect_SE_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) && !TryConnect_WN_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross)) @@ -777,7 +782,7 @@ { if (roomInfo.GetVerticalStart() > nextRoomInfo.GetVerticalStart()) //→ //↓ { - if (_random.RandomBoolean()) + if (Random.RandomBoolean()) { if (!TryConnect_ES_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) && !TryConnect_NW_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross)) @@ -796,7 +801,7 @@ } else { - if (_random.RandomBoolean()) //→ //↑ + if (Random.RandomBoolean()) //→ //↑ { if (!TryConnect_EN_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross) && !TryConnect_SW_Door(roomInfo, nextRoomInfo, roomDoor, nextRoomDoor, ref cross)) diff --git a/DungeonShooting_Godot/src/framework/map/DungeonRule.cs b/DungeonShooting_Godot/src/framework/map/DungeonRule.cs new file mode 100644 index 0000000..c4d7238 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/map/DungeonRule.cs @@ -0,0 +1,24 @@ + +/// +/// 用于自定义地牢房间生成规则 +/// +public abstract class DungeonRule +{ + public DungeonGenerator Generator { get; } + + public DungeonConfig Config { get; } + + public SeedRandom Random { get; } + + public DungeonRule(DungeonGenerator generator) + { + Generator = generator; + Config = generator.Config; + Random = generator.Random; + } + + /// + /// 计算下一个房间类型 + /// + public abstract DungeonRoomType CalcNextRoomType(RoomInfo prev); +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index 9e97a76..32add5e 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -106,7 +106,7 @@ DungeonConfig = new DungeonConfig(); DungeonConfig.GroupName = "Test1"; - DungeonConfig.RoomCount = 20; + DungeonConfig.BattleRoomCount = 20; } public override void _EnterTree() diff --git a/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs b/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs new file mode 100644 index 0000000..601ad26 --- /dev/null +++ b/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs @@ -0,0 +1,15 @@ + +/// +/// 默认实现地牢房间规则 +/// +public class DefaultDungeonRule : DungeonRule +{ + public DefaultDungeonRule(DungeonGenerator generator) : base(generator) + { + } + + public override DungeonRoomType CalcNextRoomType(RoomInfo prev) + { + return DungeonRoomType.Battle; + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 032bc8d..3a8f4c8 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -198,7 +198,8 @@ //生成地牢房间 var random = new SeedRandom(); _dungeonGenerator = new DungeonGenerator(CurrConfig, random); - if (!_dungeonGenerator.Generate()) //生成房间失败 + var rule = new DefaultDungeonRule(_dungeonGenerator); + if (!_dungeonGenerator.Generate(rule)) //生成房间失败 { _dungeonGenerator.EachRoom(DisposeRoomInfo); _dungeonGenerator = null;