diff --git a/DungeonShooting_Godot/prefab/role/Enemy.tscn b/DungeonShooting_Godot/prefab/role/Enemy.tscn index 2399534..29c0d58 100644 --- a/DungeonShooting_Godot/prefab/role/Enemy.tscn +++ b/DungeonShooting_Godot/prefab/role/Enemy.tscn @@ -23,9 +23,11 @@ [node name="AnimatedSprite" parent="." index="2"] material = SubResource( 2 ) -frame = 3 [node name="ViewRay" type="RayCast2D" parent="." index="6"] position = Vector2( 0, -8 ) -[node name="NavigationAgent2D" type="NavigationAgent2D" parent="." index="8"] +[node name="NavigationPoint" type="Node2D" parent="." index="8"] +position = Vector2( 0, -5 ) + +[node name="NavigationAgent2D" type="NavigationAgent2D" parent="NavigationPoint" index="0"] diff --git a/DungeonShooting_Godot/prefab/role/Role.tscn b/DungeonShooting_Godot/prefab/role/Role.tscn index 98f98e6..ab7fba1 100644 --- a/DungeonShooting_Godot/prefab/role/Role.tscn +++ b/DungeonShooting_Godot/prefab/role/Role.tscn @@ -99,7 +99,6 @@ position = Vector2( 0, -12 ) frames = SubResource( 6 ) animation = "idle" -frame = 1 playing = true [node name="Collision" type="CollisionShape2D" parent="."] diff --git a/DungeonShooting_Godot/scene/Room.tscn b/DungeonShooting_Godot/scene/Room.tscn index 02b6ea7..284fa8c 100644 --- a/DungeonShooting_Godot/scene/Room.tscn +++ b/DungeonShooting_Godot/scene/Room.tscn @@ -17,7 +17,9 @@ script = ExtResource( 3 ) [node name="NavigationPolygonInstance" type="NavigationPolygonInstance" parent="."] +visible = false navpoly = SubResource( 2 ) +enabled = false [node name="WorldEnvironment" type="WorldEnvironment" parent="."] environment = SubResource( 1 ) diff --git a/DungeonShooting_Godot/scene/test/TestNavigationPolygon.tscn b/DungeonShooting_Godot/scene/test/TestNavigationPolygon.tscn new file mode 100644 index 0000000..8cebfb1 --- /dev/null +++ b/DungeonShooting_Godot/scene/test/TestNavigationPolygon.tscn @@ -0,0 +1,15 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://src/test/TestNavigationPolygon.cs" type="Script" id=1] + +[sub_resource type="NavigationPolygon" id=1] +vertices = PoolVector2Array( 188, 156, 308, 236, 4, 236, 92, 156, 4, 4, 92, 84, 308, 4, 188, 84 ) +polygons = [ PoolIntArray( 0, 1, 2, 3 ), PoolIntArray( 3, 2, 4, 5 ), PoolIntArray( 5, 4, 6, 7 ), PoolIntArray( 7, 6, 1, 0 ) ] +outlines = [ PoolVector2Array( 4, 4, 308, 4, 308, 236, 4, 236 ), PoolVector2Array( 92, 84, 92, 156, 188, 156, 188, 84 ) ] + +[node name="TestNavigationPolygon" type="Navigation2D"] +position = Vector2( 100, 100 ) +script = ExtResource( 1 ) + +[node name="NavigationPolygonInstance" type="NavigationPolygonInstance" parent="."] +navpoly = SubResource( 1 ) diff --git a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs index 5a4642a..946a4f2 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs @@ -52,7 +52,8 @@ public float PathSignLength { get; set; } = 500; //------------------------------------------------------- - + + private Node2D _navigationPoint; private NavigationAgent2D _navigationAgent2D; private float _navigationUpdateTimer = 0; @@ -68,7 +69,8 @@ //视野射线 ViewRay = GetNode<RayCast2D>("ViewRay"); - _navigationAgent2D = GetNode<NavigationAgent2D>("NavigationAgent2D"); + _navigationPoint = GetNode<Node2D>("NavigationPoint"); + _navigationAgent2D = _navigationPoint.GetNode<NavigationAgent2D>("NavigationAgent2D"); PathSign = new PathSign(this, PathSignLength, GameApplication.Instance.Room.Player); @@ -123,7 +125,7 @@ var nextPos = _navigationAgent2D.GetNextLocation(); LookTargetPosition(playerGlobalPosition); AnimatedSprite.Animation = AnimatorNames.Run; - Velocity = (nextPos - GlobalPosition).Normalized() * MoveSpeed; + Velocity = (nextPos - GlobalPosition - _navigationPoint.Position).Normalized() * MoveSpeed; CalcMove(delta); } diff --git a/DungeonShooting_Godot/src/game/room/RoomManager.cs b/DungeonShooting_Godot/src/game/room/RoomManager.cs index 1842ced..2d2ec83 100644 --- a/DungeonShooting_Godot/src/game/room/RoomManager.cs +++ b/DungeonShooting_Godot/src/game/room/RoomManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using Godot; /// <summary> @@ -39,8 +40,10 @@ _sortRoot = GetNode<YSort>("SortRoot"); _objectRoot = GetNode<Node2D>("ObjectRoot"); - - _navigationPolygon = GetNode<NavigationPolygonInstance>("NavigationPolygonInstance"); + + //_navigationPolygon = GetNode<NavigationPolygonInstance>("NavigationPolygonInstance"); + _navigationPolygon = new NavigationPolygonInstance(); + AddChild(_navigationPolygon); //初始化地图 _mapRoot = GetNode<Node2D>("MapRoot"); @@ -63,7 +66,15 @@ { var nowTicks = DateTime.Now.Ticks; GenerateNavigationPolygon(); - GD.Print("useTime: " + (DateTime.Now.Ticks - nowTicks) / 10000 + "毫秒"); + GD.Print("计算NavigationPolygon用时: " + (DateTime.Now.Ticks - nowTicks) / 10000 + "毫秒"); + + var polygon = new NavigationPolygon(); + foreach (var polygonData in _polygonDataList) + { + polygon.AddOutline(polygonData.Points.ToArray()); + } + polygon.MakePolygonsFromOutlines(); + _navigationPolygon.Navpoly = polygon; //播放bgm SoundManager.PlayMusic(ResourcePath.resource_sound_bgm_Intro_ogg, -17f); @@ -98,7 +109,7 @@ var item = _polygonDataList[i]; if (item.Points.Count >= 2) { - DrawPolyline(item.Points.ToArray(), Colors.Red); + DrawPolyline(item.Points.Concat(new []{ item.Points[0] }).ToArray(), Colors.Red); } } } @@ -152,7 +163,6 @@ if (polygonData != null) { _polygonDataList.Add(polygonData); - //return; } } } @@ -163,6 +173,7 @@ private NavigationPolygonData CalcOutline(int i, int j, TileMap tileMap, Vector2 size) { var polygonData = new NavigationPolygonData(); + polygonData.Type = NavigationPolygonType.Out; var points = polygonData.Points; // 0:右, 1:下, 2:左, 3:上 var dir = 0; @@ -183,13 +194,13 @@ { dir = 3; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ--; @@ -216,13 +227,13 @@ { dir = 1; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ++; @@ -237,13 +248,13 @@ { dir = 0; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI++; @@ -270,13 +281,13 @@ { dir = 2; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI--; @@ -291,13 +302,13 @@ { dir = 1; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ++; @@ -324,13 +335,13 @@ { dir = 3; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ--; @@ -345,13 +356,13 @@ { dir = 2; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI--; @@ -378,13 +389,13 @@ { dir = 0; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI++; @@ -400,12 +411,13 @@ private NavigationPolygonData CalcInline(int i, int j, TileMap tileMap, Vector2 size) { var polygonData = new NavigationPolygonData(); + polygonData.Type = NavigationPolygonType.In; var points = polygonData.Points; // 0:右, 1:下, 2:左, 3:上 var dir = 0; var offset = new Vector2(size.x * 0.5f, size.y * 0.5f); //找到路, 向右开始找边界 - var startPos = new Vector2(i, j); + var startPos = new Vector2(i - 1, j); var tempI = i; var tempJ = j; @@ -420,13 +432,13 @@ { dir = 1; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ++; @@ -453,13 +465,13 @@ { dir = 3; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ--; @@ -474,13 +486,13 @@ { dir = 2; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI--; @@ -507,13 +519,13 @@ { dir = 0; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI++; @@ -528,13 +540,13 @@ { dir = 3; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ--; @@ -561,13 +573,13 @@ { dir = 1; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempJ++; @@ -582,13 +594,13 @@ { dir = 0; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI++; @@ -615,13 +627,13 @@ { dir = 2; - points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); var pos = new Vector2(tempI, tempJ); if (points.Count > 1 && pos == startPos) { return polygonData; } + points.Add(new Vector2(tempI * size.x, tempJ * size.y) + offset); PutUsePoint(pos); tempI--; diff --git a/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs b/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs new file mode 100644 index 0000000..5106b19 --- /dev/null +++ b/DungeonShooting_Godot/src/test/TestNavigationPolygon.cs @@ -0,0 +1,32 @@ +using Godot; + +/// <summary> +/// 测试动态创建 NavigationPolygon +/// </summary> +public class TestNavigationPolygon : Navigation2D +{ + public override void _Ready() + { + var nv = GetNode<NavigationPolygonInstance>("NavigationPolygonInstance"); + + var navpoy = nv.Navpoly; + var outlines = navpoy.Outlines; + var polygons = navpoy.Polygons; + var vertices = navpoy.Vertices; + + var polygon = new NavigationPolygon(); + // polygon.Vertices = new Vector2[] + // { + // new Vector2(0,0), new Vector2(200,200), new Vector2(200, 0), new Vector2(0, 200), + // new Vector2(50,50), new Vector2(150,150), new Vector2(150, 50), new Vector2(50, 150) + // }; + // polygon.AddPolygon(new int[] { 0, 2, 1, 3 }); + // polygon.AddPolygon(new int[] { 4, 6, 5, 7 }); + + polygon.AddOutline(new [] { new Vector2(0,0), new Vector2(200, 0), new Vector2(200,200), new Vector2(0, 200) }); + polygon.AddOutline(new [] { new Vector2(50,50), new Vector2(150, 50), new Vector2(150,150), new Vector2(50, 150) }); + polygon.MakePolygonsFromOutlines(); + + nv.Navpoly = polygon; + } +} \ No newline at end of file