diff --git a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs index 97d599e..f05f144 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonConfig.cs @@ -46,6 +46,51 @@ /// public int MaxLayer = 5; + /// + /// 房间最小间隔 + /// + public int RoomMinInterval = 2; + + /// + /// 房间最大间隔 + /// + public int RoomMaxInterval = 5; + + /// + /// 房间横轴最小分散程度 + /// + public float RoomHorizontalMinDispersion = -0.6f; + + /// + /// 房间横轴最大分散程度 + /// + public float RoomHorizontalMaxDispersion = 0.6f; + + /// + /// 房间纵轴最小分散程度 + /// + public float RoomVerticalMinDispersion = -0.6f; + + /// + /// 房间纵轴最大分散程度 + /// + public float RoomVerticalMaxDispersion = 0.6f; + + /// + /// 是否启用区域限制 + /// + public bool EnableLimitRange = true; + + /// + /// 横轴范围 + /// + public int RangeX = 120; + + /// + /// 纵轴范围 + /// + public int RangeY = 120; + //----------------------- 地牢编辑使用 ------------------------- /// /// 是否指定了房间 diff --git a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs index a173308..b9b8ad9 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonGenerator.cs @@ -67,20 +67,7 @@ //下一个房间类型 private DungeonRoomType _nextRoomType = DungeonRoomType.None; - //间隔 - private int _roomMinInterval = 2; - private int _roomMaxInterval = 5; - - //房间横轴分散程度 - private float _roomHorizontalMinDispersion = -0.6f; - private float _roomHorizontalMaxDispersion = 0.6f; - - //房间纵轴分散程度 - private float _roomVerticalMinDispersion = -0.6f; - private float _roomVerticalMaxDispersion = 0.6f; - //区域限制 - private bool _enableLimitRange = true; private int _rangeX = 120; private int _rangeY = 120; @@ -104,6 +91,8 @@ Config = config; Random = seedRandom; RoomGroup = GameApplication.Instance.RoomConfig[config.GroupName]; + _rangeX = config.RangeX; + _rangeY = config.RangeY; //验证该组是否满足生成地牢的条件 var result = DungeonManager.CheckDungeon(config.GroupName); @@ -254,7 +243,7 @@ } //生成房间 - private GenerateRoomErrorCode GenerateRoom(RoomInfo prevRoomInfo, DungeonRoomType roomType, out RoomInfo resultRoomInfo) + private GenerateRoomErrorCode GenerateRoom(RoomInfo prevRoom, DungeonRoomType roomType, out RoomInfo resultRoomInfo) { // if (_count >= _config.RoomCount) // { @@ -286,9 +275,9 @@ //房间大小 room.Size = new Vector2I((int)roomSplit.RoomInfo.Size.X, (int)roomSplit.RoomInfo.Size.Y); - if (prevRoomInfo != null) //表示这不是第一个房间, 就得判断当前位置下的房间是否被遮挡 + if (prevRoom != null) //表示这不是第一个房间, 就得判断当前位置下的房间是否被遮挡 { - room.Layer = prevRoomInfo.Layer + 1; + room.Layer = prevRoom.Layer + 1; if (_currMaxLayer < room.Layer) { _currMaxLayer = room.Layer; @@ -307,50 +296,40 @@ for (; tryCount < maxTryCount; tryCount++) { //下一个房间方向 - var direction = Random.RandomRangeInt(0, 3); + var direction = _rule.GetNextRoomDoorDirection(prevRoom, roomType); //房间间隔 - var space = Random.RandomRangeInt(_roomMinInterval, _roomMaxInterval); - if (direction == 0 || direction == 2) + var space = _rule.GetNextRoomInterval(prevRoom, roomType, direction); + if (direction == RoomDirection.Up || direction == RoomDirection.Down) { space += 1; } //中心偏移 - int offset; - if (direction == 0 || direction == 2) - { - offset = Random.RandomRangeInt((int)(prevRoomInfo.Size.X * _roomVerticalMinDispersion), - (int)(prevRoomInfo.Size.X * _roomVerticalMaxDispersion)); - } - else - { - offset = Random.RandomRangeInt((int)(prevRoomInfo.Size.Y * _roomHorizontalMinDispersion), - (int)(prevRoomInfo.Size.Y * _roomHorizontalMaxDispersion)); - } + var offset = _rule.GetNextRoomOffset(prevRoom, roomType, direction); //计算房间位置 - if (direction == 0) //上 + if (direction == RoomDirection.Up) //上 { - room.Position = new Vector2I(prevRoomInfo.Position.X + offset, - prevRoomInfo.Position.Y - room.Size.Y - space); + room.Position = new Vector2I(prevRoom.Position.X + offset, + prevRoom.Position.Y - room.Size.Y - space); } - else if (direction == 1) //右 + else if (direction == RoomDirection.Right) //右 { - room.Position = new Vector2I(prevRoomInfo.Position.X + prevRoomInfo.Size.Y + space, - prevRoomInfo.Position.Y + offset); + room.Position = new Vector2I(prevRoom.Position.X + prevRoom.Size.Y + space, + prevRoom.Position.Y + offset); } - else if (direction == 2) //下 + else if (direction == RoomDirection.Down) //下 { - room.Position = new Vector2I(prevRoomInfo.Position.X + offset, - prevRoomInfo.Position.Y + prevRoomInfo.Size.Y + space); + room.Position = new Vector2I(prevRoom.Position.X + offset, + prevRoom.Position.Y + prevRoom.Size.Y + space); } - else if (direction == 3) //左 + else if (direction == RoomDirection.Left) //左 { - room.Position = new Vector2I(prevRoomInfo.Position.X - room.Size.X - space, - prevRoomInfo.Position.Y + offset); + room.Position = new Vector2I(prevRoom.Position.X - room.Size.X - space, + prevRoom.Position.Y + offset); } //是否在限制区域内 - if (_enableLimitRange) + if (Config.EnableLimitRange) { if (room.GetHorizontalStart() < -_rangeX || room.GetHorizontalEnd() > _rangeX || room.GetVerticalStart() < -_rangeY || room.GetVerticalEnd() > _rangeY) @@ -372,7 +351,7 @@ _roomGrid.SetRect(room.Position, room.Size, true); //找门, 与上一个房间是否能连通 - if (!ConnectDoor(prevRoomInfo, room)) + if (!ConnectDoor(prevRoom, room)) { _roomGrid.RemoveRect(room.Position, room.Size); //Debug.Log("链接通道失败"); @@ -397,10 +376,10 @@ } _id++; - room.Prev = prevRoomInfo; - if (prevRoomInfo != null) + room.Prev = prevRoom; + if (prevRoom != null) { - prevRoomInfo.Next.Add(room); + prevRoom.Next.Add(room); } resultRoomInfo = room; return GenerateRoomErrorCode.NoError; diff --git a/DungeonShooting_Godot/src/framework/map/DungeonRule.cs b/DungeonShooting_Godot/src/framework/map/DungeonRule.cs index b4423d4..91cb309 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonRule.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonRule.cs @@ -26,22 +26,39 @@ public abstract bool CanOverGenerator(); /// - /// 获取指定房间类型与之相连的上一个房间对象 + /// 获取指定房间类型与之相连的上一个房间对象, prevRoom 可能为 null /// - public abstract RoomInfo GetConnectPrevRoom(RoomInfo prevRoomInfo, DungeonRoomType nextRoomType); + public abstract RoomInfo GetConnectPrevRoom(RoomInfo prevRoom, DungeonRoomType nextRoomType); /// - /// 计算下一个房间类型 + /// 计算下一个房间类型, prevRoom 可能为 null /// - public abstract DungeonRoomType GetNextRoomType(RoomInfo prevRoomInfo); + public abstract DungeonRoomType GetNextRoomType(RoomInfo prevRoom); /// - /// 执行生成指定房间成功 + /// 执行生成指定房间成功, prevRoom 可能为 null /// - public abstract void GenerateRoomSuccess(RoomInfo prevRoomInfo, RoomInfo roomInfo); + public abstract void GenerateRoomSuccess(RoomInfo prevRoom, RoomInfo roomInfo); /// - /// 执行生成指定类型房间失败 + /// 执行生成指定类型房间失败, prevRoom 可能为 null /// - public abstract void GenerateRoomFail(RoomInfo prevRoomInfo, DungeonRoomType roomType); + public abstract void GenerateRoomFail(RoomInfo prevRoom, DungeonRoomType roomType); + + //-------------------------- 下面的函数 prevRoom 一定不会为 null -------------------------- + + /// + /// 获取下一个房间的方向, prevRoom 一定不为 null + /// + public abstract RoomDirection GetNextRoomDoorDirection(RoomInfo prevRoom, DungeonRoomType roomType); + + /// + /// 获取下一个房间的间隔距离, prevRoom 一定不为 null + /// + public abstract int GetNextRoomInterval(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction); + + /// + /// 获取下一个房间相对于当前房间的原点偏移 (单位: 格), prevRoom 一定不为 null + /// + public abstract int GetNextRoomOffset(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction); } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/RoomDirection.cs b/DungeonShooting_Godot/src/framework/map/RoomDirection.cs new file mode 100644 index 0000000..0befbc9 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/map/RoomDirection.cs @@ -0,0 +1,11 @@ + +/// +/// 生成房间的方向 +/// +public enum RoomDirection +{ + Up, + Down, + Left, + Right +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index 5fd28f9..7d82ea4 100644 --- a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs +++ b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs @@ -61,7 +61,7 @@ ActivePropsPack.SetCapacity(1); // debug用 - DebugSet(); + //DebugSet(); //注册状态机 StateController.Register(new PlayerIdleState()); diff --git a/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs b/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs index 2b75d05..8820212 100644 --- a/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs +++ b/DungeonShooting_Godot/src/game/room/DefaultDungeonRule.cs @@ -17,6 +17,8 @@ //结束房间尝试链接次数 private int outletTryCount = 0; + private readonly RoomDirection[] _roomDirections = new []{ RoomDirection.Up, RoomDirection.Down, RoomDirection.Left, RoomDirection.Right }; + public DefaultDungeonRule(DungeonGenerator generator) : base(generator) { } @@ -26,7 +28,7 @@ return Generator.BattleRoomInfos.Count >= Config.BattleRoomCount && Generator.EndRoomInfos.Count > 0; } - public override RoomInfo GetConnectPrevRoom(RoomInfo prevRoomInfo, DungeonRoomType nextRoomType) + public override RoomInfo GetConnectPrevRoom(RoomInfo prevRoom, DungeonRoomType nextRoomType) { if (nextRoomType == DungeonRoomType.Inlet) { @@ -38,25 +40,25 @@ } else if (nextRoomType == DungeonRoomType.Outlet || nextRoomType == DungeonRoomType.Reward || nextRoomType == DungeonRoomType.Shop || nextRoomType == DungeonRoomType.Event) { - return prevRoomInfo; + return prevRoom; } else if (nextRoomType == DungeonRoomType.Battle) { if (battleTryCount < battleMaxTryCount) { - if (prevRoomInfo != null && prevRoomInfo.Layer >= Config.MaxLayer - 1) //层数太高, 下一个房间生成在低层级 + if (prevRoom != null && prevRoom.Layer >= Config.MaxLayer - 1) //层数太高, 下一个房间生成在低层级 { return Generator.RandomRoomLessThanLayer(Mathf.Max(1, Config.MaxLayer / 2)); } - return prevRoomInfo; + return prevRoom; } } return Generator.GetRandomRoom(); } - public override DungeonRoomType GetNextRoomType(RoomInfo prevRoomInfo) + public override DungeonRoomType GetNextRoomType(RoomInfo prevRoom) { if (Generator.StartRoomInfo == null) //生成第一个房间 { @@ -66,7 +68,7 @@ // { // return DungeonRoomType.Reward; // } - else if (prevRoomInfo.RoomType == DungeonRoomType.Boss) //boss房间后生成结束房间 + else if (prevRoom.RoomType == DungeonRoomType.Boss) //boss房间后生成结束房间 { return DungeonRoomType.Outlet; } @@ -85,7 +87,7 @@ return DungeonRoomType.Battle; } - public override void GenerateRoomSuccess(RoomInfo prevRoomInfo, RoomInfo roomInfo) + public override void GenerateRoomSuccess(RoomInfo prevRoom, RoomInfo roomInfo) { if (roomInfo.RoomType == DungeonRoomType.Boss) //boss房间 { @@ -103,18 +105,18 @@ Generator.SubmitCanRollbackRoom(); } - if (prevRoomInfo != null && prevRoomInfo.CanRollback) + if (prevRoom != null && prevRoom.CanRollback) { roomInfo.CanRollback = true; } } - public override void GenerateRoomFail(RoomInfo prevRoomInfo, DungeonRoomType roomType) + public override void GenerateRoomFail(RoomInfo prevRoom, DungeonRoomType roomType) { if (roomType == DungeonRoomType.Boss) { //生成boss房间成功 - excludePrevRoom.Add(prevRoomInfo); + excludePrevRoom.Add(prevRoom); if (excludePrevRoom.Count >= Generator.RoomInfos.Count) { //全都没找到合适的, 那就再来一遍 @@ -124,10 +126,10 @@ else if (roomType == DungeonRoomType.Outlet) { outletTryCount++; - if (outletTryCount >= 3 && prevRoomInfo != null) //生成结束房间失败, 那么只能回滚boss房间 + if (outletTryCount >= 3 && prevRoom != null) //生成结束房间失败, 那么只能回滚boss房间 { outletTryCount = 0; - Generator.RollbackRoom(prevRoomInfo); + Generator.RollbackRoom(prevRoom); } } else if (roomType == DungeonRoomType.Battle) @@ -135,4 +137,35 @@ battleTryCount++; } } + + public override RoomDirection GetNextRoomDoorDirection(RoomInfo prevRoom, DungeonRoomType roomType) + { + return Random.RandomChoose(_roomDirections); + } + + public override int GetNextRoomInterval(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction) + { + return Random.RandomRangeInt(Config.RoomMinInterval, Config.RoomMaxInterval); + } + + public override int GetNextRoomOffset(RoomInfo prevRoom, DungeonRoomType roomType, RoomDirection direction) + { + //为什么最后的值要减4或者5? 因为这个值是房间地板向外扩充的格子数量 + + if (roomType == DungeonRoomType.Outlet) + { + if (direction == RoomDirection.Up || direction == RoomDirection.Down) + { + return (int)(prevRoom.Size.X * 0.5f - 4); + } + return (int)(prevRoom.Size.Y * 0.5f - 5); + } + if (direction == RoomDirection.Up || direction == RoomDirection.Down) + { + return Random.RandomRangeInt((int)(prevRoom.Size.X * Config.RoomVerticalMinDispersion), + (int)(prevRoom.Size.X * Config.RoomVerticalMaxDispersion)) + (int)(prevRoom.Size.X * 0.5f - 4); + } + return Random.RandomRangeInt((int)(prevRoom.Size.Y * Config.RoomHorizontalMinDispersion), + (int)(prevRoom.Size.Y * Config.RoomHorizontalMaxDispersion)) + (int)(prevRoom.Size.Y * 0.5f - 5); + } } \ No newline at end of file