diff --git a/DungeonShooting_Godot/prefab/ui/MapEditor.tscn b/DungeonShooting_Godot/prefab/ui/MapEditor.tscn index 144e166..7e28155 100644 --- a/DungeonShooting_Godot/prefab/ui/MapEditor.tscn +++ b/DungeonShooting_Godot/prefab/ui/MapEditor.tscn @@ -10,14 +10,9 @@ [ext_resource type="PackedScene" uid="uid://b4u66mxndxbrg" path="res://prefab/ui/MapEditorTools.tscn" id="6_7pvgu"] [ext_resource type="PackedScene" uid="uid://bb2ekkpxifd7g" path="res://prefab/ui/MapEditorMapLayer.tscn" id="7_ychtn"] [ext_resource type="PackedScene" uid="uid://peo0n8bl15y5" path="res://prefab/ui/MapEditorMapMark.tscn" id="8_8tgeu"] +[ext_resource type="NavigationPolygon" uid="uid://brpcle7mygiml" path="res://resource/navigation/NavigationPolygon.tres" id="8_t7nq5"] [ext_resource type="PackedScene" uid="uid://tjbfj67t5akm" path="res://prefab/ui/MapEditorMapTile.tscn" id="10_4fu5v"] -[sub_resource type="NavigationPolygon" id="NavigationPolygon_oidah"] -resource_local_to_scene = true -source_geometry_mode = 1 -source_geometry_group_name = &"navigation" -cell_size = 4.0 - [sub_resource type="Animation" id="Animation_o3btm"] length = 0.001 tracks/0/type = "value" @@ -230,7 +225,7 @@ [node name="NavigationRegion" type="NavigationRegion2D" parent="Bg/VBoxContainer/HSplitContainer/HSplitContainer2/HBoxContainer/Left/MarginContainer/MapView/SubViewport/TileMap"] z_index = 10 -navigation_polygon = SubResource("NavigationPolygon_oidah") +navigation_polygon = ExtResource("8_t7nq5") [node name="ErrorCell" type="Sprite2D" parent="Bg/VBoxContainer/HSplitContainer/HSplitContainer2/HBoxContainer/Left/MarginContainer/MapView/SubViewport/TileMap"] visible = false @@ -285,7 +280,6 @@ [node name="MapEditorMapTile" parent="Bg/VBoxContainer/HSplitContainer/HSplitContainer2/Right/MarginContainer/TabContainer/MapTile" instance=ExtResource("10_4fu5v")] layout_mode = 2 -Layer = 1 [node name="MapMark" type="MarginContainer" parent="Bg/VBoxContainer/HSplitContainer/HSplitContainer2/Right/MarginContainer/TabContainer"] visible = false diff --git a/DungeonShooting_Godot/prefab/ui/MapEditorMapTile.tscn b/DungeonShooting_Godot/prefab/ui/MapEditorMapTile.tscn index 64027e4..49c7fd0 100644 --- a/DungeonShooting_Godot/prefab/ui/MapEditorMapTile.tscn +++ b/DungeonShooting_Godot/prefab/ui/MapEditorMapTile.tscn @@ -16,7 +16,6 @@ grow_horizontal = 2 grow_vertical = 2 script = ExtResource("1_gtth6") -Layer = null [node name="VBoxContainer" type="VBoxContainer" parent="."] layout_mode = 1 diff --git a/DungeonShooting_Godot/prefab/ui/Setting.tscn b/DungeonShooting_Godot/prefab/ui/Setting.tscn index d0eb890..1ecf5f0 100644 --- a/DungeonShooting_Godot/prefab/ui/Setting.tscn +++ b/DungeonShooting_Godot/prefab/ui/Setting.tscn @@ -1,7 +1,7 @@ [gd_scene load_steps=3 format=3 uid="uid://bnwweusrc44xy"] [ext_resource type="Script" path="res://src/game/ui/setting/SettingPanel.cs" id="1_ff0oi"] -[ext_resource type="Texture2D" uid="uid://bd0kpqji660ta" path="res://resource/sprite/ui/commonIcon/Back.png" id="2_vgl60"] +[ext_resource type="Texture2D" uid="uid://cajcnlimvoxk" path="res://resource/sprite/ui/commonIcon/Back.png" id="2_vgl60"] [node name="Setting" type="Control"] layout_mode = 3 @@ -315,7 +315,7 @@ [node name="Value" type="Label" parent="ScrollContainer/KeySetting/Key14"] layout_mode = 2 -text = "Ctrl" +text = "Shift" [node name="Back" type="Button" parent="ScrollContainer/KeySetting"] layout_mode = 2 diff --git a/DungeonShooting_Godot/project.godot b/DungeonShooting_Godot/project.godot index 45426b8..b62f34d 100644 --- a/DungeonShooting_Godot/project.godot +++ b/DungeonShooting_Godot/project.godot @@ -210,7 +210,7 @@ } map={ "deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194326,"key_label":0,"unicode":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194325,"key_label":0,"unicode":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null) ] } diff --git a/DungeonShooting_Godot/resource/navigation/NavigationPolygon.tres b/DungeonShooting_Godot/resource/navigation/NavigationPolygon.tres new file mode 100644 index 0000000..2027580 --- /dev/null +++ b/DungeonShooting_Godot/resource/navigation/NavigationPolygon.tres @@ -0,0 +1,7 @@ +[gd_resource type="NavigationPolygon" format=3 uid="uid://brpcle7mygiml"] + +[resource] +resource_local_to_scene = true +source_geometry_mode = 1 +source_geometry_group_name = &"navigation" +cell_size = 4.0 diff --git a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs index 18371c0..e463ddf 100644 --- a/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs +++ b/DungeonShooting_Godot/src/framework/coroutine/ProxyCoroutineHandler.cs @@ -23,8 +23,8 @@ for (var i = 0; i < pairs.Length; i++) { var item = pairs[i]; - try - { + // try + // { var canNext = true; if (item.WaitState == CoroutineData.WaitTypeEnum.WaitForSeconds) //等待秒数 @@ -130,12 +130,12 @@ } } } - } - catch (Exception e) - { - Debug.LogError("执行协程发生异常: \n" + e); - ProxyStopCoroutine(ref coroutineList, item.Id); - } + // } + // catch (Exception e) + // { + // Debug.LogError("执行协程发生异常: \n" + e); + // ProxyStopCoroutine(ref coroutineList, item.Id); + // } } } diff --git a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs index fdc459f..5bf491c 100644 --- a/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs +++ b/DungeonShooting_Godot/src/framework/map/DungeonTileMap.cs @@ -9,26 +9,10 @@ /// public class DungeonTileMap { - //--------------------- 导航 ------------------------- - - //已经标记过的点 - private readonly HashSet _usePoints = new HashSet(); - - //导航区域数据 - private readonly List _polygonDataList = new List(); - - //连接门的导航区域 - private readonly List _connectNavigationItemList = new List(); //---------------------------------------------------- private TileMap _tileRoot; - //地面地砖在 Atlas 的位置 - private List _floorAtlasCoords; - //生成导航的结果 - private GenerateNavigationResult _generateNavigationResult; - - private InfiniteGrid _tempAisleFloorGrid = new InfiniteGrid(); public DungeonTileMap(TileMap tileRoot) { @@ -36,14 +20,21 @@ } /// - /// 根据 startRoom 和 config 数据自动填充 tileMap 参数中的地图数据, 该函数为协程函数 + /// 根据 startRoom 和 config 数据自动填充 tileMap 参数中的房间数据, 该函数为协程函数 /// public IEnumerator AutoFillRoomTile(AutoTileConfig config, RoomInfo startRoomInfo, World world) { - _connectNavigationItemList.Clear(); yield return _AutoFillRoomTile(config, startRoomInfo, world); } + /// + /// 根据 startRoom 和 config 数据自动填充 tileMap 参数中的过道数据, 该函数为协程函数 + /// + public IEnumerator AutoFillAisleTile(AutoTileConfig config, RoomInfo roomInfo, World world) + { + yield return _AutoFillAisleTile(config, roomInfo, world); + } + private IEnumerator _AutoFillRoomTile(AutoTileConfig config, RoomInfo roomInfo, World world) { foreach (var info in roomInfo.Next) @@ -52,114 +43,98 @@ } //铺房间 - if (roomInfo.RoomSplit == null) //自动填充的矩形房间, 现已经弃用 + var rectPos = roomInfo.RoomSplit.RoomInfo.Position.AsVector2I(); + var tileInfo = roomInfo.RoomSplit.TileInfo; + + //---------------------- 生成房间小地图预览 ---------------------- + //先计算范围 + var x = int.MaxValue; + var y = int.MaxValue; + var x2 = int.MinValue; + var y2 = int.MinValue; + for (var i = 0; i < tileInfo.Floor.Count; i += 4) { - FillRect(MapLayer.AutoFloorLayer, config.Floor, roomInfo.Position + Vector2.One, - roomInfo.Size - new Vector2(2, 2)); - - FillRect(MapLayer.AutoTopLayer, config.Wall_In_LT, roomInfo.Position, Vector2.One); - FillRect(MapLayer.AutoTopLayer, config.Wall_Left, roomInfo.Position + new Vector2(0, 1), - new Vector2(1, roomInfo.Size.Y - 2)); - FillRect(MapLayer.AutoTopLayer, config.Wall_In_LB, roomInfo.Position + new Vector2(0, roomInfo.Size.Y - 1), - new Vector2(1, 1)); - FillRect(MapLayer.AutoTopLayer, config.Wall_Bottom, roomInfo.Position + new Vector2(1, roomInfo.Size.Y - 1), - new Vector2(roomInfo.Size.X - 2, 1)); - FillRect(MapLayer.AutoTopLayer, config.Wall_In_RB, - roomInfo.Position + new Vector2(roomInfo.Size.X - 1, roomInfo.Size.Y - 1), - Vector2.One); - FillRect(MapLayer.AutoTopLayer, config.Wall_Right, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, 1), - new Vector2(1, roomInfo.Size.Y - 2)); - FillRect(MapLayer.AutoTopLayer, config.Wall_In_RT, roomInfo.Position + new Vector2(roomInfo.Size.X - 1, 0), - Vector2.One); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Top, roomInfo.Position + Vector2.Right, - new Vector2(roomInfo.Size.X - 2, 1)); + var posX = tileInfo.Floor[i]; + var posY = tileInfo.Floor[i + 1]; + x = Mathf.Min(x, posX); + x2 = Mathf.Max(x2, posX); + y = Mathf.Min(y, posY); + y2 = Mathf.Max(y2, posY); } - else + //创建image, 这里留两个像素宽高用于描边 + var image = Image.Create(x2 - x + 3, y2 - y + 3, false, Image.Format.Rgba8); + //image.Fill(Colors.Green); + //填充像素点 + for (var i = 0; i < tileInfo.Floor.Count; i += 4) { - var rectPos = roomInfo.RoomSplit.RoomInfo.Position.AsVector2I(); - var tileInfo = roomInfo.RoomSplit.TileInfo; - - //---------------------- 生成房间小地图预览 ---------------------- - //先计算范围 - var x = int.MaxValue; - var y = int.MaxValue; - var x2 = int.MinValue; - var y2 = int.MinValue; - for (var i = 0; i < tileInfo.Floor.Count; i += 4) - { - var posX = tileInfo.Floor[i]; - var posY = tileInfo.Floor[i + 1]; - x = Mathf.Min(x, posX); - x2 = Mathf.Max(x2, posX); - y = Mathf.Min(y, posY); - y2 = Mathf.Max(y2, posY); - } - //创建image, 这里留两个像素宽高用于描边 - var image = Image.Create(x2 - x + 3, y2 - y + 3, false, Image.Format.Rgba8); - //image.Fill(Colors.Green); - //填充像素点 - for (var i = 0; i < tileInfo.Floor.Count; i += 4) - { - var posX = tileInfo.Floor[i] - x + 1; - var posY = tileInfo.Floor[i + 1] - y + 1; - image.SetPixel(posX, posY, new Color(0, 0, 0, 0.5882353F)); - } - //创建texture - var imageTexture = ImageTexture.CreateFromImage(image); - roomInfo.PreviewTexture = imageTexture; - - //---------------------- 填充tile操作 ---------------------- - var terrainInfo = config.TerrainInfo; - - SetAutoLayerDataFromList(MapLayer.AutoFloorLayer, config.SourceId, roomInfo, tileInfo.Floor, rectPos, terrainInfo); - SetCustomLayerDataFromList(MapLayer.CustomFloorLayer1, roomInfo, tileInfo.CustomFloor1, rectPos); - SetCustomLayerDataFromList(MapLayer.CustomFloorLayer2, roomInfo, tileInfo.CustomFloor2, rectPos); - SetCustomLayerDataFromList(MapLayer.CustomFloorLayer3, roomInfo, tileInfo.CustomFloor3, rectPos); - SetAutoLayerDataFromList(MapLayer.AutoMiddleLayer, config.SourceId, roomInfo, tileInfo.Middle, rectPos, terrainInfo); - SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer1, roomInfo, tileInfo.CustomMiddle1, rectPos); - SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer2, roomInfo, tileInfo.CustomMiddle2, rectPos); - SetAutoLayerDataFromList(MapLayer.AutoTopLayer, config.SourceId, roomInfo, tileInfo.Top, rectPos, terrainInfo); - SetCustomLayerDataFromList(MapLayer.CustomTopLayer, roomInfo, tileInfo.CustomTop, rectPos); - - //寻找可用传送点 - var maxCount = (roomInfo.Size.X - 2) * (roomInfo.Size.Y - 2); - var startPosition = roomInfo.Position + roomInfo.Size / 2; - for (int i = 0; i < maxCount; i++) - { - var pos = SpiralUtil.Screw(i) + startPosition; - if (IsWayTile(MapLayer.AutoFloorLayer, pos.X, pos.Y)) - { - roomInfo.Waypoints = pos; - break; - } - } - - //---------------------- 随机选择预设 ---------------------- - RoomPreinstallInfo preinstallInfo; - if (EditorPlayManager.IsPlay && roomInfo.RoomType == GameApplication.Instance.DungeonManager.CurrConfig.DesignatedType) //编辑器模式, 指定预设 - { - preinstallInfo = EditorTileMapManager.SelectPreinstall; - } - else //普通模式 - { - if (roomInfo.RoomSplit.Preinstall.Count == 1) - { - preinstallInfo = roomInfo.RoomSplit.Preinstall[0]; - } - else - { - var weights = roomInfo.RoomSplit.Preinstall.Select(info => info.Weight).ToArray(); - var index = world.Random.RandomWeight(weights); - preinstallInfo = roomInfo.RoomSplit.Preinstall[index]; - } - } - - var roomPreinstall = new RoomPreinstall(roomInfo, preinstallInfo); - roomInfo.RoomPreinstall = roomPreinstall; - //执行预处理操作 - roomPreinstall.Pretreatment(world); + var posX = tileInfo.Floor[i] - x + 1; + var posY = tileInfo.Floor[i + 1] - y + 1; + image.SetPixel(posX, posY, new Color(0, 0, 0, 0.5882353F)); } + //创建texture + var imageTexture = ImageTexture.CreateFromImage(image); + roomInfo.PreviewTexture = imageTexture; + //---------------------- 填充tile操作 ---------------------- + var terrainInfo = config.TerrainInfo; + + SetAutoLayerDataFromList(MapLayer.AutoFloorLayer, config.SourceId, roomInfo, tileInfo.Floor, rectPos, terrainInfo); + SetCustomLayerDataFromList(MapLayer.CustomFloorLayer1, roomInfo, tileInfo.CustomFloor1, rectPos); + SetCustomLayerDataFromList(MapLayer.CustomFloorLayer2, roomInfo, tileInfo.CustomFloor2, rectPos); + SetCustomLayerDataFromList(MapLayer.CustomFloorLayer3, roomInfo, tileInfo.CustomFloor3, rectPos); + //SetAutoLayerDataFromList(MapLayer.AutoMiddleLayer, config.SourceId, roomInfo, tileInfo.Middle, rectPos, terrainInfo); + SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer1, roomInfo, tileInfo.CustomMiddle1, rectPos); + SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer2, roomInfo, tileInfo.CustomMiddle2, rectPos); + //SetAutoLayerDataFromList(MapLayer.AutoTopLayer, config.SourceId, roomInfo, tileInfo.Top, rectPos, terrainInfo); + SetCustomLayerDataFromList(MapLayer.CustomTopLayer, roomInfo, tileInfo.CustomTop, rectPos); + + //寻找可用传送点 + var maxCount = (roomInfo.Size.X - 2) * (roomInfo.Size.Y - 2); + var startPosition = roomInfo.Position + roomInfo.Size / 2; + for (int i = 0; i < maxCount; i++) + { + var pos = SpiralUtil.Screw(i) + startPosition; + if (IsWayTile(MapLayer.AutoFloorLayer, pos.X, pos.Y)) + { + roomInfo.Waypoints = pos; + break; + } + } + + //---------------------- 随机选择预设 ---------------------- + RoomPreinstallInfo preinstallInfo; + if (EditorPlayManager.IsPlay && roomInfo.RoomType == GameApplication.Instance.DungeonManager.CurrConfig.DesignatedType) //编辑器模式, 指定预设 + { + preinstallInfo = EditorTileMapManager.SelectPreinstall; + } + else //普通模式 + { + if (roomInfo.RoomSplit.Preinstall.Count == 1) + { + preinstallInfo = roomInfo.RoomSplit.Preinstall[0]; + } + else + { + var weights = roomInfo.RoomSplit.Preinstall.Select(info => info.Weight).ToArray(); + var index = world.Random.RandomWeight(weights); + preinstallInfo = roomInfo.RoomSplit.Preinstall[index]; + } + } + + var roomPreinstall = new RoomPreinstall(roomInfo, preinstallInfo); + roomInfo.RoomPreinstall = roomPreinstall; + //执行预处理操作 + roomPreinstall.Pretreatment(world); + } + + + private IEnumerator _AutoFillAisleTile(AutoTileConfig config, RoomInfo roomInfo, World world) + { + foreach (var info in roomInfo.Next) + { + yield return _AutoFillAisleTile(config, info, world); + } + // yield break; //铺过道 foreach (var doorInfo in roomInfo.Doors) @@ -176,25 +151,32 @@ yield return 0; //创建image, 这里留两个像素宽高用于描边 - var image = Image.Create(doorInfo.FloorRect.Size.X, doorInfo.FloorRect.Size.Y, false, Image.Format.Rgba8); + var aisleImage = Image.Create(doorInfo.FloorRect.Size.X, doorInfo.FloorRect.Size.Y, false, Image.Format.Rgba8); //image.Fill(new Color(0, 1, 0, 0.2f)); //填充像素点 foreach (var p in doorInfo.FloorCell) { - //_tileRoot.SetCell(MapLayer.AutoAisleFloorLayer, p, config.Floor.SourceId, config.Floor.AutoTileCoords); - _tileRoot.SetCell(MapLayer.CustomTopLayer, p, config.Auto_000_010_000.SourceId, config.Auto_000_010_000.AutoTileCoords); - image.SetPixel(p.X - doorInfo.FloorRect.Position.X, p.Y - doorInfo.FloorRect.Position.Y, new Color(1, 1, 1, 0.5882353F)); + _tileRoot.SetCell(MapLayer.AutoFloorLayer, p, config.Floor.SourceId, config.Floor.AutoTileCoords); + //_tileRoot.SetCell(MapLayer.CustomTopLayer, p, config.Auto_000_010_000.SourceId, config.Auto_000_010_000.AutoTileCoords); + aisleImage.SetPixel(p.X - doorInfo.FloorRect.Position.X, p.Y - doorInfo.FloorRect.Position.Y, new Color(1, 1, 1, 0.5882353F)); } //创建texture - var imageTexture = ImageTexture.CreateFromImage(image); - doorInfo.AislePreviewTexture = imageTexture; - doorInfo.ConnectDoor.AislePreviewTexture = imageTexture; - - _tempAisleFloorGrid.Clear(); + var aisleImageTexture = ImageTexture.CreateFromImage(aisleImage); + doorInfo.AislePreviewTexture = aisleImageTexture; + doorInfo.ConnectDoor.AislePreviewTexture = aisleImageTexture; } } } + + public void GenerateWallAndNavigation(World world, AutoTileConfig config) + { + var navigation = new NavigationRegion2D(); + navigation.Name = "Navigation"; + world.NavigationRoot.AddChild(navigation); + TileMapUtils.GenerateTerrain(_tileRoot, navigation, config); + } + //设置自动地形层的数据 private void SetAutoLayerDataFromList(int layer, int sourceId, RoomInfo roomInfo, List data, Vector2I rectPos, TileSetTerrainInfo terrainInfo) { @@ -226,83 +208,6 @@ _tileRoot.SetCell(layer, pos, sourceId, new Vector2I(atlasCoordsX, atlasCoordsY)); } } - - /// - /// 给TileMap添加轮廓, 该函数为协程函数 - /// - /// 描轮廓的Tile - public IEnumerator AddOutlineTile(TileCellData tileCellData) - { - var c = 0; - var rect = _tileRoot.GetUsedRect(); - var endX = rect.End.X + 1; - var endY = rect.End.Y + 1; - for (int x = rect.Position.X - 1; x <= endX; x++) - { - for (int y = rect.Position.Y - 1; y <= endY; y++) - { - if (c++ > 1000) //份帧处理, 不要挤在一帧 - { - c = 0; - yield return 0; - } - var pos = new Vector2I(x, y); - var flag1 = _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, pos) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, pos) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoAisleFloorLayer, pos) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, pos) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, pos) != tileCellData.AutoTileCoords); - if (!flag1) //空地 - { - var posDown = new Vector2I(pos.X, pos.Y + 1); - var posTop = new Vector2I(pos.X, pos.Y - 1); - var posLeft = new Vector2I(pos.X - 1, pos.Y); - var posRight = new Vector2I(pos.X + 1, pos.Y); - - var posLD = new Vector2I(pos.X - 1, pos.Y + 1); - var posLT = new Vector2I(pos.X - 1, pos.Y - 1); - var posRD = new Vector2I(pos.X + 1, pos.Y + 1); - var posRT = new Vector2I(pos.X + 1, pos.Y - 1); - - var flag2 = _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posDown) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posDown) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posDown) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posDown) != tileCellData.AutoTileCoords) || - - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posTop) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posTop) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posTop) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posTop) != tileCellData.AutoTileCoords) || - - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posLeft) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posLeft) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posLeft) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posLeft) != tileCellData.AutoTileCoords) || - - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posRight) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posRight) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posRight) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posRight) != tileCellData.AutoTileCoords) || - // - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posLD) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posLD) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posLD) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posLD) != tileCellData.AutoTileCoords) || - - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posLT) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posLT) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posLT) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posLT) != tileCellData.AutoTileCoords) || - - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posRD) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posRD) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posRD) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posRD) != tileCellData.AutoTileCoords) || - - _tileRoot.GetCellSourceId(MapLayer.AutoFloorLayer, posRT) != -1 || - _tileRoot.GetCellSourceId(MapLayer.AutoMiddleLayer, posRT) != -1 || - (_tileRoot.GetCellSourceId(MapLayer.AutoTopLayer, posRT) != -1 && _tileRoot.GetCellAtlasCoords(MapLayer.AutoTopLayer, posRT) != tileCellData.AutoTileCoords); - - if (flag2) //非空地, 那么说明这个点需要填充 WALL_BLOCK - { - _tileRoot.SetCell(MapLayer.AutoTopLayer, pos, tileCellData.SourceId, tileCellData.AutoTileCoords); - } - } - } - } - } //填充tile区域 private void FillRect(int layer, TileCellData data, Vector2 pos, Vector2 size) @@ -312,10 +217,6 @@ for (int j = 0; j < size.Y; j++) { var p = new Vector2I((int)pos.X + i, (int)pos.Y + j); - if (layer == MapLayer.AutoAisleFloorLayer) - { - _tempAisleFloorGrid.Set(p, true); - } _tileRoot.SetCell(layer, p, data.SourceId, data.AutoTileCoords); } } @@ -329,894 +230,16 @@ for (int j = 0; j < size.Y; j++) { var p = new Vector2I((int)pos.X + i, (int)pos.Y + j); - if (layer == MapLayer.AutoAisleFloorLayer) - { - _tempAisleFloorGrid.Remove(p.X, p.Y); - } _tileRoot.SetCell(layer, p, 0); } } } - - //横向过道 - private void FullHorizontalAisle(AutoTileConfig config, Rect2 rect) - { - FillRect(MapLayer.AutoAisleFloorLayer, config.Floor, rect.Position + new Vector2(0, 2), rect.Size - new Vector2(0, 3)); - - FillRect(MapLayer.AutoTopLayer, config.TopMask, rect.Position + new Vector2(0, -2), new Vector2(rect.Size.X, 1)); - FillRect(MapLayer.AutoTopLayer, config.TopMask, rect.Position + new Vector2(0, rect.Size.Y), new Vector2(rect.Size.X, 1)); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Top, rect.Position + new Vector2(0, -1), new Vector2(rect.Size.X, 1)); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Vertical_CenterTop, rect.Position, new Vector2(rect.Size.X, 1)); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Vertical_CenterBottom, rect.Position + new Vector2(0, 1), new Vector2(rect.Size.X, 1)); - FillRect(MapLayer.AutoTopLayer, config.Wall_Bottom, rect.Position + new Vector2(0, rect.Size.Y - 1), new Vector2(rect.Size.X, 1)); - } - - //纵向过道 - private void FullVerticalAisle(AutoTileConfig config, Rect2 rect) - { - FillRect(MapLayer.AutoAisleFloorLayer, config.Floor, rect.Position + new Vector2(1, 0), rect.Size - new Vector2(2, 0)); - FillRect(MapLayer.AutoTopLayer, config.TopMask, rect.Position - new Vector2(1, 0), new Vector2(1, rect.Size.Y - 1)); - FillRect(MapLayer.AutoTopLayer, config.TopMask, rect.Position + new Vector2(rect.Size.X, 0), new Vector2(1, rect.Size.Y - 1)); - FillRect(MapLayer.AutoTopLayer, config.Wall_Left, rect.Position, new Vector2(1, rect.Size.Y - 1)); - FillRect(MapLayer.AutoTopLayer, config.Wall_Right, rect.Position + new Vector2(rect.Size.X - 1, 0), new Vector2(1, rect.Size.Y - 1)); - } - - //横向过道, 门朝右, 连接方向向左 - private void FullHorizontalAisleLeft(AutoTileConfig config, Rect2 rect, RoomDoorInfo doorInfo = null) - { - //左 - ClearRect(MapLayer.AutoTopLayer, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2)); - if (doorInfo == null) - { - FillRect(MapLayer.AutoAisleFloorLayer, config.Floor, rect.Position + new Vector2(-1, 1), - new Vector2(1, rect.Size.Y - 2)); - } - else - { - ClearRect(MapLayer.AutoTopLayer, rect.Position - new Vector2(1, 1), new Vector2(2, 4)); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Vertical_LeftTop, rect.Position - new Vector2(1, 0), Vector2.One); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Out_LB, rect.Position - new Vector2(1, 1), Vector2.One); - FillRect(MapLayer.AutoTopLayer, config.Wall_Out_LT, rect.Position + new Vector2(-1, 3), Vector2.One); - - FillRect(MapLayer.AutoFloorLayer, config.Floor, rect.Position + new Vector2(-1, 1), new Vector2(1, rect.Size.Y - 2)); - //生成门的导航区域 - var x = rect.Position.X * GameConfig.TileCellSize; - var y = rect.Position.Y * GameConfig.TileCellSize; - - var op1 = new Vector2(x - GameConfig.TileCellSize * 1.5f, y + GameConfig.TileCellSize * 1.5f); - var op2 = new Vector2(x + GameConfig.TileCellSize * 0.5f, y + GameConfig.TileCellSize * 1.5f); - var op3 = new Vector2(x + GameConfig.TileCellSize * 0.5f, y + GameConfig.TileCellSize * 3f); - var op4 = new Vector2(x - GameConfig.TileCellSize * 1.5f, y + GameConfig.TileCellSize * 3f); - AddDoorNavigation( - doorInfo, op1, op2, op3, op4, - op1, - new Vector2(op1.X + GameConfig.TileCellSize, op2.Y), - new Vector2(op1.X + GameConfig.TileCellSize, op3.Y), - op4 - ); - } - } - - //横向过道, 门朝左, 连接方向向右 - private void FullHorizontalAisleRight(AutoTileConfig config, Rect2 rect, RoomDoorInfo doorInfo = null) - { - //右 - ClearRect(MapLayer.AutoTopLayer, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2)); - if (doorInfo == null) - { - FillRect(MapLayer.AutoAisleFloorLayer, config.Floor, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2)); - } - else - { - ClearRect(MapLayer.AutoTopLayer, rect.Position + new Vector2(rect.Size.X - 1, -1), new Vector2(2, 4)); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Vertical_RightTop, rect.Position + new Vector2(rect.Size.X, 0), Vector2.One); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Out_RB, rect.Position + new Vector2(rect.Size.X, -1), Vector2.One); - FillRect(MapLayer.AutoTopLayer, config.Wall_Out_RT, rect.Position + new Vector2(rect.Size.X, 3), Vector2.One); - - FillRect(MapLayer.AutoFloorLayer, config.Floor, rect.Position + new Vector2(rect.Size.X, 1), new Vector2(1, rect.Size.Y - 2)); - //生成门的导航区域 - var x = rect.Position.X * GameConfig.TileCellSize; - var y = rect.Position.Y * GameConfig.TileCellSize; - - var op1 = new Vector2(x - GameConfig.TileCellSize * 1.5f + (rect.Size.X + 1) * GameConfig.TileCellSize, y + GameConfig.TileCellSize * 1.5f); - var op2 = new Vector2(x + GameConfig.TileCellSize * 0.5f + (rect.Size.X + 1) * GameConfig.TileCellSize, y + GameConfig.TileCellSize * 1.5f); - var op3 = new Vector2(x + GameConfig.TileCellSize * 0.5f + (rect.Size.X + 1) * GameConfig.TileCellSize, y + GameConfig.TileCellSize * 3f); - var op4 = new Vector2(x - GameConfig.TileCellSize * 1.5f + (rect.Size.X + 1) * GameConfig.TileCellSize, y + GameConfig.TileCellSize * 3f); - AddDoorNavigation( - doorInfo, op1, op2, op3, op4, - new Vector2(op2.X - GameConfig.TileCellSize, op1.Y), - op2, - op3, - new Vector2(op2.X - GameConfig.TileCellSize, op4.Y) - ); - } - } - - //纵向过道, 门朝下, 连接方向向上 - private void FullVerticalAisleUp(AutoTileConfig config, Rect2 rect, RoomDoorInfo doorInfo = null) - { - //上 - ClearRect(MapLayer.AutoTopLayer, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1)); - if (doorInfo == null) - { - FillRect(MapLayer.AutoAisleFloorLayer, config.Floor, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1)); - } - else - { - ClearRect(MapLayer.AutoTopLayer, rect.Position + new Vector2(1, 0), new Vector2(2, 2)); - - FillRect(MapLayer.AutoTopLayer, config.Wall_Out_RT, rect.Position + new Vector2(0, -1), Vector2.One); - FillRect(MapLayer.AutoTopLayer, config.Wall_Out_LT, rect.Position + new Vector2(3, -1), Vector2.One); - - FillRect(MapLayer.AutoFloorLayer, config.Floor, rect.Position + new Vector2(1, -1), new Vector2(rect.Size.X - 2, 1)); - //生成门的导航区域 - var x = rect.Position.X * GameConfig.TileCellSize; - var y = rect.Position.Y * GameConfig.TileCellSize; - - var op1 = new Vector2(x + GameConfig.TileCellSize * 1.5f, y - GameConfig.TileCellSize * 1f); - var op2 = new Vector2(x + GameConfig.TileCellSize * 2.5f, y - GameConfig.TileCellSize * 1f); - var op3 = new Vector2(x + GameConfig.TileCellSize * 2.5f, y + GameConfig.TileCellSize * 0.5f); - var op4 = new Vector2(x + GameConfig.TileCellSize * 1.5f, y + GameConfig.TileCellSize * 0.5f); - AddDoorNavigation( - doorInfo, op1, op2, op3, op4, - op1, - op2, - new Vector2(op3.X, op1.Y + GameConfig.TileCellSize), - new Vector2(op4.X, op1.Y + GameConfig.TileCellSize) - ); - } - } - - //纵向过道, 门朝上, 连接方向向下 - private void FullVerticalAisleDown(AutoTileConfig config, Rect2 rect, RoomDoorInfo doorInfo = null) - { - //下 - ClearRect(MapLayer.AutoMiddleLayer, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1)); - if (doorInfo == null) - { - FillRect(MapLayer.AutoAisleFloorLayer, config.Floor, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1)); - } - else - { - ClearRect(MapLayer.AutoTopLayer, rect.Position + new Vector2(1, rect.Size.Y - 2), new Vector2(2, 2)); - ClearRect(MapLayer.AutoMiddleLayer, rect.Position + new Vector2(0, rect.Size.Y - 1), new Vector2(4, 2)); - - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Out_RB, rect.Position + new Vector2(0, rect.Size.Y - 1), Vector2.One); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Vertical_RightTop, rect.Position + new Vector2(0, rect.Size.Y), Vector2.One); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Out_LB, rect.Position + new Vector2(rect.Size.X - 1, rect.Size.Y - 1), Vector2.One); - FillRect(MapLayer.AutoMiddleLayer, config.Wall_Vertical_LeftTop, rect.Position + new Vector2(rect.Size.X - 1, rect.Size.Y), Vector2.One); - - FillRect(MapLayer.AutoFloorLayer, config.Floor, rect.Position + new Vector2(1, rect.Size.Y), new Vector2(rect.Size.X - 2, 1)); - //生成门的导航区域 - var x = rect.Position.X * GameConfig.TileCellSize; - var y = rect.Position.Y * GameConfig.TileCellSize; - - var op1 = new Vector2(x + GameConfig.TileCellSize * 1.5f, y - GameConfig.TileCellSize * 1f + (rect.Size.Y + 1) * GameConfig.TileCellSize); - var op2 = new Vector2(x + GameConfig.TileCellSize * 2.5f, y - GameConfig.TileCellSize * 1f + (rect.Size.Y + 1) * GameConfig.TileCellSize); - var op3 = new Vector2(x + GameConfig.TileCellSize * 2.5f, y + GameConfig.TileCellSize * 0.5f + (rect.Size.Y + 1) * GameConfig.TileCellSize); - var op4 = new Vector2(x + GameConfig.TileCellSize * 1.5f, y + GameConfig.TileCellSize * 0.5f + (rect.Size.Y + 1) * GameConfig.TileCellSize); - AddDoorNavigation( - doorInfo, op1, op2, op3, op4, - new Vector2(op1.X, op3.Y - GameConfig.TileCellSize), - new Vector2(op2.X, op3.Y - GameConfig.TileCellSize), - op3, - op4 - ); - } - } - - /// - /// 添加房间 - /// - private void AddDoorNavigation(RoomDoorInfo doorInfo, - Vector2 op1, Vector2 op2, Vector2 op3, Vector2 op4, - Vector2 cp1, Vector2 cp2, Vector2 cp3, Vector2 cp4) - { - var openPolygonData = new NavigationPolygonData(); - openPolygonData.Type = NavigationPolygonType.Out; - openPolygonData.SetPoints(new []{ op1, op2, op3, op4 }); - - var closePolygonData = new NavigationPolygonData(); - closePolygonData.Type = NavigationPolygonType.Out; - closePolygonData.SetPoints(new []{ cp1, cp2, cp3, cp4 }); - - _connectNavigationItemList.Add(new DoorNavigationInfo(doorInfo, openPolygonData, closePolygonData)); - } - - /// - /// 计算并动生成导航区域, layer 为需要计算的层级,如果没有设置 floorAtlasCoords,则该 layer 下不为空的地砖都将视为可行走区域 - /// - public void GenerateNavigationPolygon(int layer) - { - _usePoints.Clear(); - _polygonDataList.Clear(); - - try - { - var size = new Vector2(GameConfig.TileCellSize, GameConfig.TileCellSize); - - var rect = _tileRoot.GetUsedRect(); - - var x = rect.Position.X; - var y = rect.Position.Y; - var w = rect.Size.X; - var h = rect.Size.Y; - - for (int j = y; j < h; j++) - { - for (int i = x; i < w; i++) - { - if (IsWayTile(layer, i, j)) - { - if (!_usePoints.Contains(new Vector2I(i, j))) - { - NavigationPolygonData polygonData = null; - - if (!IsWayTile(layer, i, j - 1)) - { - polygonData = CalcOutline(layer, i, j, size); - } - else if (!IsWayTile(layer, i, j + 1)) - { - polygonData = CalcInline(layer, i, j, size); - } - - if (polygonData != null) - { - _polygonDataList.Add(polygonData); - } - } - } - } - } - - _generateNavigationResult = new GenerateNavigationResult(true); - } - catch (NavigationPointException e) - { - _usePoints.Clear(); - _polygonDataList.Clear(); - Debug.Log(e.Message); - _generateNavigationResult = new GenerateNavigationResult(false, e); - } - } - - /// - /// 获取生成导航区域操作的结果, 如果没有调用过 GenerateNavigationPolygon() 函数, 则返回 null - /// - /// - public GenerateNavigationResult GetGenerateNavigationResult() - { - return _generateNavigationResult; - } - - /// - /// 将导航区域挂载到 navigationRoot 上 - /// - public void MountNavigationPolygon(Node2D navigationRoot) - { - //TestData(); - // 在 Godot4.0_rc6 中 如果将所有点都放在 NavigationPolygon 里面, 即使点是对的, 但调用 MakePolygonsFromOutlines 还是可能会报错, 这应该是个bug - - //通过 GenerateNavigationPolygon() 计算出来的导航区域 - for (var i = 0; i < _polygonDataList.Count; i++) - { - var polygonData = _polygonDataList[i]; - CreateNavigationRegion(navigationRoot, polygonData); - } - - //门占用区域的导航区域 - for (var i = 0; i < _connectNavigationItemList.Count; i++) - { - var item = _connectNavigationItemList[i]; - item.CloseNavigationNode = CreateNavigationRegion(navigationRoot, item.CloseNavigationData); - item.OpenNavigationNode = CreateNavigationRegion(navigationRoot, item.OpenNavigationData); - item.CloseNavigationNode.Enabled = false; - item.OpenNavigationNode.Enabled = false; - item.DoorInfo.Navigation = item; - } - } - - //创建导航区域 - private NavigationRegion2D CreateNavigationRegion(Node2D navigationRoot, NavigationPolygonData polygonData) - { - var polygon = new NavigationPolygon(); - polygon.CellSize = GameConfig.NavigationCellSize; - polygon.AddOutline(polygonData.GetPoints()); - polygon.MakePolygonsFromOutlines(); - //var param = new NavigationMeshSourceGeometryData2D(); - //NavigationServer2D.BakeFromSourceGeometryData(polygon, param); - var navigationPolygon = new NavigationRegion2D(); - navigationPolygon.Name = "NavigationRegion" + (navigationRoot.GetChildCount() + 1); - navigationPolygon.NavigationPolygon = polygon; - navigationRoot.AddChild(navigationPolygon); - return navigationPolygon; - } - - /// - /// 获取房间内的导航点数据 - /// - public NavigationPolygonData[] GetPolygonData() - { - return _polygonDataList.ToArray(); - } - - /// - /// 设置导航网格数据 - /// - /// - public void SetPolygonData(List list) - { - _polygonDataList.Clear(); - _polygonDataList.AddRange(list); - _generateNavigationResult = new GenerateNavigationResult(true); - } - - /// - /// 清除生成的导航数据 - /// - public void ClearPolygonData() - { - _polygonDataList.Clear(); - _generateNavigationResult = null; - } - - /// - /// 获取连接门导航数据, 必须要调用 AutoFillRoomTile() 函数才有数据 - /// - public NavigationPolygonData[] GetConnectDoorPolygonData() - { - var array = new NavigationPolygonData[_connectNavigationItemList.Count]; - for (var i = 0; i < _connectNavigationItemList.Count; i++) - { - array[i] = _connectNavigationItemList[i].OpenNavigationData; - } - return array; - } - - /// - /// 设置地面的地砖,将影响导航网格计算 - /// - public void SetFloorAtlasCoords(List floorAtlasCoords) - { - _floorAtlasCoords = floorAtlasCoords; - } /// /// 返回指定位置的Tile是否为可以行走 /// private bool IsWayTile(int layer, int x, int y) { - if (_floorAtlasCoords == null || _floorAtlasCoords.Count == 0) - { - return _tileRoot.GetCellSourceId(layer, new Vector2I(x, y)) != -1; - } - - var result = _tileRoot.GetCellAtlasCoords(layer, new Vector2I(x, y)); - return _floorAtlasCoords.Contains(result); - } - - //计算导航网格外轮廓 - private NavigationPolygonData CalcOutline(int layer, int i, int j, Vector2 size) - { - var polygonData = new NavigationPolygonData(); - polygonData.Type = NavigationPolygonType.Out; - var points = new List(); - // 0:右, 1:下, 2:左, 3:上 - var dir = 0; - var offset = new Vector2(size.X * 0.5f, size.Y * 0.5f); - //找到路, 向右开始找边界 - var startPos = new Vector2I(i, j); - - var tempI = i; - var tempJ = j; - - while (true) - { - switch (dir) - { - case 0: //右 - { - if (IsWayTile(layer, tempI, tempJ - 1)) //先向上找 - { - dir = 3; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempJ--; - break; - } - else if (IsWayTile(layer, tempI + 1, tempJ)) //再向右找 - { - if (points.Count == 0) - { - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempI++; - break; - } - else if (IsWayTile(layer, tempI, tempJ + 1)) //向下找 - { - dir = 1; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempJ++; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - case 1: //下 - { - if (IsWayTile(layer, tempI + 1, tempJ)) //先向右找 - { - dir = 0; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempI++; - break; - } - else if (IsWayTile(layer, tempI, tempJ + 1)) //再向下找 - { - if (points.Count == 0) - { - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempJ++; - break; - } - else if (IsWayTile(layer, tempI - 1, tempJ)) //向左找 - { - dir = 2; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempI--; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - case 2: //左 - { - if (IsWayTile(layer, tempI, tempJ + 1)) //先向下找 - { - dir = 1; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempJ++; - break; - } - else if (IsWayTile(layer, tempI - 1, tempJ)) //再向左找 - { - if (points.Count == 0) - { - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempI--; - break; - } - else if (IsWayTile(layer, tempI, tempJ - 1)) //向上找 - { - dir = 3; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempJ--; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - case 3: //上 - { - if (IsWayTile(layer, tempI - 1, tempJ)) //先向左找 - { - dir = 2; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempI--; - break; - } - else if (IsWayTile(layer, tempI, tempJ - 1)) //再向上找 - { - if (points.Count == 0) - { - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempJ--; - break; - } - else if (IsWayTile(layer, tempI + 1, tempJ)) //向右找 - { - dir = 0; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempI++; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - } - } - } - - //计算导航网格内轮廓 - private NavigationPolygonData CalcInline(int layer, int i, int j, Vector2 size) - { - var polygonData = new NavigationPolygonData(); - polygonData.Type = NavigationPolygonType.In; - var points = new List(); - // 0:右, 1:下, 2:左, 3:上 - var dir = 0; - var offset = new Vector2(size.X * 0.5f, size.Y * 0.5f); - //找到路, 向右开始找边界 - var startPos = new Vector2I(i - 1, j); - PutUsePoint(startPos); - - var tempI = i; - var tempJ = j; - - while (true) - { - switch (dir) - { - case 0: //右 - { - if (IsWayTile(layer, tempI, tempJ + 1)) //向下找 - { - dir = 1; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempJ++; - break; - } - else if (IsWayTile(layer, tempI + 1, tempJ)) //再向右找 - { - if (points.Count == 0) - { - //points.Add(new Vector2((tempI - 1) * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2((tempI - 1) * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempI++; - break; - } - else if (IsWayTile(layer, tempI, tempJ - 1)) //先向上找 - { - dir = 3; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempJ--; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - case 1: //下 - { - if (IsWayTile(layer, tempI - 1, tempJ)) //向左找 - { - dir = 2; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempI--; - break; - } - else if (IsWayTile(layer, tempI, tempJ + 1)) //再向下找 - { - if (points.Count == 0) - { - points.Add(new Vector2((tempI - 1) * size.X + offset.X, tempJ * size.Y + offset.Y)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempJ++; - break; - } - else if (IsWayTile(layer, tempI + 1, tempJ)) //先向右找 - { - dir = 0; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempI++; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - case 2: //左 - { - if (IsWayTile(layer, tempI, tempJ - 1)) //向上找 - { - dir = 3; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempJ--; - break; - } - else if (IsWayTile(layer, tempI - 1, tempJ)) //再向左找 - { - if (points.Count == 0) - { - points.Add(new Vector2((tempI - 1) * size.X + offset.X, tempJ * size.Y + offset.Y)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempI--; - break; - } - else if (IsWayTile(layer, tempI, tempJ + 1)) //先向下找 - { - dir = 1; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempJ++; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - case 3: //上 - { - if (IsWayTile(layer, tempI + 1, tempJ)) //向右找 - { - dir = 0; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - //points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y * 2)); - PutUsePoint(pos); - - tempI++; - break; - } - else if (IsWayTile(layer, tempI, tempJ - 1)) //再向上找 - { - if (points.Count == 0) - { - points.Add(new Vector2((tempI - 1) * size.X + offset.X, tempJ * size.Y + offset.Y)); - } - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - PutUsePoint(new Vector2I(tempI, tempJ)); - tempJ--; - break; - } - else if (IsWayTile(layer, tempI - 1, tempJ)) //先向左找 - { - dir = 2; - - var pos = new Vector2I(tempI, tempJ); - if (points.Count > 1 && pos == startPos) - { - polygonData.SetPoints(points.ToArray()); - return polygonData; - } - - points.Add(new Vector2(tempI * size.X + offset.X, tempJ * size.Y + offset.Y)); - PutUsePoint(pos); - - tempI--; - break; - } - - throw new NavigationPointException(new Vector2I(tempI, tempJ), "生成导航多边形发生错误! 点: " + new Vector2I(tempI, tempJ) + "发生交错!"); - } - } - } - } - - //记录导航网格中已经使用过的坐标 - private void PutUsePoint(Vector2I pos) - { - if (_usePoints.Contains(pos)) - { - throw new NavigationPointException(pos, "生成导航多边形发生错误! 点: " + pos + "发生交错!"); - } - - _usePoints.Add(pos); + return _tileRoot.GetCellSourceId(layer, new Vector2I(x, y)) != -1; } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/MapLayer.cs b/DungeonShooting_Godot/src/framework/map/MapLayer.cs index f9995a5..10ad947 100644 --- a/DungeonShooting_Godot/src/framework/map/MapLayer.cs +++ b/DungeonShooting_Godot/src/framework/map/MapLayer.cs @@ -37,10 +37,6 @@ /// 自定义图块顶层 /// public const int CustomTopLayer = AutoTopLayer + 1; - /// - /// 自动图块过道中的地板层, 该层只会出现在 World 场景中的 TileMap - /// - public const int AutoAisleFloorLayer = CustomTopLayer + 1; /// /// 标记数据层, 特殊层, 不会出现在 TileMap 中 diff --git a/DungeonShooting_Godot/src/framework/map/TileMapUtils.cs b/DungeonShooting_Godot/src/framework/map/TileMapUtils.cs new file mode 100644 index 0000000..71f508b --- /dev/null +++ b/DungeonShooting_Godot/src/framework/map/TileMapUtils.cs @@ -0,0 +1,228 @@ + +using System.Collections.Generic; +using System.Linq; +using Godot; +using Godot.Collections; + +public static class TileMapUtils +{ + public const int MainSource = 0; + public const int MainTerrainSet = 0; + public const int MainTerrain = 0; + + /// + /// 生成自动图块和地形, 并烘焙好导航网格 + /// + public static Rect2I GenerateTerrain(TileMap tileMap, NavigationRegion2D navigationRegion, AutoTileConfig autoTileConfig) + { + var list = new List(); + var xStart = int.MaxValue; + var yStart = int.MaxValue; + var xEnd = int.MinValue; + var yEnd = int.MinValue; + + var temp = tileMap.GetUsedCells(MapLayer.AutoFloorLayer); + var autoCellLayerGrid = temp.ToHashSet(); + foreach (var (x, y) in autoCellLayerGrid) + { + //计算范围 + if (x < xStart) + xStart = x; + else if (x > xEnd) + xEnd = x; + + if (y < yStart) + yStart = y; + else if (y > yEnd) + yEnd = y; + + //填充墙壁 + if (!autoCellLayerGrid.Contains(new Vector2I(x, y - 1))) + { + var left = autoCellLayerGrid.Contains(new Vector2I(x - 1, y - 1)); + var right = autoCellLayerGrid.Contains(new Vector2I(x + 1, y - 1)); + if (left && right) + { + var tileCellData1 = autoTileConfig.Wall_Vertical_SingleTop; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); + var tileCellData2 = autoTileConfig.Wall_Vertical_SingleBottom; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); + } + else if (left) + { + var tileCellData1 = autoTileConfig.Wall_Vertical_LeftTop; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); + var tileCellData2 = autoTileConfig.Wall_Vertical_LeftBottom; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); + } + else if (right) + { + var tileCellData1 = autoTileConfig.Wall_Vertical_RightTop; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); + var tileCellData2 = autoTileConfig.Wall_Vertical_RightBottom; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); + } + else + { + var tileCellData1 = autoTileConfig.Wall_Vertical_CenterTop; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); + var tileCellData2 = autoTileConfig.Wall_Vertical_CenterBottom; + tileMap.SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); + } + } + } + + //绘制临时边界 + var temp1 = new List(); + for (var x = xStart - 3; x <= xEnd + 3; x++) + { + var p1 = new Vector2I(x, yStart - 5); + var p2 = new Vector2I(x, yEnd + 3); + temp1.Add(p1); + temp1.Add(p2); + //上横 + tileMap.SetCell(MapLayer.AutoFloorLayer, p1, autoTileConfig.TopMask.SourceId, autoTileConfig.TopMask.AutoTileCoords); + //下横 + tileMap.SetCell(MapLayer.AutoFloorLayer, p2, autoTileConfig.TopMask.SourceId, autoTileConfig.TopMask.AutoTileCoords); + } + for (var y = yStart - 5; y <= yEnd + 3; y++) + { + var p1 = new Vector2I(xStart - 3, y); + var p2 = new Vector2I(xEnd + 3, y); + temp1.Add(p1); + temp1.Add(p2); + //左竖 + tileMap.SetCell(MapLayer.AutoFloorLayer, p1, autoTileConfig.TopMask.SourceId, autoTileConfig.TopMask.AutoTileCoords); + //右竖 + tileMap.SetCell(MapLayer.AutoFloorLayer, p2, autoTileConfig.TopMask.SourceId, autoTileConfig.TopMask.AutoTileCoords); + } + + //计算需要绘制的图块 + var temp2 = new List(); + for (var x = xStart - 2; x <= xEnd + 2; x++) + { + for (var y = yStart - 4; y <= yEnd + 2; y++) + { + if (!autoCellLayerGrid.Contains(new Vector2I(x, y)) && !autoCellLayerGrid.Contains(new Vector2I(x, y + 1)) && !autoCellLayerGrid.Contains(new Vector2I(x, y + 2))) + { + list.Add(new Vector2I(x, y)); + if (!IsMaskCollisionGround(autoCellLayerGrid, x, y)) + { + temp2.Add(new Vector2I(x, y)); + } + } + } + } + var arr = new Array(list); + //绘制自动图块 + tileMap.SetCellsTerrainConnect(MapLayer.AutoFloorLayer, arr, MainTerrainSet, MainTerrain, false); + + //擦除临时边界 + for (var i = 0; i < temp1.Count; i++) + { + tileMap.EraseCell(MapLayer.AutoFloorLayer, temp1[i]); + } + + //计算区域 + var rect = Utils.CalcRect(autoCellLayerGrid); + rect.Position -= new Vector2I(2, 3); + rect.Size += new Vector2I(4, 5); + + //开始绘制导航网格 + GenerateNavigation(navigationRegion, rect.Position, rect.Size); + + //擦除临时边界2 + for (var i = 0; i < temp2.Count; i++) + { + tileMap.EraseCell(MapLayer.AutoFloorLayer, temp2[i]); + } + + //将墙壁移动到指定层 + MoveTerrainCell(tileMap, autoTileConfig, autoCellLayerGrid, rect.Position, rect.Size); + return rect; + } + + private static bool IsMaskCollisionGround(HashSet autoCellLayerGrid, int x, int y) + { + for (var i = -2; i <= 2; i++) + { + for (var j = -2; j <= 4; j++) + { + if (autoCellLayerGrid.Contains(new Vector2I(x + i, y + j))) + { + return true; + } + } + } + + return false; + } + + //生成导航网格 + private static void GenerateNavigation(NavigationRegion2D navigationRegion, Vector2I currRoomPosition, Vector2I currRoomSize) + { + var navigationPolygon = navigationRegion.NavigationPolygon; + if (navigationPolygon != null) + { + navigationPolygon.Clear(); + navigationPolygon.ClearPolygons(); + navigationPolygon.ClearOutlines(); + } + else + { + navigationPolygon = ResourceManager.Load(ResourcePath.resource_navigation_NavigationPolygon_tres); + navigationRegion.NavigationPolygon = navigationPolygon; + } + + var endPos = currRoomPosition + currRoomSize; + navigationPolygon.AddOutline(new [] + { + currRoomPosition * GameConfig.TileCellSize, + new Vector2(endPos.X, currRoomPosition.Y) * GameConfig.TileCellSize, + endPos * GameConfig.TileCellSize, + new Vector2(currRoomPosition.X, endPos.Y) * GameConfig.TileCellSize + }); + navigationRegion.BakeNavigationPolygon(false); + } + + + //将自动生成的图块从 MapLayer.AutoFloorLayer 移动到指定图层中 + private static void MoveTerrainCell(TileMap tileMap, AutoTileConfig autoTileConfig, HashSet autoCellLayerGrid, Vector2I currRoomPosition, Vector2I currRoomSize) + { + tileMap.ClearLayer(MapLayer.AutoTopLayer); + tileMap.ClearLayer(MapLayer.AutoMiddleLayer); + + var x = currRoomPosition.X; + var y = currRoomPosition.Y - 1; + var w = currRoomSize.X; + var h = currRoomSize.Y + 1; + + for (var i = 0; i < w; i++) + { + for (var j = 0; j < h; j++) + { + var pos = new Vector2I(x + i, y + j); + if (!autoCellLayerGrid.Contains(pos) && tileMap.GetCellSourceId(MapLayer.AutoFloorLayer, pos) != -1) + { + var atlasCoords = tileMap.GetCellAtlasCoords(MapLayer.AutoFloorLayer, pos); + var layer = autoTileConfig.GetLayer(atlasCoords); + if (layer == MapLayer.AutoMiddleLayer) + { + layer = MapLayer.AutoMiddleLayer; + } + else if (layer == MapLayer.AutoTopLayer) + { + layer = MapLayer.AutoTopLayer; + } + else + { + Debug.LogError($"异常图块: {pos}, 这个图块的图集坐标'{atlasCoords}'不属于'MiddleMapLayer'和'TopMapLayer'!"); + continue; + } + tileMap.EraseCell(MapLayer.AutoFloorLayer, pos); + tileMap.SetCell(layer, pos, MainSource, atlasCoords); + } + } + } + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs b/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs index 86fc1b6..499b276 100644 --- a/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs +++ b/DungeonShooting_Godot/src/framework/map/fog/FogMask.cs @@ -241,7 +241,6 @@ { return tileMap.GetCellSourceId(MapLayer.AutoFloorLayer, pos) != -1 || tileMap.GetCellSourceId(MapLayer.AutoMiddleLayer, pos) != -1 || - tileMap.GetCellSourceId(MapLayer.AutoTopLayer, pos) != -1 || - tileMap.GetCellSourceId(MapLayer.AutoAisleFloorLayer, pos) != -1; + tileMap.GetCellSourceId(MapLayer.AutoTopLayer, pos) != -1; } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs index 02fb5fa..4b3373d 100644 --- a/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/room/RoomInfo.cs @@ -136,11 +136,6 @@ public Vector2I Waypoints { get; set; } /// - /// 导航网格对象 - /// - public NavigationRegion2D NavigationRegion { get; set; } - - /// /// 在 DungeonGenerator 中是否可以回滚, 如果可以回滚, 那么当前房间就只会有一个 NextRoom /// public bool CanRollback { get; set; } = false; diff --git a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs index ffe961b..9e97d81 100644 --- a/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs +++ b/DungeonShooting_Godot/src/framework/map/serialize/room/DungeonTileInfo.cs @@ -21,18 +21,6 @@ /// [JsonInclude] public List Floor; - - /// - /// 中层数据, 四个一组, 分别是: 地图x坐标, 地图y坐标, Terrain 的 bit, Terrain 的 type - /// - [JsonInclude] - public List Middle; - - /// - /// 顶层数据, 四个一组, 分别是: 地图x坐标, 地图y坐标, Terrain 的 bit, Terrain 的 type - /// - [JsonInclude] - public List Top; /// /// 自定义底层1, 数据五个一组, 分别为: 地图x坐标, 地图y坐标, 资源id, 图集x坐标, 图集y坐标 @@ -75,8 +63,6 @@ NavigationVertices = new List(); NavigationPolygon = new List(); Floor = new List(); - Middle = new List(); - Top = new List(); CustomFloor1 = new List(); CustomFloor2 = new List(); CustomFloor3 = new List(); diff --git a/DungeonShooting_Godot/src/framework/map/serialize/tileSet/TileSetSplit.cs b/DungeonShooting_Godot/src/framework/map/serialize/tileSet/TileSetSplit.cs index b8d22b5..ff55cef 100644 --- a/DungeonShooting_Godot/src/framework/map/serialize/tileSet/TileSetSplit.cs +++ b/DungeonShooting_Godot/src/framework/map/serialize/tileSet/TileSetSplit.cs @@ -291,6 +291,10 @@ /// private static void SetAtlasSourceCollision(TileSetTerrainInfo terrainInfo, TileSetAtlasSource tileSetAtlasSource, byte type, Vector2I bitCoords, bool isHalf) { + if (isHalf) //暂时让半块不设置碰撞信息 + { + return; + } var index = terrainInfo.TerrainCoordsToIndex(bitCoords, type); var cellData = terrainInfo.GetTerrainCell(index, type); if (cellData != null) @@ -298,17 +302,17 @@ var pos = terrainInfo.GetPosition(cellData); var tileData = tileSetAtlasSource.GetTileData(pos, 0); tileData.AddCollisionPolygon(0); - if (isHalf) - { - tileData.SetCollisionPolygonPoints(0, 0, new[] - { - new Vector2(-8, 2), - new Vector2(8, 2), - new Vector2(8, 8), - new Vector2(-8, 8) - }); - } - else + // if (isHalf) + // { + // tileData.SetCollisionPolygonPoints(0, 0, new[] + // { + // new Vector2(-8, 7), + // new Vector2(8, 7), + // new Vector2(8, 8), + // new Vector2(-8, 8) + // }); + // } + // else { tileData.SetCollisionPolygonPoints(0, 0, new [] { diff --git a/DungeonShooting_Godot/src/game/activity/role/player/Player.cs b/DungeonShooting_Godot/src/game/activity/role/player/Player.cs index ea0a6cd..1331123 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/manager/MapLayerManager.cs b/DungeonShooting_Godot/src/game/manager/MapLayerManager.cs index 2def661..047f359 100644 --- a/DungeonShooting_Godot/src/game/manager/MapLayerManager.cs +++ b/DungeonShooting_Godot/src/game/manager/MapLayerManager.cs @@ -58,10 +58,5 @@ tileMap.SetLayerZIndex(MapLayer.CustomTopLayer, 10); tileMap.SetLayerNavigationEnabled(MapLayer.CustomTopLayer, false); tileMap.SetLayerName(MapLayer.CustomTopLayer, nameof(MapLayer.CustomTopLayer)); - - tileMap.AddLayer(MapLayer.AutoAisleFloorLayer); - tileMap.SetLayerZIndex(MapLayer.AutoAisleFloorLayer, -10); - tileMap.SetLayerNavigationEnabled(MapLayer.AutoAisleFloorLayer, false); - tileMap.SetLayerName(MapLayer.AutoAisleFloorLayer, nameof(MapLayer.AutoAisleFloorLayer)); } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index 86af038..6375088 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -79,6 +79,7 @@ public const string prefab_bullet_normal_Bullet0006_tscn = "res://prefab/bullet/normal/Bullet0006.tscn"; public const string prefab_bullet_normal_Bullet0007_tscn = "res://prefab/bullet/normal/Bullet0007.tscn"; public const string prefab_bullet_normal_Bullet0008_tscn = "res://prefab/bullet/normal/Bullet0008.tscn"; + public const string prefab_bullet_normal_Bullet0009_tscn = "res://prefab/bullet/normal/Bullet0009.tscn"; public const string prefab_currency_Gold1_tscn = "res://prefab/currency/Gold1.tscn"; public const string prefab_currency_Gold10_tscn = "res://prefab/currency/Gold10.tscn"; public const string prefab_currency_Gold5_tscn = "res://prefab/currency/Gold5.tscn"; @@ -208,6 +209,7 @@ public const string resource_material_Sawtooth_gdshader = "res://resource/material/Sawtooth.gdshader"; public const string resource_material_Sawtooth_tres = "res://resource/material/Sawtooth.tres"; public const string resource_material_SmokeParticleMaterial_tres = "res://resource/material/SmokeParticleMaterial.tres"; + public const string resource_navigation_NavigationPolygon_tres = "res://resource/navigation/NavigationPolygon.tres"; public const string resource_sound_bgm_Intro_ogg = "res://resource/sound/bgm/Intro.ogg"; public const string resource_sound_sfx_beLoaded_BeLoaded0001_ogg = "res://resource/sound/sfx/beLoaded/BeLoaded0001.ogg"; public const string resource_sound_sfx_beLoaded_BeLoaded0002_ogg = "res://resource/sound/sfx/beLoaded/BeLoaded0002.ogg"; @@ -486,7 +488,8 @@ public const string resource_sprite_weapon_weapon0021_weapon0021_png = "res://resource/sprite/weapon/weapon0021/weapon0021.png"; public const string resource_sprite_weapon_weapon0022_weapon0022_png = "res://resource/sprite/weapon/weapon0022/weapon0022.png"; public const string resource_sprite_weapon_weapon0023_weapon0023_png = "res://resource/sprite/weapon/weapon0023/weapon0023.png"; - public const string resource_sprite_weapon_weapon0033_weapon0033export_png = "res://resource/sprite/weapon/weapon0033/weapon0033-export.png"; + public const string resource_sprite_weapon_weapon0030_weapon0030_png = "res://resource/sprite/weapon/weapon0030/weapon0030.png"; + public const string resource_sprite_weapon_weapon0032_weapon0032_png = "res://resource/sprite/weapon/weapon0032/weapon0032.png"; public const string resource_sprite_weapon_weapon0033_weapon0033_png = "res://resource/sprite/weapon/weapon0033/weapon0033.png"; public const string resource_sprite_weapon_weapon0034_weapon0034_png = "res://resource/sprite/weapon/weapon0034/weapon0034.png"; public const string resource_sprite_weapon_weapon0035_weapon0035_png = "res://resource/sprite/weapon/weapon0035/weapon0035.png"; @@ -498,6 +501,15 @@ public const string resource_sprite_weapon_weapon0039_weapon00391_png = "res://resource/sprite/weapon/weapon0039/weapon0039(1).png"; public const string resource_sprite_weapon_weapon0040_weapon00401_png = "res://resource/sprite/weapon/weapon0040/weapon0040,1.png"; public const string resource_sprite_weapon_weapon0040_weapon0040_png = "res://resource/sprite/weapon/weapon0040/weapon0040.png"; + public const string resource_sprite_weapon_weapon0041_weapon0041_png = "res://resource/sprite/weapon/weapon0041/weapon0041.png"; + public const string resource_sprite_weapon_weapon0042_weapon0042_png = "res://resource/sprite/weapon/weapon0042/weapon0042.png"; + public const string resource_sprite_weapon_weapon0043_weapon0043_png = "res://resource/sprite/weapon/weapon0043/weapon0043.png"; + public const string resource_sprite_weapon_weapon0044_weapon0044_png = "res://resource/sprite/weapon/weapon0044/weapon0044.png"; + public const string resource_sprite_weapon_weapon0045_weapon0045_png = "res://resource/sprite/weapon/weapon0045/weapon0045.png"; + public const string resource_sprite_weapon_weapon0045_子弹_png = "res://resource/sprite/weapon/weapon0045/子弹.png"; + public const string resource_sprite_weapon_weapon0046_weapon0046_png = "res://resource/sprite/weapon/weapon0046/weapon0046.png"; + public const string resource_sprite_weapon_weapon29_weapon0029_png = "res://resource/sprite/weapon/weapon29/weapon0029.png"; + public const string resource_sprite_weapon_weapon31_weapon0031_png = "res://resource/sprite/weapon/weapon31/weapon0031.png"; public const string resource_spriteFrames_bullet_Bullet0001_tres = "res://resource/spriteFrames/bullet/Bullet0001.tres"; public const string resource_spriteFrames_bullet_Bullet0002_tres = "res://resource/spriteFrames/bullet/Bullet0002.tres"; public const string resource_spriteFrames_bullet_Bullet0003_tres = "res://resource/spriteFrames/bullet/Bullet0003.tres"; @@ -506,6 +518,7 @@ public const string resource_spriteFrames_bullet_Bullet0006_tres = "res://resource/spriteFrames/bullet/Bullet0006.tres"; public const string resource_spriteFrames_bullet_Bullet0007_tres = "res://resource/spriteFrames/bullet/Bullet0007.tres"; public const string resource_spriteFrames_bullet_Bullet0008_tres = "res://resource/spriteFrames/bullet/Bullet0008.tres"; + public const string resource_spriteFrames_bullet_Bullet0009_tres = "res://resource/spriteFrames/bullet/Bullet0009.tres"; public const string resource_spriteFrames_bullet_Collision0001_tres = "res://resource/spriteFrames/bullet/Collision0001.tres"; public const string resource_spriteFrames_bullet_Collision0002_tres = "res://resource/spriteFrames/bullet/Collision0002.tres"; public const string resource_spriteFrames_other_RoomDoor_E_Down_tres = "res://resource/spriteFrames/other/RoomDoor_E_Down.tres"; diff --git a/DungeonShooting_Godot/src/game/room/DungeonManager.cs b/DungeonShooting_Godot/src/game/room/DungeonManager.cs index 8f7d569..11b649d 100644 --- a/DungeonShooting_Godot/src/game/room/DungeonManager.cs +++ b/DungeonShooting_Godot/src/game/room/DungeonManager.cs @@ -233,13 +233,11 @@ AutoTileConfig = new AutoTileConfig(0, tileSetSplit.TileSetInfo.Sources[0].Terrain[0]); _dungeonTileMap = new DungeonTileMap(World.TileRoot); yield return _dungeonTileMap.AutoFillRoomTile(AutoTileConfig, _dungeonGenerator.StartRoomInfo, World); + yield return _dungeonTileMap.AutoFillAisleTile(AutoTileConfig, _dungeonGenerator.StartRoomInfo, World); //yield return _dungeonTileMap.AddOutlineTile(AutoTileConfig.WALL_BLOCK); - - //生成寻路网格, 这一步操作只生成过道的导航 - //_dungeonTileMap.GenerateNavigationPolygon(MapLayer.AutoAisleFloorLayer); yield return 0; - //挂载过道导航区域 - //_dungeonTileMap.MountNavigationPolygon(World.NavigationRoot); + //生成墙壁, 生成导航网格 + _dungeonTileMap.GenerateWallAndNavigation(World, AutoTileConfig); yield return 0; //初始化所有房间 yield return _dungeonGenerator.EachRoomCoroutine(InitRoom); @@ -320,8 +318,6 @@ private void InitRoom(RoomInfo roomInfo) { roomInfo.CalcRange(); - //挂载房间导航区域 - MountNavFromRoomInfo(roomInfo); //创建门 CreateDoor(roomInfo); //创建房间归属区域 @@ -337,28 +333,6 @@ //创建房间/过道预览sprite CreatePreviewSprite(roomInfo); } - - //挂载房间导航区域 - private void MountNavFromRoomInfo(RoomInfo roomInfo) - { - var offset = roomInfo.GetOffsetPosition(); - var worldPosition = roomInfo.GetWorldPosition() - offset; - var polygon = roomInfo.RoomSplit.TileInfo.NavigationPolygon; - var vertices = roomInfo.RoomSplit.TileInfo.NavigationVertices; - var polygonData = new NavigationPolygon(); - polygonData.CellSize = GameConfig.NavigationCellSize; - //这里的位置需要加上房间位置 - polygonData.Vertices = vertices.Select(v => v.AsVector2() + worldPosition).ToArray(); - for (var i = 0; i < polygon.Count; i++) - { - polygonData.AddPolygon(polygon[i]); - } - var navigationPolygon = new NavigationRegion2D(); - navigationPolygon.Name = "NavigationRegion" + (GetChildCount() + 1); - navigationPolygon.NavigationPolygon = polygonData; - World.NavigationRoot.AddChild(navigationPolygon); - roomInfo.NavigationRegion = navigationPolygon; - } //创建门 private void CreateDoor(RoomInfo roomInfo) diff --git a/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs b/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs index 8427d3e..02352cf 100644 --- a/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs +++ b/DungeonShooting_Godot/src/game/ui/mapEditor/tileView/EditorTileMap.cs @@ -664,7 +664,10 @@ if (CheckTerrain()) { Debug.Log("开始绘制自动贴图..."); - GenerateTerrain(); + var rect = TileMapUtils.GenerateTerrain(this, _editorTileMap.L_NavigationRegion.Instance, _autoTileConfig); + CurrRoomPosition = rect.Position; + SetMapSize(rect.Size, true); + //GenerateTerrain(); _isGenerateTerrain = true; } else @@ -795,10 +798,8 @@ SetCustomLayerDataFromList(MapLayer.CustomFloorLayer1, tileInfo.CustomFloor1); SetCustomLayerDataFromList(MapLayer.CustomFloorLayer2, tileInfo.CustomFloor2); SetCustomLayerDataFromList(MapLayer.CustomFloorLayer3, tileInfo.CustomFloor3); - SetAutoLayerDataFromList(MapLayer.AutoMiddleLayer, tileInfo.Middle); SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer1, tileInfo.CustomMiddle1); SetCustomLayerDataFromList(MapLayer.CustomMiddleLayer2, tileInfo.CustomMiddle2); - SetAutoLayerDataFromList(MapLayer.AutoTopLayer, tileInfo.Top); SetCustomLayerDataFromList(MapLayer.CustomTopLayer, tileInfo.CustomTop); //如果有图块错误, 则找出错误的点位 @@ -1236,212 +1237,6 @@ }); return _checkTerrainFlag; } - - //生成自动图块 (地形) - private void GenerateTerrain() - { - //ClearLayer(MapLayer.AutoFloorLayer); - var list = new List(); - var xStart = int.MaxValue; - var yStart = int.MaxValue; - var xEnd = int.MinValue; - var yEnd = int.MinValue; - - _autoCellLayerGrid.ForEach((x, y, flag) => - { - if (flag) - { - //计算范围 - if (x < xStart) - xStart = x; - else if (x > xEnd) - xEnd = x; - - if (y < yStart) - yStart = y; - else if (y > yEnd) - yEnd = y; - - //填充墙壁 - if (!_autoCellLayerGrid.Contains(x, y - 1)) - { - var left = _autoCellLayerGrid.Contains(x - 1, y - 1); - var right = _autoCellLayerGrid.Contains(x + 1, y - 1); - if (left && right) - { - var tileCellData1 = _autoTileConfig.Wall_Vertical_SingleTop; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); - var tileCellData2 = _autoTileConfig.Wall_Vertical_SingleBottom; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); - } - else if (left) - { - var tileCellData1 = _autoTileConfig.Wall_Vertical_LeftTop; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); - var tileCellData2 = _autoTileConfig.Wall_Vertical_LeftBottom; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); - } - else if (right) - { - var tileCellData1 = _autoTileConfig.Wall_Vertical_RightTop; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); - var tileCellData2 = _autoTileConfig.Wall_Vertical_RightBottom; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); - } - else - { - var tileCellData1 = _autoTileConfig.Wall_Vertical_CenterTop; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 2), tileCellData1.SourceId, tileCellData1.AutoTileCoords); - var tileCellData2 = _autoTileConfig.Wall_Vertical_CenterBottom; - SetCell(MapLayer.AutoFloorLayer, new Vector2I(x, y - 1), tileCellData2.SourceId, tileCellData2.AutoTileCoords); - } - } - } - - return true; - }); - - //绘制临时边界 - var temp1 = new List(); - for (var x = xStart - 3; x <= xEnd + 3; x++) - { - var p1 = new Vector2I(x, yStart - 5); - var p2 = new Vector2I(x, yEnd + 3); - temp1.Add(p1); - temp1.Add(p2); - //上横 - SetCell(MapLayer.AutoFloorLayer, p1, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords); - //下横 - SetCell(MapLayer.AutoFloorLayer, p2, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords); - } - for (var y = yStart - 5; y <= yEnd + 3; y++) - { - var p1 = new Vector2I(xStart - 3, y); - var p2 = new Vector2I(xEnd + 3, y); - temp1.Add(p1); - temp1.Add(p2); - //左竖 - SetCell(MapLayer.AutoFloorLayer, p1, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords); - //右竖 - SetCell(MapLayer.AutoFloorLayer, p2, _autoTileConfig.TopMask.SourceId, _autoTileConfig.TopMask.AutoTileCoords); - } - - //计算需要绘制的图块 - var temp2 = new List(); - for (var x = xStart - 2; x <= xEnd + 2; x++) - { - for (var y = yStart - 4; y <= yEnd + 2; y++) - { - if (!_autoCellLayerGrid.Contains(x, y) && !_autoCellLayerGrid.Contains(x, y + 1) && !_autoCellLayerGrid.Contains(x, y + 2)) - { - list.Add(new Vector2I(x, y)); - if (!IsMaskCollisionGround(_autoCellLayerGrid, x, y)) - { - temp2.Add(new Vector2I(x, y)); - } - } - } - } - var arr = new Array(list); - //绘制自动图块 - SetCellsTerrainConnect(MapLayer.AutoFloorLayer, arr, _mainTerrainSet, _mainTerrain, false); - - //擦除临时边界 - for (var i = 0; i < temp1.Count; i++) - { - EraseCell(MapLayer.AutoFloorLayer, temp1[i]); - } - - //计算区域 - CalcTileRect(true); - - //开始绘制导航网格 - GenerateNavigation(); - - //擦除临时边界2 - for (var i = 0; i < temp2.Count; i++) - { - EraseCell(MapLayer.AutoFloorLayer, temp2[i]); - } - - //将墙壁移动到指定层 - MoveTerrainCell(); - } - - private bool IsMaskCollisionGround(InfiniteGrid autoCellLayerGrid, int x, int y) - { - for (var i = -2; i <= 2; i++) - { - for (var j = -2; j <= 4; j++) - { - if (autoCellLayerGrid.Contains(x + i, y + j)) - { - return true; - } - } - } - - return false; - } - - //将自动生成的图块从 MapLayer.AutoFloorLayer 移动到指定图层中 - private void MoveTerrainCell() - { - ClearLayer(MapLayer.AutoTopLayer); - ClearLayer(MapLayer.AutoMiddleLayer); - - var x = CurrRoomPosition.X; - var y = CurrRoomPosition.Y - 1; - var w = CurrRoomSize.X; - var h = CurrRoomSize.Y + 1; - - for (var i = 0; i < w; i++) - { - for (var j = 0; j < h; j++) - { - var pos = new Vector2I(x + i, y + j); - if (!_autoCellLayerGrid.Contains(pos) && GetCellSourceId(MapLayer.AutoFloorLayer, pos) != -1) - { - var atlasCoords = GetCellAtlasCoords(MapLayer.AutoFloorLayer, pos); - var layer = _autoTileConfig.GetLayer(atlasCoords); - if (layer == MapLayer.AutoMiddleLayer) - { - layer = MapLayer.AutoMiddleLayer; - } - else if (layer == MapLayer.AutoTopLayer) - { - layer = MapLayer.AutoTopLayer; - } - else - { - Debug.LogError($"异常图块: {pos}, 这个图块的图集坐标'{atlasCoords}'不属于'MiddleMapLayer'和'TopMapLayer'!"); - continue; - } - EraseCell(MapLayer.AutoFloorLayer, pos); - SetCell(layer, pos, _mainSource, atlasCoords); - } - } - } - } - - //生成导航网格 - private void GenerateNavigation() - { - var navigationRegion = _editorTileMap.L_NavigationRegion.Instance; - var navigationPolygon = navigationRegion.NavigationPolygon; - navigationPolygon.Clear(); - navigationPolygon.ClearPolygons(); - navigationPolygon.ClearOutlines(); - var endPos = CurrRoomPosition + CurrRoomSize; - navigationPolygon.AddOutline(new [] - { - CurrRoomPosition * GameConfig.TileCellSize, - new Vector2(endPos.X, CurrRoomPosition.Y) * GameConfig.TileCellSize, - endPos * GameConfig.TileCellSize, - new Vector2(CurrRoomPosition.X, endPos.Y) * GameConfig.TileCellSize - }); - navigationRegion.BakeNavigationPolygon(false); - } //设置显示的错误cell, 会标记上红色的闪烁动画 private void SetErrorCell(Vector2I pos) @@ -1637,8 +1432,6 @@ tileInfo.NavigationPolygon.AddRange(polygon.Polygons); tileInfo.NavigationVertices.AddRange(polygon.Vertices.Select(v => new SerializeVector2(v))); tileInfo.Floor.Clear(); - tileInfo.Middle.Clear(); - tileInfo.Top.Clear(); tileInfo.CustomFloor1.Clear(); tileInfo.CustomFloor2.Clear(); tileInfo.CustomFloor3.Clear(); @@ -1648,8 +1441,6 @@ //保存图块数据 PushAutoLayerDataToList(MapLayer.AutoFloorLayer, tileInfo.Floor); - PushAutoLayerDataToList(MapLayer.AutoMiddleLayer, tileInfo.Middle); - PushAutoLayerDataToList(MapLayer.AutoTopLayer, tileInfo.Top); PushLayerDataToList(MapLayer.CustomFloorLayer1, tileInfo.CustomFloor1); PushLayerDataToList(MapLayer.CustomFloorLayer2, tileInfo.CustomFloor2); PushLayerDataToList(MapLayer.CustomFloorLayer3, tileInfo.CustomFloor3);