private void Start() { this.tilemap = GameObject.Find("Walls").GetComponent <Tilemap>(); this.CellSize = (Vector2Int)tilemap.cellBounds.size; this.halfCellSize = this.CellSize / 2; this.mapSize = new Vector2(16, 16); this.aStarNode = new AStar2D(); this.cellPath = new List <Vector2>(); this.obstacles = new List <Vector2>(); this.theGrid = GameObject.Find("Grid").GetComponent <Grid>(); GameObject[] obstaclesArray = GameObject.FindGameObjectsWithTag("NavigationObstacle"); Tilemap[] maps = new Tilemap[obstaclesArray.Length]; for (int i = 0; i < obstaclesArray.Length; i++) { maps[i] = obstaclesArray[i].GetComponent <Tilemap>(); foreach (Vector3Int pos in maps[i].cellBounds.allPositionsWithin) { if (maps[i].GetTile(pos) != null) { this.obstacles.Add((Vector3)pos); } } } List <Vector2> walkableCells = CalculateAStarWalkableCells(this.obstacles); ConnectAStarWalkableCells(walkableCells); }
void Start() { pathfind = GetComponent<AStar2D>(); humanSpawnPoint = GameObject.Find ("HumanSpawnPoint"); armyScript = humanSpawnPoint.GetComponent<HumanSpawnPoint> ().monsterCore.GetComponent<MonsterCore> ().armyScript; nearbyPawns = new List<GameObject> (); InvokeRepeating("healNearby", 0, 1); }
public void GetGoalPosition() { UpdateStartPosition(); StartNode = new Node2D( GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(_startPos))); GoalNode = new Node2D( GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(_player.transform.position))); _pathArray = AStar2D.FindPath(StartNode, GoalNode); }
void Start() { health = 50.0f + constitution * 10; maxHealth = 50.0f + constitution * 10; speed = 1.0f + agility * 0.33f; hitDamage = 4.0f + strength; pathfind = GetComponent<AStar2D>(); pathfind.speed = speed; // pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete); }
private void GetGoalPosition(Vector2 startPosition) { StartNode = new Node2D( GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(startPosition))); var mousePos = GetMouseInput(); GoalNode = new Node2D( GridManager2D.Instance.GetGridCellCenter(GridManager2D.Instance.GetGridIndex(mousePos))); if (GoalNode.position.y < 1f) { GoalNode = StartNode; } _pathArray = AStar2D.FindPath(StartNode, GoalNode); }
public override void _Ready() { _aStar = new AStar2D(); _grid = (Node2D)GetNode("Grid"); if (!debug) { _grid.Visible = false; } _tilestoWorld = new Godot.Collections.Dictionary(); _gridRects = new Godot.Collections.Dictionary <int, ColorRect>(); _updateTraversableTilesTimer = (Timer)GetNode("UpdateTraversableTilesTimer"); _updateTraversableTilesTimer.WaitTime = UpdateTRaversableTilesTime; }
// Called every time stabilizes (mode changes to RigidBody2D.MODE_STATIC). // // Once all rooms have stabilized it calculates a playable dungeon `_path` using the MST // algorithm. Based on the calculated `_path`, it populates `_data` with room and corridor tile // positions. // // It emits the "rooms_placed" signal when it finishes so we can begin the tileset placement. private void _on_Room_sleeping_state_changed() { GD.Print("_on_Room_sleeping_state_changed"); _sleepingRooms++; if (_sleepingRooms < MaxRooms) { return; } var mainRooms = new List <Room>(); var mainRoomsPositions = new List <Vector2>(); foreach (Room room in Rooms.GetChildren()) { if (IsMainRoom(room)) { mainRooms.Add(room); mainRoomsPositions.Add(room.Position); } } _path = Utils.MST(mainRoomsPositions); foreach (int point1Id in _path.GetPoints()) { foreach (int point2Id in _path.GetPoints()) { if (point1Id != point2Id && !_path.ArePointsConnected(point1Id, point2Id) && _rng.Randf() < ReconnectionFactor) { _path.ConnectPoints(point1Id, point2Id); } } } foreach (Room room in mainRooms) { AddRoom(room); } AddCorridors(); SetProcess(false); EmitSignal(nameof(RoomsPlaced)); }
//Calculates the Minimum Spanning Tree (MST) for given points and returns an `AStar2D` graph using Prim's algorithm. // https://en.wikipedia.org/wiki/Prim%27s_algorithm // https://en.wikipedia.org/wiki/Minimum_spanning_tree public static AStar2D MST(List <Vector2> pointsList) { var result = new AStar2D(); var firstPoint = pointsList.LastOrDefault(); //Start from an arbitrary point in the list of points result.AddPoint(result.GetAvailablePointId(), firstPoint); pointsList.Remove(firstPoint); //Loop through all points, erasing them as we connect them. while (pointsList.Any()) { var currentPosition = Vector2.Zero; var minPosition = Vector2.Zero; var minDistance = float.PositiveInfinity; foreach (int point1Id in result.GetPoints()) { //Compare each point added to the Astar2D graph to each remaining point to find the closest one var point1Position = result.GetPointPosition(point1Id); foreach (var point2Position in pointsList) { var distance = point1Position.DistanceTo(point2Position); if (minDistance > distance) { //We use the variables to store the coordinates of the closest point. //We have to loop over all points to ensure it's the closest. currentPosition = point1Position; minPosition = point2Position; minDistance = distance; } } } //Connect the point closest to the "current position" with our new point var pointId = result.GetAvailablePointId(); result.AddPoint(pointId, minPosition); result.ConnectPoints(result.GetClosestPoint(currentPosition), pointId); pointsList.Remove(minPosition); } return(result); }
//private static IEnumerator CreateTunnels(IVector2 _entryPt) //UNITY private static void CreateTunnels(IVector2 _entryPt) { var map = m_Tilemap.m_MapData; var points = new List <Point2D>(); foreach (var room in m_Tilemap.m_Rooms) { points.Add(new Point2D(room.Anchor.x, room.Anchor.y)); } var dt = new DelaunayTriangulation(points); var tris = dt.Triangulate(); //TODO Creates null on seed 22 if (tris == null) { m_Tilemap.m_Tunnels = null; //yield break; //UNITY } var roomGraph = new ioGraph <IVector2>(); foreach (var tri in tris) { var p1 = new IVector2((int)tri.a.x, (int)tri.a.y); var p2 = new IVector2((int)tri.b.x, (int)tri.b.y); var p3 = new IVector2((int)tri.c.x, (int)tri.c.y); roomGraph.AddEdge(p1, p2, m_Random.NextDouble() * 100d); roomGraph.AddEdge(p2, p1, m_Random.NextDouble() * 100d); roomGraph.AddEdge(p2, p3, m_Random.NextDouble() * 100d); roomGraph.AddEdge(p3, p2, m_Random.NextDouble() * 100d); roomGraph.AddEdge(p1, p3, m_Random.NextDouble() * 100d); roomGraph.AddEdge(p3, p1, m_Random.NextDouble() * 100d); } var roomMST = roomGraph.PrimMST(); //Get extra room connections beyond mst and add them to the graph var extTunnelPct = (Settings.ExtraTunnelMinPct + (Settings.ExtraTunnelMaxPct - Settings.ExtraTunnelMinPct) * m_Random.NextDouble()); var remEdgeAddCnt = (int)((roomGraph.EdgeCount - roomMST.EdgeCount) * extTunnelPct); Msg.LogDebug(TAG_DEBUG, "Room MST:", MsgPriLvl.HIGH); Msg.LogDebug(TAG_DEBUG, roomMST.ToString(), MsgPriLvl.HIGH); var remAvailEdges = roomGraph.GetNodeConnectionsList(); foreach (var connection in roomMST.GetNodeConnectionsList()) { if (remAvailEdges.Contains(connection)) { remAvailEdges.Remove(connection); } if (remAvailEdges.Contains(connection.Swapped)) { remAvailEdges.Remove(connection.Swapped); } } if (remEdgeAddCnt > remAvailEdges.Count) { Msg.LogDebug(TAG_DEBUG, "Additional Edge count (beyond MST) greater than available edges remaining. Trimming", MsgPriLvl.HIGH); remEdgeAddCnt = remAvailEdges.Count; } for (var i = 0; i < remEdgeAddCnt; ++i) { var connection = remAvailEdges[m_Random.Next(remAvailEdges.Count)]; var edge = new ioGraph <IVector2> .ioGraphEdge(1, connection.v2); roomMST.AddEdge(connection.v1, edge); remAvailEdges.Remove(connection); } Msg.LogDebug(TAG_DEBUG, "Room MST (with extra conns):", MsgPriLvl.HIGH); Msg.LogDebug(TAG_DEBUG, roomMST.ToString(), MsgPriLvl.HIGH); Msg.LogDebug(TAG_DEBUG, roomMST.GetEdgeDesc(), MsgPriLvl.LOW); //Create tunnel paths m_Tilemap.m_Tunnels = new List <TunnelNetwork>(); var logMsg = "Creating Tunnels"; Msg.Log(LOGKEY_MESSAGES, LOGKEY_MESSAGES, logMsg, MsgPriLvl.HIGH); var edgesDone = 0; double debugRoutingTime = 0; double debugAStarTime = 0; for (var nodeIdx = 0; nodeIdx < roomMST.NodeCount; ++nodeIdx) { foreach (var edge in roomMST.GetConnectionsFast(nodeIdx)) { var fromVector = roomMST.GetNode(nodeIdx); var toVector = roomMST.GetNode(edge.ToNode); Progress = 0.5d + (edgesDone / (double)roomMST.EdgeCount) / 2d; logMsg = "Creating Tunnels " + (int)((edgesDone / (float)roomMST.EdgeCount) * 100); //Log(logMsg); Msg.Log(LOGKEY_MESSAGES, LOGKEY_MESSAGES, logMsg, MsgPriLvl.HIGH); var roomsToConnect = new[] { m_Tilemap.m_Rooms.Get(fromVector), m_Tilemap.m_Rooms.Get(toVector) }; Msg.LogDebug(TAG_DEBUG, fromVector + " -> " + toVector, MsgPriLvl.MED); if (roomsToConnect[0] == null || roomsToConnect[1] == null) { throw new NullReferenceException(TAG_DEBUG + ":Room not found in roomGroup."); } //Find closest tunnel tie if exists ========================================= //If Rooms are already connected then skip var fromNets = new List <TunnelNetwork>(); var toNets = new List <TunnelNetwork>(); var skipConnection = false; foreach (var tNet in m_Tilemap.m_Tunnels) { if (tNet.ConnectsTo(roomsToConnect[0])) { fromNets.Add(tNet); } if (tNet.ConnectsTo(roomsToConnect[1])) { toNets.Add(tNet); } } if (fromNets.Any(toNets.Contains)) { skipConnection = true; } if (skipConnection) { Msg.LogDebug(TAG_DEBUG, "Rooms already connected by same Net... Skipping", MsgPriLvl.MED); edgesDone++; continue; } if (Settings.ClosestConnect) { var fromCoordsf = new HashSet <IVector2>(); var toCoordsf = new HashSet <IVector2>(); //Get all coords of from and to nets (exluding room doorways) foreach (var net in fromNets) { fromCoordsf.UnionWith(net.GetAllPathCoords(true)); } foreach (var net in toNets) { toCoordsf.UnionWith(net.GetAllPathCoords(true)); } //Remove room wall coordinates foreach (var room in m_Tilemap.m_Rooms) { fromCoordsf.RemoveWhere(_coord => room.GetWallCoords(true).Contains(_coord)); toCoordsf.RemoveWhere(_coord => room.GetWallCoords(true).Contains(_coord)); } //Add anchors of rooms to connect fromCoordsf.Add(fromVector); toCoordsf.Add(toVector); //Use Manhattan Distance for distance calc var distance = AStar2D.ManhattanDistance(fromVector, toVector, 1); var closestTunnelCoords = Support2D.GetNearestCoords(fromCoordsf, toCoordsf, ref distance); if (closestTunnelCoords[0] != null) { if (!closestTunnelCoords[0].Value.Equals(fromVector)) { roomsToConnect[0] = null; fromVector = closestTunnelCoords[0].Value; } } if (closestTunnelCoords[1] != null) { if (!closestTunnelCoords[1].Value.Equals(toVector)) { roomsToConnect[1] = null; toVector = closestTunnelCoords[1].Value; } } } Msg.LogDebug(TAG_DEBUG, "Creating Routing Cost Map.", MsgPriLvl.MED); var routingTimeStamp = DateTime.Now; var costGrid = CreateRoutingCostMap(roomsToConnect.ToList(), new IVector2(map.Dims.x, map.Dims.y), Settings.TunnelBuffer, Settings.TunnelPathMag, Settings.CalcRoutingStrength); debugRoutingTime += (DateTime.Now - routingTimeStamp).TotalSeconds; Msg.LogDebug(TAG_DEBUG, "Rounting map finished. Took " + (DateTime.Now - routingTimeStamp).TotalSeconds + " seconds.", MsgPriLvl.MED); //UNITY DEBUG /* * // Unity Draw routing map to texture * * * * //Clear texture to default weight * * * var texture = (Texture2D)TileMap2D.meshRenderer.material.mainTexture; * if (!texture) * { * * texture = new Texture2D(costGrid.Dims.x, costGrid.Dims.y); * texture.filterMode = FilterMode.Point; * TileMap2D.meshRenderer.material.mainTexture = texture; * if (costGrid.Dims.x > costGrid.Dims.y) * TileMap2D.instance.transform.localScale = new Vector3(1, 0, costGrid.Dims.y / (float)costGrid.Dims.x); * else * TileMap2D.instance.transform.localScale = new Vector3(costGrid.Dims.x / (float)costGrid.Dims.y, 1, 1); * } * if (true) * { * * var defCost = Settings.CalcRoutingStrength * 2d + 1; * var weightMax = (defCost + defCost * Settings.TunnelBuffer); * * var weights = costGrid.Weights; * for (int y = 0; y < costGrid.Dims.y; ++y) * for (int x = 0; x < costGrid.Dims.x; ++x) * { * double weight = weights[x, y]; * float whiteLevel = (float)(weight / defCost); * var color = new Color(whiteLevel / 2f, whiteLevel / 2f, whiteLevel / 2f, 1f); * if (whiteLevel > 1f) * { * whiteLevel = (float)(weight - defCost) / (float)(weightMax - defCost); * whiteLevel = (whiteLevel / 2f + 0.5f); * color = new Color(whiteLevel, whiteLevel, whiteLevel, 1f); * } * texture.SetPixel(x, y, color); * } * * var doors = new HashSet<IVector2>(); * foreach (var tNet in m_Tilemap.m_Tunnels) * foreach (var room in tNet.ConnectedRooms) * if (room != null) doors.UnionWith(room.Doorways); * * foreach (var doorway in doors) * texture.SetPixel(doorway.x, doorway.y, new Color(0f, 0f, 1f, 1f)); * * texture.Apply(); * * yield return null; * } * // -------------------------- *///END UNITY BLOCK Msg.LogDebug(TAG_DEBUG, "Running AStar algorithm...", MsgPriLvl.MED); routingTimeStamp = DateTime.Now; var routingStr = Settings.CalcRoutingStrength; var turnCost = Settings.CalcRoutingStrength * Settings.CalcTurnCost; if (routingStr == 0) { turnCost = Settings.CalcTurnCost; } /*yield return //UNITY * TileMap2D.instance.StartCoroutine(AStar2D.AStar(costGrid, fromVector, toVector, * turnCost, Settings.TunnelPathMag, * AStar2D.ManhattanDistance)); */ AStar2D.AStar(costGrid, fromVector, toVector, turnCost, Settings.TunnelPathMag, AStar2D.ManhattanDistance); debugAStarTime += (DateTime.Now - routingTimeStamp).TotalSeconds; Msg.LogDebug(TAG_DEBUG, "AStar finished. Took " + (DateTime.Now - routingTimeStamp).TotalSeconds + " seconds.", MsgPriLvl.MED); var vecPath = AStar2D.AStarPath; if (vecPath == null) { logMsg = "Unable to create path: " + fromVector + " --> " + toVector; //Log(logMsg); Msg.LogDebug(TAG_DEBUG, logMsg, MsgPriLvl.HIGH); continue; } var path = new TunnelNetwork.IPath(vecPath, roomsToConnect[0], roomsToConnect[1]); TrimTunnelAtRooms(ref path); AddPathToNetwork(path); ++edgesDone; } } //Add Entry Point and connect to closest room var connectEntry = true; var entryDist = int.MaxValue; //Connect entry point to closest room or tunnel foreach (var room in m_Tilemap.m_Rooms) { if (room.ContainsCoord(_entryPt, true)) { connectEntry = false; break; } } if (connectEntry) { var availCoords = new HashSet <IVector2>(); foreach (var tNet in m_Tilemap.m_Tunnels) { availCoords.UnionWith(tNet.GetAllPathCoords(false)); } foreach (var room in m_Tilemap.m_Rooms) { availCoords.RemoveWhere(_coord => room.GetWallCoords(true).Contains(_coord)); } availCoords.UnionWith(m_Tilemap.m_Rooms.Anchors); double distance = m_Tilemap.Dims.x + m_Tilemap.Dims.y; var closestCoords = Support2D.GetNearestCoords(new HashSet <IVector2> { _entryPt }, availCoords, ref distance); var closestRoom = m_Tilemap.m_Rooms.Get(closestCoords[1].Value); var excludeList = new List <Room>(); if (closestRoom != null) { excludeList.Add(closestRoom); } var turnCost = Settings.CalcRoutingStrength * Settings.CalcTurnCost; var entryRouteGraph = CreateRoutingCostMap(excludeList, new IVector2(map.Dims.x, map.Dims.y), Settings.RoomBufferMax, Settings.TunnelPathMag, Settings.CalcRoutingStrength); /* //UNITY * yield return TileMap2D.instance.StartCoroutine(AStar2D.AStar(entryRouteGraph, _entryPt, closestCoords[1].Value, * turnCost, Settings.TunnelPathMag, * AStar2D.ManhattanDistance)); * */ AStar2D.AStar(entryRouteGraph, _entryPt, closestCoords[1].Value, turnCost, Settings.TunnelPathMag, AStar2D.ManhattanDistance); var entryConnect = AStar2D.AStarPath; //TODO make entry point a room? /*var entryRoom = new Room(new Bounds(_entryPt.x - 1, _entryPt.y - 1, _entryPt.x + 1, _entryPt.y + 1), * Room.ShapeType.Rectangle); * m_Tilemap.m_Rooms.Add(entryRoom);*/ var entryPath = new TunnelNetwork.IPath(entryConnect, null, closestRoom); TrimTunnelAtRooms(ref entryPath); AddPathToNetwork(entryPath); } Msg.LogDebug(TAG_DEBUG, "Total routing graph time: " + debugRoutingTime, MsgPriLvl.HIGH); Msg.LogDebug(TAG_DEBUG, "Total AStar time: " + debugAStarTime, MsgPriLvl.HIGH); }
void Start() { constitution = level; agility = level; strength = level; for(int i = 0; i < level - 1; i++) { int skill = UnityEngine.Random.Range (1, 5); switch(skill) { case 1: constitution ++; break; case 2: agility ++; break; case 3: strength ++; break; } } health = 50.0f + constitution * 10; speed = 1.0f + agility * 0.33f; hitDamage = 4.0f + strength; pathfind = GetComponent<AStar2D>(); if(pathfind == null) { Debug.Log ("Pathfind not found!"); } grid = spawnpoint.GetComponent<HumanSpawnPoint>().grid; map = spawnpoint.GetComponent<HumanSpawnPoint>().map; resourcesScript = Camera.main.gameObject.GetComponent<ResourcesControl>(); armyScript = spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.GetComponent<MonsterCore>().armyScript; pathfind.speed = speed; pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete); }
void Start() { pathfind = GetComponent<AStar2D>(); if(pathfind == null) { Debug.Log ("Pathfind not found!"); } grid = spawnpoint.GetComponent<HumanSpawnPoint>().grid; map = spawnpoint.GetComponent<HumanSpawnPoint>().map; resourcesScript = Camera.main.gameObject.GetComponent<ResourcesControl>(); pathfind.speed = 1.5f; pathfind.seeker.StartPath(transform.position, spawnpoint.GetComponent<HumanSpawnPoint>().monsterCore.transform.position, pathfind.OnPathComplete); }