// vracia objekty puzzle novych kuskov, este bez pociatocnych nastaveni public static void CreatePieces(PuzzleGameData data) { int pocetKuskov = data.PiecesCount; data.Pieces = new List <PuzzlePiece>(); for (int i = 0; i < pocetKuskov; i++) { data.Pieces.Add(new PuzzlePiece()); data.Pieces[i].ID = i; data.Pieces[i].SizeOfPieceImage = new Size(data.PieceDimensions.Width + 2 * data.PieceSurroundingSize, data.PieceDimensions.Height + 2 * data.PieceSurroundingSize); data.Pieces[i].SizeOfPiece = data.PieceDimensions; // zatial nie je spojeny s dalsimi kuskami data.Pieces[i].LeftNeighbor = null; data.Pieces[i].TopNeighbor = null; data.Pieces[i].RightNeighbor = null; data.Pieces[i].BottomNeighbor = null; // povodni susedia, nastavime neskor pomocou SetPiecesOriginalNeighbours() data.Pieces[i].OriginalLeftNeighbor = null; data.Pieces[i].OriginalTopNeighbor = null; data.Pieces[i].OriginalRightNeighbor = null; data.Pieces[i].OriginalBottomNeighbor = null; // ci su kusky na spravnom mieste data.Pieces[i].IsInTheRightPlace_Current = false; data.Pieces[i].IsInTheRightPlace_Final = false; data.Pieces[i].VisitState = false; } }
// prednastavi objekty reprezentujuce jednotlive kusky, obrazok kusku, pozicia, kolizne miesta, ... public static void SetPiecesImages(PuzzleGameData data) { //Vytvorime pole vykrojenych obrazkov pre puzzle kusky Bitmap[] puzzleShapes = CreatePuzzleShapeImagesFromSourceImage(data); //Vykrojene obrazky aplikujeme na kusky for (int i = 0; i < data.PiecesCount; i++) { data.Pieces[i].PieceImage = puzzleShapes[i]; } }
// pozicia puzzle kuska vramci poskladaneho puzzle, pouzite pri vypocte spravnosti zlozenych kuskov public static void SetOriginalPiecesLocations(PuzzleGameData data) { Point[] locations = GenerateOriginalPiecesLocations(data.GameBoardStartPosition, data.PieceDimensions, data.PieceSurroundingSize, data.PiecesGridDimensions); for (int i = 0; i < data.PiecesCount; i++) { data.Pieces[i].OriginalPosition = locations[i]; data.Pieces[i].CurrentPosition = locations[i]; } }
// vystrihne jednotlive kusku zo zdrojoveho obrazka za pomoci metody CreatePuzzleShapePath private static Bitmap[] CreatePuzzleShapeImagesFromSourceImage(PuzzleGameData data) { Bitmap[] pShapes = new Bitmap[data.PiecesCount]; //Pre zjednodesenie vyrezavania pridame hranu hrubky SurroundingSize okolo zdrojoveho obrazka, //sourceImage == obrazok + hrany dookola int hrubkaHrany = data.PieceSurroundingSize; int gridWidth = data.PiecesGridDimensions.Width; int gridheight = data.PiecesGridDimensions.Height; int pieceWidth = data.PieceDimensions.Width; int pieceHeight = data.PieceDimensions.Height; Bitmap sourceImage = new Bitmap(data.SourcePicture.Width + 2 * hrubkaHrany, data.SourcePicture.Height + 2 * hrubkaHrany); using (Graphics draw = Graphics.FromImage(sourceImage)) { draw.DrawImage(data.SourcePicture, new Point(hrubkaHrany, hrubkaHrany)); } //Vyrezavanie jednotlivych kuskov int x = 0, y = 0; //Point startP = new Point(x, y); //Point endP = new Point((x + pieceWidth + 2 * hrubkaHrany), // (y + pieceHeight + 2 * hrubkaHrany)); GraphicsPath shapePath; int index; for (int j = 0; j < gridheight; j++) { for (int i = 0; i < gridWidth; i++) { index = j * gridWidth + i; pShapes[index] = PictureEditor.CropImage(sourceImage, new Point(x, y), new Point((x + pieceWidth + 2 * hrubkaHrany), (y + pieceHeight + 2 * hrubkaHrany))); shapePath = CreatePuzzleShapePath(hrubkaHrany, data.PieceDimensions, data.Pieces[index].Arrangement); pShapes[index] = PieceCutter.CutOut(pShapes[index], shapePath); x += pieceWidth; } x = 0; y += pieceHeight; } return(pShapes); }
// nastavi jednotlivym kuskom ich tvary stran public static void SetPiecesArrangement(PuzzleGameData data) { if (data.Pieces != null) { PieceArrangement[] arrang = GeneratePiecesArrangement(data.PiecesGridDimensions); for (int i = 0; i < data.PiecesCount; i++) { data.Pieces[i].Arrangement = arrang[i]; } } else { MessageBox.Show("Neboli vytvorene instancie PuzzlePiece!", "Runtime Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
//pre kazdy kusok nastavi ich originalnych susedov public static void SetPiecesOriginalNeighbours(PuzzleGameData data) { int indexCurrPiece; int gridWidth = (data.PiecesGridDimensions.Width - 1); int gridHeight = (data.PiecesGridDimensions.Height - 1); int maxArrayIndex = (data.PiecesCount - 1); List <PuzzlePiece> pieces = data.Pieces; for (int j = 0; j < (data.PiecesGridDimensions.Height - 1); j++) { for (int i = 0; i < (data.PiecesGridDimensions.Width - 1); i++) { // jednorozmere pole prechadzame ako dvojrozmerne indexCurrPiece = (j * gridWidth + i); // up neighbour if ((indexCurrPiece - gridWidth) >= 0) { pieces[indexCurrPiece].OriginalTopNeighbor = pieces[indexCurrPiece - gridWidth]; } // right neighbour if ((i + 1) <= gridWidth) { pieces[indexCurrPiece].OriginalRightNeighbor = pieces[indexCurrPiece + 1]; } // down neighbour if ((indexCurrPiece + gridWidth) <= maxArrayIndex) { pieces[indexCurrPiece].OriginalBottomNeighbor = pieces[indexCurrPiece + gridWidth]; } // left neighbour if ((i - 1) >= 0) { pieces[indexCurrPiece].OriginalLeftNeighbor = pieces[indexCurrPiece - 1]; } } } }
// Button = nova hra, zahodia sa objekty reprezentujuce staru hru, prednastavenia pred dalsou hrou private void button4_Click(object sender, EventArgs e) { // zoomLabel odstranime z panelu3 (tenky pasik) this.panel3.Controls.Clear(); // gameboard sa prestane zobrazovat v panel-y this.gameboard.Visible = false; // odoberieme gameboard z panela, pred tym nez ho zahodime this.panel4.Controls.Remove(PuzzleGameUtilities.ControlByName(panel4, "gameboard")); // zahodime staru hraciu plochu gameboard = null; // zahodime stare data pre hru gameData = null; // vytvorime nove data pre hru gameData = new PuzzleGameData(); // naspat zobrazime controls pre vyber obrazka textBox1.Visible = true; textBox1.Text = ""; pictureBox1.Image = null; pictureBox1.Visible = false; choosePictureLabel.Visible = true; choosePictureLabel.BringToFront(); autorLabel.BringToFront(); autorLabel.Visible = true; button1.Visible = true; button2.Visible = true; panel5.Visible = false; //obsahuje button3==Restart, button4==NewGame if (showGameInstructions) { showGameInstructions = false; this.panel6.Visible = false; } }
// vraci nadobu pod mysou, pouziva funkciu BucketCoordinates public static List <PuzzlePiece> BucketUnderMouse(PuzzleGameData data, Point currMouseCoords) //Skupina puzzle kuskov nachadzajuca sa pod suradnicami mysi { // //Vyberame skupinku kuskov najblizsiu k ukazovatelovi mysi (ak skupinka neexistuje, return null). // List <PuzzlePiece> value; Size realPieceSize = data.PieceDimensions; realPieceSize.Width += 2 * data.PieceSurroundingSize; realPieceSize.Height += 2 * data.PieceSurroundingSize; Point bucketCoords = PuzzleGameUtilities.BucketCoordinates(realPieceSize, currMouseCoords); if (data.bucketOfPieces.TryGetValue(bucketCoords, out value)) { return(value); } else { return(null); } }
// ak kusok odoberame z pozicie kde bol, odoberieme ho aj z nadob, nad ktorymi boli jeho rohy public static void DeregisterPieceFromGrid(PuzzleGameData data, PuzzlePiece piece) { List <PuzzlePiece> value; Point[] pieceToRemove_Corners; pieceToRemove_Corners = RealPieceCornerPoints(piece.CurrentPosition, //ziskame rohy kuska, na ktory prave ukazujeme piece.SizeOfPieceImage); //aby sme ho odobrali zo vsetkych policok kde predtym bol foreach (var corner in pieceToRemove_Corners) { if (data.bucketOfPieces.TryGetValue(BucketCoordinates(piece.SizeOfPieceImage, corner), out value)) { value.Remove(piece); //odoberieme zo vsetkych List<PuzzlePiece> skupiniek(policok) kde kusok patril //metoda Remove() vracia false ak nebol najdeny objekt pre zmazanie if (!value.Any()) //ak je policko sachovnice (List<>) po odobrani kuska prazdne, odoberieme ho zo zaznamu { data.bucketOfPieces.Remove(BucketCoordinates(piece.SizeOfPieceImage, corner)); value = null; } } } }
// funkcia nahodne rozmiestni puzzle kusky po hracom poli public static void RandomizePiecesLocations(PuzzleGameData data) { Random rnd = new Random(); Point startPos, endPos; startPos = new Point(data.PieceSurroundingSize, data.PieceSurroundingSize); endPos = new Point((data.GameBoard.Width - (2 * data.PieceSurroundingSize + data.PieceDimensions.Width)), (data.GameBoard.Height - (2 * data.PieceSurroundingSize + data.PieceDimensions.Height))); foreach (var piece in data.Pieces) { //nahodna pozicia kuska v ramci hracej plochy piece.CurrentPosition = new Point(rnd.Next(startPos.X, endPos.X), rnd.Next(startPos.Y, endPos.Y)); //registracia kuska do virtualnej hracej sachovnice, kde policko v sachovnici reprezentuje skupinu vsetkych kuskov puzzle ktore sa ho priamo dotykaju(prekryvaju) RegisterPieceInGrid(data, piece); } //using (var streamWriter = new System.IO.StreamWriter("output.txt")) //{ // foreach (var item in data.bucketOfPieces) // streamWriter.WriteLine("[{0} {1}]", item.Key, item.Value); //} }
// ak kusok polozime na novu poziciu, pridame ho do nadob, nad ktorymi su jeho rohy vyskytuju public static void RegisterPieceInGrid(PuzzleGameData data, PuzzlePiece piece) { List <PuzzlePiece> value; Point[] realPieceCorners; realPieceCorners = RealPieceCornerPoints(piece.CurrentPosition, piece.SizeOfPieceImage); //zistime z ktorymi polickami sa pretinaju rohy kuska foreach (var cornerPosition in realPieceCorners) { if (data.bucketOfPieces.TryGetValue(BucketCoordinates(piece.SizeOfPieceImage, cornerPosition), out value)) { if (value.Last() != piece) // vylucime moznost aby sme zaznamenali viacero rohov kuska do jedneho policka { value.Add(piece); } } else { value = new List <PuzzlePiece>(); value.Add(piece); data.bucketOfPieces.Add(BucketCoordinates(piece.SizeOfPieceImage, cornerPosition), value); } } }
// pociatocne nastavenia public void Configure(PuzzleGameData data, Form1 form) { #region Pociatocne nastavenia - rozmiestnenia, velkosti, vztahy medzi controls, events handlers this.data = data; //Je potrebny zdrojovy obrazok v gamedata!! this.parentPanel = (form.Controls["panel4"] as Panel); //Je potrebne nastavit pred zavolanim Configure(), kto je komu rodicom this.parentPictBox = (this.Parent as PictureBox); this.parentPictBox.Location = new Point(0 - data.SourcePicture.Width, 0 - data.SourcePicture.Height); this.parentPictBox.Size = new Size(data.SourcePicture.Width + this.parentPanel.Size.Width, data.SourcePicture.Height + this.parentPanel.Size.Height); this.parentPictBox.BringToFront(); // this.Location = new Point(data.SourcePicture.Width, data.SourcePicture.Height); //pozicia gridlayer kvoli posunu picturebox-u this.Size = new Size(this.parentPanel.Size.Width, this.parentPanel.Height); //velkost gridlayer podla velkosti zobrazovaniecho panelu(panel4) this.BackColor = Color.Transparent; this.BringToFront(); this.Anchor = AnchorStyles.None; this.Anchor = (AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right); this.Controls.Add(widthBox); this.Controls.Add(heightBox); this.Controls.Add(dimensionBox); this.MouseDown += this.customGridLayer_MouseDown; this.MouseUp += this.customGridLayer_MouseUp; this.MouseMove += this.customGridLayer_MouseMove; this.parentPictBox.ClientSizeChanged += customclientSizeChanged_ParentPictureBox; // this.parentPictBox.Image = PictureEditor.ImageScale(GridRatioFromSourceImageResolution, data.SourcePicture); this.parentPictBox.Padding = new Padding(data.SourcePicture.Width + (int)((this.parentPanel.Width - this.parentPictBox.Image.Size.Width) / 2), data.SourcePicture.Height + (int)((this.parentPanel.Height - this.parentPictBox.Image.Size.Height) / 2), 0, 0); TextBoxesVisible = false; //==================================================================================================================================== #endregion #region Nastavenie Grid // //Prednastavenia pred vytvorenim Grid okrazka // backGroundImageForGrid = PictureEditor.ColouredBackGroundImage(Color.Black, this.Size); //Color.RoyalBlue backGroundImageForGrid = PictureEditor.ImageOpacity(0.60F, backGroundImageForGrid); pieceDimensions = new Size(100, 100); gridDimensions = new Size((int)((data.SourcePicture.Width * 0.7) / pieceDimensions.Width), (int)((data.SourcePicture.Height * 0.7) / pieceDimensions.Height)); // //Nastavenie vygenerovaneho grid obrazka // this.SetGridImage(GridRatioFromSourceImageResolution); ////this.Refresh(); // //Nastavenie textboxov // widthBox.TextChanged += this.whenTextBox1_Changed; widthBox.MouseEnter += this.whenTextBox1_MouseEnter; widthBox.MouseLeave += this.whenTextBox1_MouseLeave; heightBox.TextChanged += this.whenTextBox2_Changed; heightBox.MouseEnter += this.whenTextBox2_MouseEnter; heightBox.MouseLeave += this.whenTextBox2_MouseLeave; dimensionBox.TextChanged += this.whenTextBox3_Changed; dimensionBox.MouseEnter += this.whenTextBox3_MouseEnter; dimensionBox.MouseLeave += this.whenTextBox3_MouseLeave; //widthBox.Text = "Width"; //heightBox.Text = "Height"; //dimensionBox.Text = "Size"; var textBoxes = this.Controls.OfType <TextBox>().ToArray(); foreach (var textBox in textBoxes) { textBox.BackColor = Color.FromArgb(64, 64, 64); textBox.BorderStyle = BorderStyle.FixedSingle; textBox.ForeColor = Color.White; textBox.Size = new Size(50, 20); //textBox.Refresh(); } // //do textboxov vyplnime pociatocne hodnoty rozmerov grid, a velkost kuska puzzle, zalohujeme text, ktory v nich bol // textbox1_BackupText = (gridDimensions.Width).ToString(); widthBox.Text = "Šírka"; textbox2_BackupText = (gridDimensions.Height).ToString(); heightBox.Text = "Dĺžka"; textbox3_BackupText = (pieceDimensions.Width).ToString(); dimensionBox.Text = "Rozmer"; // //TextBox-y umiestnime do stredu // TextBoxesInTheMiddle(MiddlePoint_Grid); // //TextBox-y budu viditelne // TextBoxesVisible = true; this.Refresh(); // // Vzhlad kurzora // //Pri vybere obrazka sa vzhlad kurzoru zmeni na posovny kurzor, sipky styrmi smermi this.Cursor = Cursors.SizeAll; // // Zistime ako su od seba posunuta mriezka a obrazok a prevedieme to do skutocneho rozdielu, ak by bol obrazok nescalovany // Pri zmene velkosti okna totiz nesmie dojst k posunu mriezky vzhladom k obrazku, mriezka by mohla vyjst mimo obrazok // originalCornersDiff = OriginalCornersDiff; #endregion }