public Grid(IEnumerable <GamePiece> tiles, Vector2u gridSize, Vector2f scale, uint gridLayers = 1, DragManager mouseManager = null, int dragLayer = -1, int dropLayer = -1, Vector2f dropScale = default, Vector2u cellSize = default) { if (dropScale == default) { dropScale = scale; } window = mouseManager.Window; if (tiles == null) { this.tiles = new List <GamePiece>(); } else { this.tiles = tiles.ToList(); } this.mapSize = gridSize; this.scale = scale; mapLayers = gridLayers; map = new int[gridSize.X, gridSize.Y, gridLayers]; if (cellSize == default) { tileSize = this.tiles[0].TextureRect.GetSize().ToVector2f(); } else { tileSize = (Vector2f)cellSize; } // apply scale to tiles for (var i = 0; i < this.tiles.Count; i++) { this.tiles[i].Scale = scale; } size = new Vector2f(gridSize.X * tileSize.X, gridSize.Y * tileSize.Y); scaledSize = new Vector2f(Size.X * scale.X, Size.Y * scale.Y); scaledTileSize = new Vector2f(tileSize.X * scale.X, tileSize.Y * scale.Y); // init map for (var z = 0; z < mapLayers; z++) { for (var y = 0; y < mapSize.Y; y++) { for (var x = 0; x < mapSize.X; x++) { map[x, y, z] = -1; } } } // mouse if (mouseManager != null) { if (dragLayer != -1) { GamePiece picked = null; int pickedIndex = -1; Action <Sprite> dropHandled = null; Vector2f dragOffset = default; Vector2i pickCoords = default; mouseManager.DragStart += (object sender, DragEventArgs e) => { if (Enabled) { if (e.Button == Mouse.Button.Left && e.DragStart.X >= Rect.Left && e.DragStart.Y >= Rect.Top && e.DragStart.X < Rect.Left + Rect.Width && e.DragStart.Y < Rect.Top + Rect.Height) { picked = SpritePicker(e.DragStart, dragLayer, out pickCoords); if (picked != null) { moves = GetMoves(picked, pickCoords); movesOccupied = GetMovesOccupied(picked, pickCoords); Debug.WriteLine($"[Grid] Picked {pickCoords.X},{pickCoords.Y}"); pickedIndex = map[pickCoords.X, pickCoords.Y, dragLayer]; dropHandled = sprite => { //map[pickCoords.X, pickCoords.Y, dragLayer] = -1; }; picked.Color = new Color(255, 255, 255, 0); draggingSprite = new GamePiece(picked); draggingSprite.Color = new Color(255, 255, 255, 200); dragOffset = (e.DragStart.ToVector2f() - draggingSprite.Position) * -1; // empty origial area var subgridSize = getSubGridSizeOfTile(picked); for (var y = 0; y < subgridSize.Y; y++) { for (var x = 0; x < subgridSize.X; x++) { map[pickCoords.X + x, pickCoords.Y + y, dragLayer] = -1; } } } } } }; mouseManager.Dragging += (object sender, DragEventArgs e) => { if (Enabled && draggingSprite != null) { var dp = e.DragCurrent.ToVector2f(); draggingSprite.Position = dp + dragOffset; } }; mouseManager.DragEnd += (object sender, DragEventArgs e) => { if (Enabled) { if (picked != null) { picked.Color = new Color(255, 255, 255, 255); picked = null; moves = null; movesOccupied = null; } if (draggingSprite != null) { if (!mouseManager.Drop(this, draggingSprite, dropHandled, e)) { // if the drop was unhandled, restore the item to its original location var subgridSize = getSubGridSizeOfTile(draggingSprite); if (subgridSize.X > 1 || subgridSize.Y > 1) { for (var y = 0; y < subgridSize.Y; y++) { for (var x = 0; x < subgridSize.X; x++) { map[pickCoords.X + x, pickCoords.Y + y, dropLayer] = pickedIndex - int.MinValue; } } } map[pickCoords.X, pickCoords.Y, dropLayer] = pickedIndex; } draggingSprite = null; } } }; } if (dropLayer != -1) { mouseManager.Dropped += (object sender, DropEventArgs e) => { if (Enabled) { if (e.DragStop.X >= Rect.Left && e.DragStop.Y >= Rect.Top && e.DragStop.X < Rect.Left + Rect.Width && e.DragStop.Y < Rect.Top + Rect.Height) { var p = e.Sprite.GetGlobalBounds().GetCenter().ToVector2i() + new Vector2i(0, 32); // move the drop point down so it is centered on the base of the chess piece //var p = (Vector2i)(e.Sprite.Position + (cellSize.ToVector2f() / 2.0f)); var tpi = ScreenToGridCoordinates(p); Debug.WriteLine($"[Grid] Dropped {tpi.X},{tpi.Y}"); var subgridSize = getSubGridSizeOfTile(e.Sprite); if (tpi.X >= 0 && tpi.X + (subgridSize.X - 1) < mapSize.X && tpi.Y >= 0 && tpi.Y + (subgridSize.Y - 1) < mapSize.Y) { var obstacleFound = false; /* * for (var y=tpi.Y; y<tpi.Y+subgridSize.Y; y++){ * for (var x=tpi.X; x<tpi.X+subgridSize.X; x++){ * if (map[x, y, dropLayer] != -1){ * obstacleFound=true; * break; * } * } * } */ // check if move is valid according to board state if (!obstacleFound) { obstacleFound = !IsMoveAllowed(e.Sprite, ScreenToGridCoordinates(e.DragStart), tpi); } //var index = map[tpi.X, tpi.Y, dropLayer]; //if (index == -1) if (!obstacleFound) { e.Sprite.Color = new Color(255, 255, 255, 255); if (!this.tiles.Contains(e.Sprite)) { this.tiles.Add(e.Sprite); } var tileIndex = this.tiles.IndexOf(e.Sprite); // if this item is larger than 1x1 fill the other grid cells with "shadow" indeces // so that items will not be able to overlap if (subgridSize.X > 1 || subgridSize.Y > 1) { for (var y = 0; y < subgridSize.Y; y++) { for (var x = 0; x < subgridSize.X; x++) { map[tpi.X + x, tpi.Y + y, dropLayer] = tileIndex - int.MinValue; } } } map[tpi.X, tpi.Y, dropLayer] = tileIndex; e.Sprite.Scale = dropScale; if (e.OnHandled != null) { e.OnHandled.Invoke(e.Sprite); e.Handled = true; OnMoved(); } } } } } }; } } moveMarker = new CircleShape(13); moveMarker.OutlineThickness = 1; moveMarker.FillColor = new Color(0, 0, 0, 64); moveMarker.OutlineColor = new Color(0, 0, 0, 32); moveMarker.Origin = moveMarker.GetGlobalBounds().GetCenter(); moveMarkerOccupied = new CircleShape(24); moveMarkerOccupied.FillColor = new Color(0, 0, 0, 0); moveMarkerOccupied.OutlineThickness = 6; moveMarkerOccupied.OutlineColor = new Color(0, 0, 0, 64); moveMarkerOccupied.Origin = moveMarkerOccupied.GetGlobalBounds().GetCenter(); }
static void Main(string[] args) { //perfTest();return; var appStartTime = DateTime.Now; RenderWindow window = new RenderWindow(new VideoMode(768, 768), "Derpy Chess"); window.SetFramerateLimit(40); window.SetActive(); window.Closed += (object sender, EventArgs e) => window.Close(); var parchment = FileSystem.LoadSprite("./data/parchment.png"); var backgroundSprite = FileSystem.LoadSprite("./data/background_512x512.png"); var vignette = FileSystem.LoadSprite("./data/vignette_512x512.png"); var mouseManager = new DragManager(window); var storybookFont = FileSystem.LoadFont("./data/storybook.ttf"); var oldenglishFont = FileSystem.LoadFont("./data/oldenglish.ttf"); var boardSprite = FileSystem.LoadSprite("./data/board_512x552.png"); var blackSprites = FileSystem.LoadTiles("./data/black2_128x128.png", 128, 128); var whiteSprites = FileSystem.LoadTiles("./data/white3_128x128.png", 128, 128); var pixelFont = FileSystem.LoadFont("./data/rainyhearts.ttf"); GameBoard board = new GameBoard(boardSprite, blackSprites, whiteSprites, pixelFont, new Vector2f(), new Vector2u(8, 8), new Vector2f(1, 1), 1, mouseManager, 0, 0, new Vector2f(1, 1), new Vector2u(64, 64));; var busyIndicator = new BusyIndicator(); var resize = new Action <float, float>((float width, float height) => { window.SetView(new View(new FloatRect(0, 0, width, height))); vignette.Scale = window.Size.ToVector2f().Div(vignette.TextureRect.GetSize().ToVector2f()); board.Position = ((window.Size.ToVector2f() * 0.5f) - (boardSprite.TextureRect.GetSize().ToVector2f() * 0.5f)) + new Vector2f(0, 16); parchment.Position = (window.Size.ToVector2f() * 0.5f) - (parchment.TextureRect.GetSize().ToVector2f() * 0.5f); busyIndicator.Position = new Vector2f(window.Size.X / 2, board.Position.Y - 72); }); resize(window.Size.X, window.Size.Y); window.Resized += (object sender, SizeEventArgs e) => resize(e.Width, e.Height); // --- logo ----------- var logo = FileSystem.LoadSprite("./data/retrodactyl_logo.png"); logo.Scale = new Vector2f(2, 2); logo.Origin = logo.TextureRect.GetSize().ToVector2f() * 0.5f; logo.Position = window.Size.ToVector2f() * 0.5f - new Vector2f(0, 25); logo.Color = new Color(255, 255, 255, 0); var viewingLogo = true; var logoFade = false; DateTime logoFadeStart = DateTime.MaxValue; while (window.IsOpen && viewingLogo) { window.Clear(new Color(0xe5f1fdff)); window.DispatchEvents(); logo.Draw(window, RenderStates.Default); window.Display(); if ((Keyboard.IsKeyPressed(Keyboard.Key.Enter) || Keyboard.IsKeyPressed(Keyboard.Key.Space) || Mouse.IsButtonPressed(Mouse.Button.Left))) { logoFade = true; logoFadeStart = DateTime.MinValue; } if (logoFade && logoFadeStart < DateTime.Now) { logo.Color -= new Color(0, 0, 0, 5); if (logo.Color.A < 1) { viewingLogo = false; } } if (!logoFade) { logo.Color += new Color(0, 0, 0, 5); if (logo.Color.A >= 254) { logoFadeStart = DateTime.Now + TimeSpan.FromSeconds(2); logoFade = true; } } } // ---- story --------------------------------------------------------------------------------------- /* * var storybookText = new Text(); * storybookText.Font = oldenglishFont; * storybookText.FillColor = new Color(48,32,32, 200); * storybookText.OutlineColor = new Color(48, 32, 32, 64); * storybookText.OutlineThickness = 1; * storybookText.CharacterSize = 48; * storybookText.DisplayedString = * "Once upon a time," + Environment.NewLine + * "there was a dude who" + Environment.NewLine + * "liked to play chess but" + Environment.NewLine + * "really sucked at it..." + Environment.NewLine + Environment.NewLine + * "He never enjoyed chess" + Environment.NewLine + * "because he never won." + Environment.NewLine + Environment.NewLine + * "This game is dedicated" + Environment.NewLine + * "to that guy."; * * storybookText.Position = parchment.Position + new Vector2f(80,64); * * bool viewingStory = true; * bool storyFade = false; * while (window.IsOpen && viewingStory) * { * window.Clear(); * window.DispatchEvents(); * * for (var y = 0; y < window.Size.Y; y += backgroundSprite.TextureRect.Height) * { * for (var x = 0; x < window.Size.X; x += backgroundSprite.TextureRect.Width) * { * backgroundSprite.Position = new Vector2f(x, y); * backgroundSprite.Draw(window, RenderStates.Default); * } * } * vignette.Draw(window, RenderStates.Default); * parchment.Draw(window, RenderStates.Default); * storybookText.Draw(window, RenderStates.Default); * window.Display(); * * if ((Keyboard.IsKeyPressed(Keyboard.Key.Enter) || Keyboard.IsKeyPressed(Keyboard.Key.Space) || Mouse.IsButtonPressed(Mouse.Button.Left))) * { * storyFade = true; * } * if (storyFade) { * parchment.Color -= new Color(0, 0, 0, 3); * storybookText.FillColor -= new Color(0, 0, 0, 4); * storybookText.OutlineColor -= new Color(0, 0, 0, 4); * if (parchment.Color.A < 1) * { * viewingStory = false; * } * } * } */ // --- title ------------------------------------------------------------------------------------ var titleText = new Text(); titleText.Font = oldenglishFont; titleText.FillColor = new Color(48, 32, 32, 200); titleText.OutlineColor = new Color(48, 32, 32, 64); titleText.OutlineThickness = 1; titleText.CharacterSize = 92; titleText.DisplayedString = "Derpy Chess"; titleText.Position = new Vector2f(10 + parchment.GetGlobalBounds().GetCenter().X - titleText.GetGlobalBounds().GetCenter().X, parchment.Position.Y + 64); var playGameText = new Text(); playGameText.Font = oldenglishFont; playGameText.FillColor = new Color(48, 32, 32, 200); playGameText.OutlineColor = new Color(48, 32, 32, 64); playGameText.OutlineThickness = 1; playGameText.CharacterSize = 48; playGameText.DisplayedString = "Play Game"; //playGameText.Origin = playGameText.GetGlobalBounds().GetSize() * 0.5f; //playGameText.Position = window.Size.ToVector2f() * 0.5f; playGameText.Position = new Vector2f(10, 0) + parchment.GetGlobalBounds().GetCenter() - playGameText.GetGlobalBounds().GetCenter(); bool viewingTitle = true; bool titleFade = false; while (window.IsOpen && viewingTitle) { window.Clear(); window.DispatchEvents(); for (var y = 0; y < window.Size.Y; y += backgroundSprite.TextureRect.Height) { for (var x = 0; x < window.Size.X; x += backgroundSprite.TextureRect.Width) { backgroundSprite.Position = new Vector2f(x, y); backgroundSprite.Draw(window, RenderStates.Default); } } vignette.Draw(window, RenderStates.Default); parchment.Draw(window, RenderStates.Default); titleText.Draw(window, RenderStates.Default); playGameText.Draw(window, RenderStates.Default); window.Display(); if ((Keyboard.IsKeyPressed(Keyboard.Key.Enter) || Keyboard.IsKeyPressed(Keyboard.Key.Space) || Mouse.IsButtonPressed(Mouse.Button.Left))) { titleFade = true; } if (titleFade) { parchment.Color -= new Color(0, 0, 0, 3); titleText.FillColor -= new Color(0, 0, 0, 4); titleText.OutlineColor -= new Color(0, 0, 0, 4); playGameText.FillColor -= new Color(0, 0, 0, 4); playGameText.OutlineColor -= new Color(0, 0, 0, 4); if (parchment.Color.A < 1) { viewingTitle = false; } } else { parchment.Color += new Color(0, 0, 0, 3); if (playGameText.GetGlobalBounds().Contains(Mouse.GetPosition(window))) { playGameText.FillColor = new Color(150, 0, 32, 200); playGameText.OutlineColor = new Color(150, 0, 32, 64); } else { playGameText.FillColor = new Color(48, 32, 32, 200); playGameText.OutlineColor = new Color(48, 32, 32, 64); } } } // --- game ------------------------------------------------------------------------ var debugText = new Text(); debugText.Font = storybookFont; debugText.FillColor = new Color(0, 255, 0, 255); debugText.CharacterSize = 16; if (window.IsOpen) { // play game var endgameText = new Text(); endgameText.Font = storybookFont; endgameText.FillColor = Color.White; endgameText.OutlineColor = Color.Black; endgameText.OutlineThickness = 2; endgameText.CharacterSize = 48; endgameText.DisplayedString = "Checkmate!"; board.Enabled = true; while (window.IsOpen) { window.Clear(); window.DispatchEvents(); for (var y = 0; y < window.Size.Y; y += backgroundSprite.TextureRect.Height) { for (var x = 0; x < window.Size.X; x += backgroundSprite.TextureRect.Width) { backgroundSprite.Position = new Vector2f(x, y); backgroundSprite.Draw(window, RenderStates.Default); } } vignette.Draw(window, RenderStates.Default); board.Draw(window, RenderStates.Default); busyIndicator.Visible = board.aiThinking; busyIndicator.Draw(window, RenderStates.Default); if (board.GameEndText != null) { endgameText.DisplayedString = board.GameEndText; var textBounds = endgameText.GetGlobalBounds(); endgameText.Position = new Vector2f( (window.Size.X * 0.5f) - (textBounds.Width * 0.5f), window.Size.Y - textBounds.Height - 32);//(window.Size.Y * 0.5f) - (textBounds.Height * 0.5f)); endgameText.Draw(window, RenderStates.Default); } // debug view if (Keyboard.IsKeyPressed(Keyboard.Key.D)) //#if DEBUG { var labels = new[] { "A", "B", "C", "D", "E", "F", "G", "H", "8", "7", "6", "5", "4", "3", "2", "1" }; int i = 0; for (var x = board.Position.X; x < board.Position.X + board.Rect.Width; x += board.Rect.Width / 8) { debugText.DisplayedString = labels[i++]; debugText.Position = new Vector2f(x + 32 - debugText.GetGlobalBounds().Width * 0.5f, board.Position.Y - 32 - debugText.GetGlobalBounds().Height * 0.5f); debugText.Draw(window, RenderStates.Default); debugText.Position = new Vector2f(x + 32 - debugText.GetGlobalBounds().Width * 0.5f, board.Position.Y + board.Rect.Height + 32 - debugText.GetGlobalBounds().Height * 0.5f); debugText.Draw(window, RenderStates.Default); } for (var y = board.Position.Y; y < board.Position.Y + board.Rect.Height; y += board.Rect.Height / 8) { debugText.DisplayedString = labels[i++]; debugText.Position = new Vector2f(board.Position.X - 32 - debugText.GetGlobalBounds().Width * 0.5f, y + 32 - debugText.GetGlobalBounds().Height * 0.5f); debugText.Draw(window, RenderStates.Default); debugText.Position = new Vector2f(board.Position.X + board.Rect.Width + 32 - debugText.GetGlobalBounds().Width * 0.5f, y + 32 - debugText.GetGlobalBounds().Height * 0.5f); debugText.Draw(window, RenderStates.Default); } } //#endif window.Display(); } } }
public GameBoard(Sprite board, Sprite[] black, Sprite[] white, Font labelFont, Vector2f position, Vector2u gridSize, Vector2f scale, uint gridLayers = 1, DragManager mouseManager = null, int dragLayer = -1, int dropLayer = -1, Vector2f dropScale = default, Vector2u cellSize = default) : base(null, gridSize, scale, gridLayers, mouseManager, dragLayer, dropLayer, dropScale, cellSize) { font = labelFont; boardSquareLabel = new Text("", font, 17); //boardSquareLabel.Style = Text.Styles.Bold; boardSquareLabel.OutlineThickness = 1; boardSprite = board; Position = position; chessBoard = new Board(true); //chessBoard = new Board("rnb1k1nr/ppppbppp/8/4Q3/8/4P3/PPP2qPP/RNB1KBNR w 11"); /*** setup "tiles" (the game piece sprites) ******************************************/ blackRook = new Sprite(black[11]); blackBishop = new Sprite(black[00]); blackKnight = new Sprite(black[06]); blackQueen = new Sprite(black[10]); blackKing = new Sprite(black[08]); blackPawn = new Sprite(black[12]); whitePawn = new Sprite(white[12]); whiteRook = new Sprite(white[11]); whiteBishop = new Sprite(white[00]); whiteKnight = new Sprite(white[05]); whiteQueen = new Sprite(white[10]); whiteKing = new Sprite(white[08]); //shadow = new Sprite(black[13]); blackPieces = new Dictionary <int, Sprite>() { { PieceType.Bishop, blackBishop }, { PieceType.King, blackKing }, { PieceType.Knight, blackKnight }, { PieceType.Pawn, blackPawn }, { PieceType.Queen, blackQueen }, { PieceType.Rook, blackRook }, }; whitePieces = new Dictionary <int, Sprite>() { { PieceType.Bishop, whiteBishop }, { PieceType.King, whiteKing }, { PieceType.Knight, whiteKnight }, { PieceType.Pawn, whitePawn }, { PieceType.Queen, whiteQueen }, { PieceType.Rook, whiteRook }, }; updateBoardFromGameState(); }