private IEnumerable <Monster> GetNearbyMonsters() { var area = new TileRect(new TilePos(this._player.TilePosition.X - 16, this._player.TilePosition.Y - 16), 32, 32); var searchParameters = new SearchParameters { EndLocation = this._player.TilePosition, MaximumLengthOfPath = 20, CanBeOccupied = tp => !GlobalServices.GameState.IsImpassableItemOnTile(tp) }; var result = new List <Monster>(); foreach (var monsterOrEgg in GlobalServices.GameState.AllItemsInRectangle(area).OfType <IMonster>()) { var monster = monsterOrEgg as Monster; if (monsterOrEgg is MonsterEgg egg) { monster = egg.HatchEgg(); } if (monster != null && !monster.IsStationary) { searchParameters.StartLocation = monster.TilePosition; var pf = new PathFinder(searchParameters); if (pf.TryFindPath(out _)) { result.Add(monster); } } } return(result); }
/// <summary> /// Returns the distance from the TilePosition to the closest tile in the TileRect /// </summary> /// <param name="a">Tile to find the distance from</param> /// <param name="r">TileRect to find the distance to</param> /// <returns></returns> public static float EuclideanDistance(TilePosition a, TileRect r) { if (r.Contains(a)) { // Inside rect return(0); } if (r.CMin <= a.Column && a.Column <= r.CMax) { // Closest point is on one of the horiztonal edges return(Math.Min(Math.Abs(a.Row - r.RMin), Math.Abs(a.Row - r.RMax))); } if (r.RMin <= a.Row && a.Row <= r.RMax) { // Closest point is on one of the vertical edges return(Math.Min(Math.Abs(a.Column - r.CMin), Math.Abs(a.Column - r.CMax))); } // Closest point is one of the corners. return (Math.Min( Math.Min( EuclideanDistance(a, new TilePosition(r.CMin, r.RMin)), EuclideanDistance(a, new TilePosition(r.CMin, r.RMax))), Math.Min( EuclideanDistance(a, new TilePosition(r.CMax, r.RMin)), EuclideanDistance(a, new TilePosition(r.CMax, r.RMax))))); }
/// <summary> /// Find the shortest path using the A* algorithm and a Euclidean distance heuristic /// </summary> public TilePath Plan(TilePosition start, TileRect end) { heap.Clear(); searchedTilesOverlay.Clear(); var startNode = heap.NodeAt(start); startNode.Predecessor = null; heap.DecreaseKey(startNode, 0, 0); var currentNode = startNode; while (!heap.IsEmpty && !end.Contains((currentNode = heap.ExtractMin()).Position)) { searchedTilesOverlay.Add(currentNode.Position); foreach (var n in currentNode.Neighbors) { float newDistanceFromStart = currentNode.DistanceFromStart // Cost so far + TilePosition.EuclideanDistance(currentNode.Position, n.Position) // Edge cost + TilePosition.EuclideanDistance(n.Position, end); // Estimated cost to end if (n.DistanceFromStart > newDistanceFromStart) { n.Predecessor = currentNode; heap.DecreaseKey(n, newDistanceFromStart, newDistanceFromStart); } } } heap.SetOverlayToComputedPath(this.computedPathOverlay, currentNode); searchedTilesOverlay.Clear(); searchedTilesOverlay.SetRect(end); if (!end.Contains(currentNode.Position)) return null; return this.MakePath(currentNode); }
public void SetTileColor(TileRect r, Color c) { foreach (var tile in r) { SetTileColor(tile, c); } }
/// <summary> /// Set this overlay to include exactly the tiles in the specified rectangle. /// </summary> /// <param name="r"></param> public void SetRect(TileRect r) { this.tiles.Clear(); foreach (var p in r) { this.tiles.Add(p); } }
/// <summary> /// Gets the rectangle that encompasses the room that contains the specified position /// </summary> /// <param name="position">Specifies the position within the world</param> /// <returns>A rectangular structure which specifies the co-ordinates of the room containing the specified position</returns> public static TileRect GetContainingRoom(TilePos position) { var roomX = (int)(position.X / Constants.RoomSizeInTiles.X); var roomY = (int)(position.Y / Constants.RoomSizeInTiles.Y); var topLeft = new TilePos(roomX * (int)Constants.RoomSizeInTiles.X, roomY * (int)Constants.RoomSizeInTiles.Y); var result = new TileRect(topLeft, (int)Constants.RoomSizeInTiles.X, (int)Constants.RoomSizeInTiles.Y); return(result); }
public static bool Build(TileRect rect, out PreciseSectorRows tiles) { Span <int> xList = stackalloc int[5]; var xSize = build_clamped_tile_coordlist(rect.x1, rect.x2 + 1, 64, xList); var xSizeMin1 = xSize - 1; if (xSize == 1) { tiles = default; return(false); } Span <int> yList = stackalloc int[5]; var ySize = build_clamped_tile_coordlist(rect.y1, rect.y2 + 1, 64, yList) - 1; if (ySize <= 0) { tiles = default; return(false); } tiles = new PreciseSectorRows(); tiles.Init(); var v17 = 0; var v18 = ySize; do { var deltaY = yList[v17 + 1] - yList[v17]; tiles.Rows[v17].colCount = 0; tiles.Rows[v17].field_68 = deltaY; var v14 = 0; if (xSizeMin1 > 0) { do { tiles.Rows[v17].Tiles[v14] = new locXY(xList[v14], yList[v17]); tiles.Rows[v17].sectors[v14] = new SectorLoc(tiles.Rows[v17].Tiles[v14]); tiles.Rows[v17].startTiles[v14] = Sector.GetSectorTileIndex(xList[v14], yList[v17]); tiles.Rows[v17].strides[v14] = xList[v14 + 1] - xList[v14]; v14++; } while (v14 < xSizeMin1); } tiles.Rows[v17].colCount = xSizeMin1; v17++; v18--; } while (v18 > 0); tiles.RowCount = ySize; return(true); }
public Tile[,] GetRegionTiles(TileRect r) { var tiles = new Tile[r.Width, r.Height]; foreach (var p in r) { tiles[p.Column - r.CMin, p.Row - r.RMin] = contents[p.Column, p.Row]; } return(tiles); }
private string GetTileName(int tileX, int tileY) { TileRect tile = GetTile(tileX, tileY); if (tile != null) { return(tile.name); } return("unknown"); }
public bool IsFreespace(TileRect r) { foreach (var p in r) { if (!IsFreespace(p)) { return(false); } } return(true); }
private static TileRect GetRectangleEnclosingTilesThatAreCurrentlyInView(Vector2 windowOffset) { var roomStartX = (int)Math.Floor(windowOffset.X / Constants.TileLength); var roomStartY = (int)Math.Floor(windowOffset.Y / Constants.TileLength); var roomEndX = (int)Math.Ceiling((windowOffset.X + Constants.RoomSizeInPixels.X) / Constants.TileLength); var roomEndY = (int)Math.Ceiling((windowOffset.Y + Constants.RoomSizeInPixels.Y) / Constants.TileLength); var result = new TileRect(new TilePos(roomStartX, roomStartY), roomEndX - roomStartX, roomEndY - roomStartY); Debug.Assert(result.Width == (int)Constants.RoomSizeInTiles.X || result.Width == ((int)Constants.RoomSizeInTiles.X + 1)); Debug.Assert(result.Height == (int)Constants.RoomSizeInTiles.Y || result.Height == ((int)Constants.RoomSizeInTiles.Y + 1)); return(result); }
public SectorEnumerator(TileRect tileRect, bool lockSectors = true) : this() { _tileRectangle = new Rectangle( tileRect.x1, tileRect.y1, tileRect.x2 - tileRect.x1, tileRect.y2 - tileRect.y1 ); _currentX = _tileRectangle.Left; _currentY = _tileRectangle.Top; _endX = _tileRectangle.Right; _endY = _tileRectangle.Bottom; _lockSectors = lockSectors; }
public void ButtonSaveTile() { TileRect tile = GetTile(currentTileX, currentTileY); if (tile != null) { string path = Application.dataPath + "/Resources/Tilesets/" + tilesetName + "/Images/" + tile.name + ".png"; Texture2D texture = DrawTileImage(tile.x, tile.y); DrawUtils.SaveTextureToPng(texture, path); info.text = "Tile " + tile.name + " has been saved."; } else { info.text = "No available tile to save."; Debug.LogError("No available tile to save."); } }
public Bitmap CreateTileLayerImage(Bitmap canvas, ResourceClass.GWEDFile.TileMapStruct[,] tileMaps, int tileRefIndex, TileRect tileRect, ushort tilePixel, ushort bright) { byte[] buff = new byte[tilePixel * tilePixel]; // 64 x 64 Rectangle rect; ushort tileRef; for (ushort r = tileRect.minY; r < tileRect.maxY; r++) { for (ushort c = tileRect.minX; c < tileRect.maxX; c++) { tileRef = tileMaps[c, r].tileRef[tileRefIndex]; rect = new Rectangle(c * tilePixel, r * tilePixel, tilePixel, tilePixel); this.GetTileBitmap(canvas, buff, ref tileRef, rect, ref bright); } } return(canvas); }
private TileRect CalculateTileRect(ResourceClass.GWEDFile.OverlayStruct baseLayer, ushort tilePixel) { TileRect tileRect = new TileRect(); if (ApplicationRuntime.AppParams.HighMemoryUsage) { tileRect.minX = 0; tileRect.maxX = baseLayer.xtile; tileRect.minY = 0; tileRect.maxY = baseLayer.ytile; } else { double minX = Math.Abs(this.picAreaMap.DisplayRectangle.Left); double maxX = minX + this.picAreaMap.ClientSize.Width; double minY = Math.Abs(this.picAreaMap.DisplayRectangle.Top); double maxY = minY + this.picAreaMap.ClientSize.Height; tileRect.minX = (ushort)Math.Floor(minX / tilePixel); tileRect.maxX = (ushort)Math.Ceiling(maxX / tilePixel); tileRect.minY = (ushort)Math.Floor(minY / tilePixel); tileRect.maxY = (ushort)Math.Ceiling(maxY / tilePixel); int diff = tileRect.maxX - baseLayer.xtile; if (diff > 0) { tileRect.minX = (ushort)(tileRect.minX - diff < 0 ? 0 : tileRect.minX - diff); tileRect.maxX = baseLayer.xtile; } diff = tileRect.maxY - baseLayer.ytile; if (diff > 0) { tileRect.minY = (ushort)(tileRect.minY - diff < 0 ? 0 : tileRect.minY - diff); tileRect.maxY = baseLayer.ytile; } } return(tileRect); }
public void UpdateCenter(LocAndOffsets center) { CenterTile = center.location; _centerSubtile.X = SubtileFromOffset(center.off_x); _centerSubtile.Y = SubtileFromOffset(center.off_y); var partyMemberX = center.location.locx; var partyMemberY = center.location.locy; var radiusTiles = Radius / 3; OriginTile = new locXY(partyMemberX - radiusTiles, partyMemberY - radiusTiles); var tileRect = new TileRect { x1 = OriginTile.locx, y1 = OriginTile.locy, x2 = OriginTile.locx + Dimension / 3 - 1, y2 = OriginTile.locy + Dimension / 3 - 1 }; TileRect = tileRect; }
/// <summary> /// Find the shortest path using the A* algorithm and a Euclidean distance heuristic /// </summary> public TilePath Plan(TilePosition start, TileRect end) { heap.Clear(); searchedTilesOverlay.Clear(); var startNode = heap.NodeAt(start); startNode.Predecessor = null; heap.DecreaseKey(startNode, 0, 0); var currentNode = startNode; while (!heap.IsEmpty && !end.Contains((currentNode = heap.ExtractMin()).Position)) { searchedTilesOverlay.Add(currentNode.Position); foreach (var n in currentNode.Neighbors) { float newDistanceFromStart = currentNode.DistanceFromStart // Cost so far + TilePosition.EuclideanDistance(currentNode.Position, n.Position) // Edge cost + TilePosition.EuclideanDistance(n.Position, end); // Estimated cost to end if (n.DistanceFromStart > newDistanceFromStart) { n.Predecessor = currentNode; heap.DecreaseKey(n, newDistanceFromStart, newDistanceFromStart); } } } heap.SetOverlayToComputedPath(this.computedPathOverlay, currentNode); searchedTilesOverlay.Clear(); searchedTilesOverlay.SetRect(end); if (!end.Contains(currentNode.Position)) { return(null); } return(this.MakePath(currentNode)); }
/// <summary> /// Retrieves all game objects within the specified rectangle /// </summary> /// <param name="tr">Top left starting point for the rectangle</param> /// <returns>A lazy enumeration of all the matching game objects</returns> public IEnumerable <IGameObject> AllItemsInRectangle(TileRect tr) { for (int j = 0; j < tr.Height; j++) { int y = tr.TopLeft.Y + j; for (int i = 0; i < tr.Width; i++) { int x = tr.TopLeft.X + i; var listOfItems = this.GetItemsOnTile(new TilePos(x, y)); if (listOfItems == null) { continue; } var copyOfList = listOfItems.ToArray(); foreach (var item in copyOfList) { yield return(item); } } } }
public void Render(IGameViewport viewport, TileRect tileRect) { _device.SetMaterial(_material.Resource); var viewProj = viewport.Camera.GetViewProj(); _device.SetVertexShaderConstants(0, ref viewProj); using var sectorIt = new SectorIterator(tileRect); foreach (var sector in sectorIt.EnumerateSectors()) { if (!sector.IsValid) { continue; } if (!_sectorDebugState.TryGetValue(sector.Loc, out var renderingState)) { renderingState = BuildSubTileMesh(_device, _material.Resource.VertexShader, sector.Sector); _sectorDebugState.Add(sector.Loc, renderingState); } renderingState.Render(_device); } }
public SectorIterator(TileRect tileRect) : this(tileRect.x1, tileRect.x2, tileRect.y1, tileRect.y2) { }
/// <summary> /// Returns the distance from the TilePosition to the closest tile in the TileRect /// </summary> /// <param name="a">Tile to find the distance from</param> /// <param name="r">TileRect to find the distance to</param> /// <returns></returns> public static float EuclideanDistance(TilePosition a, TileRect r) { if (r.Contains(a)) // Inside rect return 0; if (r.CMin <= a.Column && a.Column <= r.CMax) // Closest point is on one of the horiztonal edges return Math.Min(Math.Abs(a.Row - r.RMin), Math.Abs(a.Row - r.RMax)); if (r.RMin <= a.Row && a.Row <= r.RMax) // Closest point is on one of the vertical edges return Math.Min(Math.Abs(a.Column - r.CMin), Math.Abs(a.Column - r.CMax)); // Closest point is one of the corners. return Math.Min( Math.Min( EuclideanDistance(a, new TilePosition(r.CMin, r.RMin)), EuclideanDistance(a, new TilePosition(r.CMin, r.RMax))), Math.Min( EuclideanDistance(a, new TilePosition(r.CMax, r.RMin)), EuclideanDistance(a, new TilePosition(r.CMax, r.RMax)))); }
/// <summary> /// Set this overlay to include exactly the tiles in the specified rectangle. /// </summary> /// <param name="r"></param> public void SetRect(TileRect r) { this.tiles.Clear(); foreach (var p in r) this.tiles.Add(p); }
public BoundaryFixed(TileRect boundary) { this._boundary = boundary; }
static TileRect() { Empty = new TileRect(0, 0, -1, -1); }
public BoundMovementFactory(TilePos worldSize) { var worldBoundary = new TileRect(TilePos.Zero, worldSize.X, worldSize.Y); this._worldBoundary = new BoundaryFixed(worldBoundary); }
public IBoundMovement GetExplicitBoundary(TileRect boundary) { return(new BoundaryFixed(boundary)); }
public bool IsFreespace(TileRect r) { foreach (var p in r) if (!IsFreespace(p)) return false; return true; }
public Tile[,] GetRegionTiles(TileRect r) { var tiles = new Tile[r.Width, r.Height]; foreach (var p in r) tiles[p.Column - r.CMin, p.Row - r.RMin] = contents[p.Column, p.Row]; return tiles; }
public void SetTileColor(TileRect r, Color c) { foreach (var tile in r) SetTileColor(tile, c); }
public void Initialize() { this.TileRect = new TileRect(Left, Bottom, Width, Height); }
public WorldRenderer(TileRect viewOfWorld, [NotNull] ISpriteBatch spriteBatch, [NotNull] ISpriteLibrary spriteLibrary) { this._viewOfWorld = viewOfWorld; this._spriteBatch = spriteBatch ?? throw new ArgumentNullException(nameof(spriteBatch)); this._spriteLibrary = spriteLibrary ?? throw new ArgumentNullException(nameof(spriteLibrary)); }