diff --git a/Sledgemapper.Api/sledgemapper.db b/Sledgemapper.Api/sledgemapper.db index 7f3ca7e..7c9664a 100644 Binary files a/Sledgemapper.Api/sledgemapper.db and b/Sledgemapper.Api/sledgemapper.db differ diff --git a/Sledgemapper.Shared/ExtensionMethods.cs b/Sledgemapper.Shared/ExtensionMethods.cs index d363d92..b1aa298 100644 --- a/Sledgemapper.Shared/ExtensionMethods.cs +++ b/Sledgemapper.Shared/ExtensionMethods.cs @@ -19,5 +19,7 @@ namespace SignalRChat.Hubs list[n] = value; } } + + } } \ No newline at end of file diff --git a/Sledgemapper/Sledgemapper.cs b/Sledgemapper/Sledgemapper.cs index 41eaee3..44ef91b 100644 --- a/Sledgemapper/Sledgemapper.cs +++ b/Sledgemapper/Sledgemapper.cs @@ -339,6 +339,66 @@ namespace Sledgemapper if (string.IsNullOrWhiteSpace(_sessionData.SessionName)) { + var isoffscreen = IsOffscreen(_state.SelectedTile); + if (isoffscreen) + { + var center = new Point((Window.ClientBounds.Width + 200) / 2 - (int)_viewportCenter.X, Window.ClientBounds.Height / 2 - (int)_viewportCenter.Y); + + var cx = center.X / _state.TileSize; + var cy = center.Y / _state.TileSize; + + var p1 = new Vector2(cx * _state.TileSize, cy * _state.TileSize); + var p2 = new Vector2(_state.SelectedTile.X * _state.TileSize, _state.SelectedTile.Y * _state.TileSize); + + var p3 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, 0 - _viewportCenter.Y); + var p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + var ua1 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(200 - _viewportCenter.X, 0 - _viewportCenter.Y); + p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, 0 - _viewportCenter.Y); + var ua2 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(200 - _viewportCenter.X, 0 - _viewportCenter.Y); + p4 = new Vector2(200 - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + var ua3 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(200 - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + var ua4 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + var uas = new List { ua1, ua2, ua3, ua4 }; + if (uas.Any(u => u > 0 && u < 1)) + { + + + var ua = uas.Where(u => u > 0 && u < 1).Min(); + + var i = uas.IndexOf(ua); + var x = (p1.X + ua * (p2.X - p1.X));// + _viewportCenter.X; + var y = (p1.Y + ua * (p2.Y - p1.Y));// + _viewportCenter.Y; + + switch (i) + { + case 0: + _spriteBatch.DrawPolygon(Vector2.Zero, new Vector2[] { new Vector2(x, y), new Vector2(x - 20, y + 10), new Vector2(x - 20, y - 10), new Vector2(x, y) }, Color.Red, 2); + break; + case 1: + y += 20; + _spriteBatch.DrawPolygon(Vector2.Zero, new Vector2[] { new Vector2(x, y), new Vector2(x - 10, y + 20), new Vector2(x + 10, y + 20), new Vector2(x, y) }, Color.Red, 2); + break; + case 2: + x += 0; + _spriteBatch.DrawPolygon(Vector2.Zero, new Vector2[] { new Vector2(x, y), new Vector2(x + 20, y + 10), new Vector2(x + 20, y - 10), new Vector2(x, y) }, Color.Red, 2); + break; + case 3: + y -= 20; + _spriteBatch.DrawPolygon(Vector2.Zero, new Vector2[] { new Vector2(x, y), new Vector2(x - 10, y - 20), new Vector2(x + 10, y - 20), new Vector2(x, y) }, Color.Red, 2); + break; + } + } + } + + _spriteBatch.DrawRectangle(new Rectangle((_state.SelectedTile.X * _state.TileSize) - 2, (_state.SelectedTile.Y * _state.TileSize) - 2, _state.TileSize + 3, _state.TileSize + 3), Color.Red, 2); } @@ -466,11 +526,9 @@ namespace Sledgemapper { foreach (var player in _sessionData.Players.Copy()) { - var hexs = player.Color.TrimStart('#').Split(2).ToArray(); - var color = new Color(int.Parse(hexs[0], System.Globalization.NumberStyles.HexNumber), - int.Parse(hexs[1], System.Globalization.NumberStyles.HexNumber), - int.Parse(hexs[2], System.Globalization.NumberStyles.HexNumber)); - _spriteBatch.DrawRectangle(new Rectangle( player.Position.X * _state.TileSize - 4 , player.Position.Y * _state.TileSize - 4 , _state.TileSize + 7 , _state.TileSize + 7), color, 2); + + var color = player.Color.ToColor(); + _spriteBatch.DrawRectangle(new Rectangle(player.Position.X * _state.TileSize - 4, player.Position.Y * _state.TileSize - 4, _state.TileSize + 7, _state.TileSize + 7), color, 2); var ffont = _fonts.FirstOrDefault(m => int.Parse(m.Key.Replace("font", "")) > _state.TileSize).Value ?? _fonts.Last().Value; @@ -485,6 +543,90 @@ namespace Sledgemapper SpriteEffects.None, 0); } + + + foreach (var player in _sessionData.Players.Copy()) + { + var isOffscreen = IsOffscreen(player.Position); + if (isOffscreen) + { + DrawPlayerPointer(player); + } + } + } + + private void DrawPlayerPointer(Player player) + { + var center = new Point((Window.ClientBounds.Width + 200) / 2 - (int)_viewportCenter.X, Window.ClientBounds.Height / 2 - (int)_viewportCenter.Y); + + var cx = center.X / _state.TileSize; + var cy = center.Y / _state.TileSize; + + var p1 = new Vector2(cx * _state.TileSize, cy * _state.TileSize); + var p2 = new Vector2(player.Position.X * _state.TileSize, player.Position.Y * _state.TileSize); + + var p3 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, 0 - _viewportCenter.Y); + var p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + var ua1 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(200 - _viewportCenter.X, 0 - _viewportCenter.Y); + p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, 0 - _viewportCenter.Y); + var ua2 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(200 - _viewportCenter.X, 0 - _viewportCenter.Y); + p4 = new Vector2(200 - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + var ua3 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + p3 = new Vector2(200 - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + p4 = new Vector2(Window.ClientBounds.Width - _viewportCenter.X, Window.ClientBounds.Height - _viewportCenter.Y); + var ua4 = ((p4.X - p3.X) * (p1.Y - p3.Y) - (p4.Y - p3.Y) * (p1.X - p3.X)) / ((p4.Y - p3.Y) * (p2.X - p1.X) - (p4.X - p3.X) * (p2.Y - p1.Y)); + + var uas = new List { ua1, ua2, ua3, ua4 }; + if (uas.Any(u => u > 0 && u < 1)) + { + var ua = uas.Where(u => u > 0 && u < 1).Min(); + var i = uas.IndexOf(ua); + var x = (p1.X + ua * (p2.X - p1.X));// + _viewportCenter.X; + var y = (p1.Y + ua * (p2.Y - p1.Y));// + _viewportCenter.Y; + Vector2[] vertexes = new Vector2[0]; + switch (i) + { + case 0: + vertexes = new Vector2[] { new Vector2(x, y), new Vector2(x - 20, y + 10), new Vector2(x - 20, y - 10), new Vector2(x, y) }; + break; + case 1: + y += 20; + vertexes = new Vector2[] { new Vector2(x, y), new Vector2(x - 10, y + 20), new Vector2(x + 10, y + 20), new Vector2(x, y) }; + break; + case 2: + x += 0; + vertexes = new Vector2[] { new Vector2(x, y), new Vector2(x + 20, y + 10), new Vector2(x + 20, y - 10), new Vector2(x, y) }; + break; + case 3: + y -= 20; + vertexes = new Vector2[] { new Vector2(x, y), new Vector2(x - 10, y - 20), new Vector2(x + 10, y - 20), new Vector2(x, y) }; + break; + } + _spriteBatch.DrawPolygon(Vector2.Zero, vertexes, player.Color.ToColor(), 2); + } + } + + private bool IsOffscreen(Tile position) + { + var visibleTilesX = GraphicsDevice.Viewport.Width / _state.TileSize + 1; + var visibleTilesY = GraphicsDevice.Viewport.Height / _state.TileSize + 1; + + var screenPositionTopLeft = new Point(200 - _state.TileSize + 0 * _state.TileSize - (int)_viewportCenter.X, 0 * _state.TileSize + _state.TileSize - (int)_viewportCenter.Y); + var screenPositionBottomRight = new Point(visibleTilesX * _state.TileSize - (int)_viewportCenter.X, visibleTilesY * _state.TileSize - 20 - (int)_viewportCenter.Y); + var tileTopLeft = new Point(screenPositionTopLeft.X / _state.TileSize, screenPositionTopLeft.Y / _state.TileSize); + var tileBottomRight = new Point(screenPositionBottomRight.X / _state.TileSize, screenPositionBottomRight.Y / _state.TileSize); + + if (position.X < tileTopLeft.X || position.Y < tileTopLeft.Y || position.X > tileBottomRight.X || position.Y > tileBottomRight.Y) + { + return true; + } + return false; + } private void DrawTiles() diff --git a/Sledgemapper/Utils.cs b/Sledgemapper/Utils.cs index f12a917..6a0cfd5 100644 --- a/Sledgemapper/Utils.cs +++ b/Sledgemapper/Utils.cs @@ -1,3 +1,4 @@ +using System.Linq; using Microsoft.Xna.Framework; namespace Sledgemapper @@ -14,5 +15,14 @@ namespace Sledgemapper b3 = Sign(pt, v3, v1) < 0.0f; return (b1 == b2) && (b2 == b3); } + + public static Color ToColor(this string s) + { + var hexs = s.TrimStart('#').Split(2).ToArray(); + var color = new Color(int.Parse(hexs[0], System.Globalization.NumberStyles.HexNumber), + int.Parse(hexs[1], System.Globalization.NumberStyles.HexNumber), + int.Parse(hexs[2], System.Globalization.NumberStyles.HexNumber)); + return color; + } } } \ No newline at end of file