diff --git a/MyGame/ExtensionMethods.cs b/MyGame/ExtensionMethods.cs new file mode 100644 index 0000000..6a3294f --- /dev/null +++ b/MyGame/ExtensionMethods.cs @@ -0,0 +1,32 @@ +// using MonoGame.Extended; +using System.Collections.Generic; +using System.IO; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework; +namespace MyGame +{ + public static class ExtensionMethods + { + public static Dictionary LoadContentFolder(this ContentManager contentManager, string contentFolder) + { + DirectoryInfo dir = new DirectoryInfo(contentManager.RootDirectory + "/" + contentFolder); + if (!dir.Exists) + throw new DirectoryNotFoundException(); + Dictionary result = new Dictionary(); + + FileInfo[] files = dir.GetFiles("*.*"); + foreach (FileInfo file in files) + { + result.Add(file.Name.Split('.')[0], contentManager.Load(contentFolder + "/" + file.Name.Split('.')[0])); + } + return result; + } + + public static Point AbsPoint(this Point point) +{ + return new Point(System.Math.Abs(point.X), System.Math.Abs(point.Y)); +} + } + +} + diff --git a/MyGame/Game1.cs b/MyGame/Game1.cs index 1293f68..2fba7e0 100644 --- a/MyGame/Game1.cs +++ b/MyGame/Game1.cs @@ -16,6 +16,13 @@ using Microsoft.Xna.Framework.Content; using Newtonsoft.Json; namespace MyGame { + public enum InsertMode + { + Tile, + Wall, + Overlay + } + public struct Tile { public int X { get; set; } @@ -42,12 +49,16 @@ namespace MyGame private List _map = new List(); private List _mapWalls = new List(); private Tile _selectedTile = new Tile { X = 1, Y = 1 }; + private Tile _hoveredTile = new Tile { X = 1, Y = 1 }; private Wall _selectedWall = new Wall { X = 1, Y = 1 }; - private int _tileSize = 60; + private int _tileSize = 30; HubConnection connection; private Desktop _desktop; private int _currentTileId = 1; + private int _currentWallId = 1; + + private InsertMode _insertMode; public Game1() { @@ -78,11 +89,8 @@ namespace MyGame } private string _session; - protected override void LoadContent() + private HorizontalMenu BuildMenu() { - _spriteBatch = new SpriteBatch(GraphicsDevice); - MyraEnvironment.Game = this; - var panel = new VerticalStackPanel(); var menu = new HorizontalMenu(); var menuFile = new MenuItem("_file", "File"); var menuFileLoad = new MenuItem("_file_load", "Load"); @@ -258,35 +266,51 @@ namespace MyGame menu.Items.Add(menuFile); menu.Items.Add(menuConnect); - panel.Widgets.Add(menu); + return menu; + } - _desktop.MenuBar = menu; - _desktop.MenuBar.Visible = true; - _desktop.MenuBar.Enabled = true; + protected override void LoadContent() + { + _spriteBatch = new SpriteBatch(GraphicsDevice); + MyraEnvironment.Game = this; - var panel2 = new Grid { Width = 200 }; - panel.Widgets.Add(panel2); - panel2.Background = new SolidBrush(Color.DarkGray); - panel2.Layout2d = new Myra.Graphics2D.UI.Properties.Layout2D("this.w=200;this.h=W.h"); + var mainPanel = new VerticalStackPanel(); - var folderContent = Content.LoadContentFolder("tiles"); + var menu = BuildMenu(); + mainPanel.Widgets.Add(menu); + + var sidePanel = new VerticalStackPanel { Layout2d = new Myra.Graphics2D.UI.Properties.Layout2D("this.w=200;this.h=W.h"), Background = new SolidBrush(Color.DarkGray) }; + var tileScrollView = new ScrollViewer { Layout2d = new Myra.Graphics2D.UI.Properties.Layout2D("this.w=200;this.h=W.h/3") }; + var tileGrid = new Grid { ColumnSpacing = 3, RowSpacing = 3, Layout2d = new Myra.Graphics2D.UI.Properties.Layout2D("this.w=200"), Background = new SolidBrush(Color.DarkGray) }; + tileScrollView.Content = tileGrid; + sidePanel.Widgets.Add(tileScrollView); + var wallScrollView = new ScrollViewer { Layout2d = new Myra.Graphics2D.UI.Properties.Layout2D("this.w=200;this.h=W.h/3") }; + var wallGrid = new Grid { ColumnSpacing = 3, RowSpacing = 3, Layout2d = new Myra.Graphics2D.UI.Properties.Layout2D("this.w=200"), Background = new SolidBrush(Color.DarkGray) }; + wallScrollView.Content = wallGrid; + sidePanel.Widgets.Add(wallScrollView); + // _desktop.MenuBar = menu; + // _desktop.MenuBar.Visible = true; + // _desktop.MenuBar.Enabled = true; + mainPanel.Widgets.Add(sidePanel); + + var tilesFolderContent = Content.LoadContentFolder("tiles"); var indexX = 0; var indexY = 0; - foreach (var item in folderContent) + + foreach (var item in tilesFolderContent) { - var tileButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key }; + var tileButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 }; tileButton.Click += (s, e) => { _currentTileId = int.Parse(((ImageButton)s).Id.Replace("tile", "")); - foreach (var widget in panel2.Widgets) - { - widget.Border = null; - } - ((ImageButton)s).Border = new SolidBrush(Color.Red); + ClearSelection(wallGrid); + ClearSelection(tileGrid); + ((ImageButton)s).Border = new SolidBrush(Color.Red); ((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2); + _insertMode = InsertMode.Tile; }; - panel2.Widgets.Add(tileButton); + tileGrid.Widgets.Add(tileButton); indexY++; if (indexY == 4) { @@ -295,15 +319,107 @@ namespace MyGame } } + var wallsFolderContent = Content.LoadContentFolder("walls"); + indexX = 0; + indexY = 0; + + foreach (var item in wallsFolderContent) + { + var wallButton = new ImageButton { Image = new TextureRegion(item.Value), GridColumn = indexY, GridRow = indexX, Id = item.Key, Width = 40, Height = 40 }; + wallButton.Click += (s, e) => + { + _currentWallId = int.Parse(((ImageButton)s).Id.Replace("wall", "")); + ClearSelection(wallGrid); + ClearSelection(tileGrid); + + + ((ImageButton)s).Border = new SolidBrush(Color.Red); + ((ImageButton)s).BorderThickness = new Myra.Graphics2D.Thickness(2); + _insertMode = InsertMode.Wall; + + }; + wallGrid.Widgets.Add(wallButton); + indexY++; + if (indexY == 4) + { + indexY = 0; + indexX++; + } + } + + + // Add it to the desktop // _desktop = new Desktop(); - _desktop.Root = panel; + _desktop.Root = mainPanel; // TODO: use this.Content to load your game content here } + + private void ClearSelection(Grid grid) + { + foreach (var widget in grid.Widgets) + { + widget.Border = null; + } + + } private KeyboardState oldState; private MouseState oldMouseState; private Vector3 _viewportCenter = new Vector3(0, 0, 0); + + + float Sign2(Point p1, Point p2, Point p3) { return (p1.X - p3.X) * (p2.Y - p3.Y) - (p2.X - p3.X) * (p1.Y - p3.Y); } + bool PointInTri(Point pt, Point v1, Point v2, Point v3) + { + bool b1, b2, b3; + b1 = Sign2(pt, v1, v2) < 0.0f; + b2 = Sign2(pt, v2, v3) < 0.0f; + b3 = Sign2(pt, v3, v1) < 0.0f; + return ((b1 == b2) && (b2 == b3)); + } + + + private void SelectClosestWall(Point mousePosition) + { + var topLeft = new Point(_hoveredTile.X * _tileSize, _hoveredTile.Y * _tileSize); + var bottomLeft = new Point(_hoveredTile.X * _tileSize, _hoveredTile.Y * _tileSize + _tileSize); + var topRight = new Point(_hoveredTile.X * _tileSize + _tileSize, _hoveredTile.Y * _tileSize); + var bottomRight = new Point(_hoveredTile.X * _tileSize + _tileSize, _hoveredTile.Y * _tileSize + _tileSize); + var center = new Point(_hoveredTile.X * _tileSize + _tileSize / 2, _hoveredTile.Y * _tileSize + _tileSize / 2); + System.Console.WriteLine($"{mousePosition.X} - {mousePosition.Y}"); + System.Console.WriteLine($"{_hoveredTile.X} - {_hoveredTile.Y}"); + var leftWall = PointInTri(mousePosition, topLeft, center, bottomLeft); + var rightWall = PointInTri(mousePosition, topRight, bottomRight, center); + var topWall = PointInTri(mousePosition, topLeft, topRight, center); + var bottomtWall = PointInTri(mousePosition, bottomLeft, center, bottomRight); + + if (leftWall) + { + _selectedWall.X = _hoveredTile.X; + _selectedWall.Y = _hoveredTile.Y; + _selectedWall.Rotation = 1; + } + else if (rightWall) + { + _selectedWall.X = _hoveredTile.X + 1; + _selectedWall.Y = _hoveredTile.Y; + _selectedWall.Rotation = 1; + } + else if (topWall) + { + _selectedWall.X = _hoveredTile.X; + _selectedWall.Y = _hoveredTile.Y; + _selectedWall.Rotation = 0; + } + else if (bottomtWall) + { + _selectedWall.X = _hoveredTile.X; + _selectedWall.Y = _hoveredTile.Y + 1; + _selectedWall.Rotation = 0; + } + } +private int scrollvalue=0; protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape)) @@ -312,18 +428,47 @@ namespace MyGame // TODO: Add your update logic here var mouseState = Mouse.GetState(); + + var screenPosition = new Point((mouseState.Position.X - (int)_viewportCenter.X), (mouseState.Position.Y - (int)_viewportCenter.Y)); + + _hoveredTile.X = screenPosition.X / _tileSize; + _hoveredTile.Y = screenPosition.Y / _tileSize; + if (screenPosition.X < 0) + { + _hoveredTile.X--; + } + if (screenPosition.Y < 0) + { + _hoveredTile.Y--; + } + SelectClosestWall(screenPosition); + + + + if (mouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton != oldMouseState.LeftButton) { - _selectedTile.X = (mouseState.Position.X - (int)_viewportCenter.X) / _tileSize; - _selectedTile.Y = (mouseState.Position.Y - (int)_viewportCenter.Y) / _tileSize; + _selectedTile.X = _hoveredTile.X; + _selectedTile.Y = _hoveredTile.Y; } if (newState.IsKeyDown(Keys.LeftControl) && mouseState.LeftButton == ButtonState.Pressed && mouseState.LeftButton != oldMouseState.LeftButton) { - _selectedTile.X = (mouseState.Position.X - (int)_viewportCenter.X) / _tileSize; - _selectedTile.Y = (mouseState.Position.Y - (int)_viewportCenter.Y) / _tileSize; - SetTile(_currentTileId); + switch (_insertMode) + { + case InsertMode.Tile: + _selectedTile.X = _hoveredTile.X; + _selectedTile.Y = _hoveredTile.Y; + SetTile(_currentTileId); + break; + + case InsertMode.Wall: + + SetWall(_currentWallId); + break; + } + } @@ -332,58 +477,19 @@ namespace MyGame _viewportCenter = new Vector3(_viewportCenter.X + mouseState.Position.X - oldMouseState.Position.X, _viewportCenter.Y + mouseState.Position.Y - oldMouseState.Position.Y, 0); } - _selectedTile.X = (mouseState.Position.X - (int)_viewportCenter.X) / _tileSize; - _selectedTile.Y = (mouseState.Position.Y - (int)_viewportCenter.Y) / _tileSize; - - System.Console.WriteLine($"mouse {mouseState.Position.X} - {mouseState.Position.Y}"); - System.Console.WriteLine($"topleft {_selectedTile.X * _tileSize} - {_selectedTile.Y * _tileSize}"); - - var leftWall = PointInTriangle(mouseState.Position, - new Point(_selectedTile.X * _tileSize, _selectedTile.Y * _tileSize), - new Point(_selectedTile.X * _tileSize, _selectedTile.Y * _tileSize + _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize / 2, _selectedTile.Y * _tileSize + _tileSize / 2)); - - var rightWall = PointInTriangle(mouseState.Position, - new Point(_selectedTile.X * _tileSize + _tileSize, _selectedTile.Y * _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize, _selectedTile.Y * _tileSize + _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize / 2, _selectedTile.Y * _tileSize + _tileSize / 2)); - - var topWall = PointInTriangle(mouseState.Position, - new Point(_selectedTile.X * _tileSize, _selectedTile.Y * _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize, _selectedTile.Y * _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize / 2, _selectedTile.Y * _tileSize + _tileSize / 2)); - - var bottomtWall = PointInTriangle(mouseState.Position, - new Point(_selectedTile.X * _tileSize, _selectedTile.Y * _tileSize + _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize, _selectedTile.Y * _tileSize + _tileSize), - new Point(_selectedTile.X * _tileSize + _tileSize / 2, _selectedTile.Y * _tileSize + _tileSize / 2)); - - if (leftWall) + if (newState.IsKeyDown(Keys.LeftControl) && mouseState.ScrollWheelValue!=oldMouseState.ScrollWheelValue) { - _selectedWall.X = _selectedTile.X; - _selectedWall.Y = _selectedTile.Y; - _selectedWall.Rotation = 1; - } - else if (rightWall) - { - _selectedWall.X = _selectedTile.X + 1; - _selectedWall.Y = _selectedTile.Y; - _selectedWall.Rotation = 1; - } - else if (topWall) - { - _selectedWall.X = _selectedTile.X; - _selectedWall.Y = _selectedTile.Y; - _selectedWall.Rotation = 0; - } - else if (bottomtWall) - { - _selectedWall.X = _selectedTile.X; - _selectedWall.Y = _selectedTile.Y + 1; - _selectedWall.Rotation = 0; + if (mouseState.ScrollWheelValue>oldMouseState.ScrollWheelValue) + { + _tileSize=System.Math.Min(120, _tileSize+10); + + } + else if (mouseState.ScrollWheelValue m.X == _selectedWall.X && m.Y == _selectedWall.Y && m.Rotation == _selectedWall.Rotation); + if (tileExist) + { + var wall = _mapWalls.First(m => m.X == _selectedWall.X && m.Y == _selectedWall.Y && m.Rotation == _selectedWall.Rotation); + var index = _mapWalls.IndexOf(wall); + _mapWalls.RemoveAt(index); + + _mapWalls.Add(new Wall { X = _selectedWall.X, Y = _selectedWall.Y, ID = wallId, Rotation = _selectedWall.Rotation }); + + } + else + { + _mapWalls.Add(new Wall { X = _selectedWall.X, Y = _selectedWall.Y, ID = wallId, Rotation = _selectedWall.Rotation }); + + //connection?.InvokeAsync("SendMessage", $"{_selectedTile.X}:{_selectedTile.Y}", tileId.ToString(), _session); + } + } + protected override void Draw(GameTime gameTime) { if (_spriteBatch is null) @@ -504,31 +629,32 @@ namespace MyGame var content = Content.Load($"tiles/tile{tile.ID.ToString().PadLeft(2, '0')}"); var destinationRectangle = new Rectangle(tile.X * _tileSize, tile.Y * _tileSize, _tileSize, _tileSize); - // _spriteBatch.Draw( - // content, - // destinationRectangle, - // null, - // Color.White, - // MathHelper.ToRadians(90*tile.Rotation), - // new Vector2(tile.X*_tileSize+_tileSize/2f, tile.Y*_tileSize+_tileSize/2f), - // SpriteEffects.None, - // 1); var posX = tile.X * _tileSize + _tileSize / 2f; var posY = tile.Y * _tileSize + _tileSize / 2f; _spriteBatch.Draw(content, new Vector2(posX, posY), - null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), 1, SpriteEffects.None, 0); + null, Color.White, MathHelper.ToRadians(90 * tile.Rotation), new Vector2(content.Width / 2, content.Height / 2), ((float)_tileSize - 1) / (float)content.Width, SpriteEffects.None, 0); + } - // _spriteBatch.Draw( - // content, - // destinationRectangle, - // null, - // Color.White,MathHelper.ToRadians(90*tile.Rotation),new Vector2(destinationRectangle.X,destinationRectangle.Y) - // ); + foreach (var wall in _mapWalls) + { - //var rf = new RectangleF(tile.X*_tileSize,tile.Y*_tileSize,_tileSize,_tileSize); + var content = Content.Load($"walls/wall{wall.ID.ToString().PadLeft(2, '0')}"); + var scale = (float)_tileSize / (float)content.Height; + var offset = scale * (float)content.Width / 2f; + var posX = wall.X * _tileSize; + var posY = wall.Y * _tileSize; + if (wall.Rotation == 1) + { + posX -= (int)offset; + } + else if (wall.Rotation == 0) + { + posY += (int)offset; + } +// _spriteBatch.Draw(content, new Vector2(posX, posY),null, Color.White, MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(offset, 0), scale, SpriteEffects.None, 0); + _spriteBatch.Draw(content, new Vector2(posX, posY),null, Color.White, MathHelper.ToRadians(90 * (wall.Rotation - 1)), new Vector2(0, 0), scale, SpriteEffects.None, 0); - // _spriteBatch.DrawRectangle(rf,Color.Red,3,0); } @@ -536,8 +662,10 @@ namespace MyGame var startWall = new Vector2(_selectedWall.X * _tileSize, _selectedWall.Y * _tileSize); - - _spriteBatch.DrawLine(startWall, _tileSize, MathHelper.ToRadians(90 * _selectedWall.Rotation), Color.Red, 2); + if (_insertMode == InsertMode.Wall) + { + _spriteBatch.DrawLine(startWall, _tileSize, MathHelper.ToRadians(90 * _selectedWall.Rotation), Color.Red, 2); + } _spriteBatch.End(); @@ -565,24 +693,4 @@ namespace MyGame return !(has_neg && has_pos); } } - - public static class ExtensionMethods - { - public static Dictionary LoadContentFolder(this ContentManager contentManager, string contentFolder) - { - DirectoryInfo dir = new DirectoryInfo(contentManager.RootDirectory + "/" + contentFolder); - if (!dir.Exists) - throw new DirectoryNotFoundException(); - Dictionary result = new Dictionary(); - - FileInfo[] files = dir.GetFiles("*.*"); - foreach (FileInfo file in files) - { - result.Add(file.Name.Split('.')[0], contentManager.Load(contentFolder + "/" + file.Name.Split('.')[0])); - } - return result; - } - - - } }