/// <summary> /// Creates a deep copy of this class /// </summary> /// <returns>Returns a deep copy of this class</returns> public SPieceInfo MakeCopy() { SPieceInfo Temp = new SPieceInfo(_ID); foreach (SJointInfo item in _Joints) { Temp.AddJoint(item); } return(Temp); }
/// <summary> /// Generate puzzle pieces from image. /// </summary> /// <param name="NoOfPiecesInRow">Total no of pieces in row of puzzle / total columns</param> /// <param name="NoOfPiecesInCol">Total no of pieces in Col of puzzle / total rows</param> /// <param name="Image">Main image for puzzle</param> /// <param name="JointMaskImage">Mask images for joints to be used to create joints for pieces in this puzzle</param> /// <param name="CreatedImageMask">Unknown</param> /// <returns>Returns generated pieces metadata</returns> private SPieceInfo[,] GenerateJigsawPieces(Texture2D Image, Texture2D[] JointMaskImage, out Texture2D CreatedImageMask, int NoOfPiecesInRow, int NoOfPiecesInCol) { #region "Argument Error Checking" if (NoOfPiecesInRow < 2) { throw new System.ArgumentOutOfRangeException("NoOfPiecesInRow", "Argument should be greater then 1"); } else if (NoOfPiecesInCol < 2) { throw new System.ArgumentOutOfRangeException("NoOfPiecesInCol", "Argument should be greater then 1"); } else if (Image == null) { throw new System.ArgumentNullException("No texture2d assigned to this class"); } #endregion _noOfPiecesInRow = NoOfPiecesInRow; _noOfPiecesInCol = NoOfPiecesInCol; _origionalImage = Image; Color[][] _PuzzleImageTopJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImageBotJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImageLeftJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImageRightJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImage = HelperMethods.Texture2DToColorArr(Image); SPieceInfo[,] PiecesInformation = null; PiecesInformation = DrawCustomPieceJointsMask(ref _PuzzleImageTopJointMask, ref _PuzzleImageBotJointMask, ref _PuzzleImageLeftJointMask, ref _PuzzleImageRightJointMask, JointMaskImage, out _pieceWidthWithoutJoint, out _pieceHeightWithoutJoint,Image.width, Image.height, NoOfPiecesInCol, NoOfPiecesInRow); CreatedImageMask = HelperMethods.ColorArrToTexture2D(_PuzzleImageTopJointMask); //Create mask image for each side joints JointsMaskToJointsImage(ref _PuzzleImage, ref _PuzzleImageTopJointMask,ref _PuzzleImageBotJointMask, ref _PuzzleImageLeftJointMask, ref _PuzzleImageRightJointMask, PieceWidthWithoutJoint, PieceHeightWithoutJoint, Image.width, Image.height); _topJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageTopJointMask); _botJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageBotJointMask); _leftJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageLeftJointMask); _rightJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageRightJointMask); _image = HelperMethods.ColorArrToTexture2D(_PuzzleImage); //Return data for puzzle pieces SPieceInfo[,] ResultData = new SPieceInfo[NoOfPiecesInCol, NoOfPiecesInRow]; for (int i = 0; i < NoOfPiecesInCol; i++) for (int j = 0; j < NoOfPiecesInRow; j++) ResultData[i, j] = PiecesInformation[i, j]; return ResultData; }
public SPieceMetaData(SPieceInfo MetaData, Texture2D Image) { PieceMetaData = MetaData; PieceImage = Image; }
private SPieceInfo[,] DrawCustomPieceJointsMask(ref Color[][] Image, Texture2D[] JointMaskImage, out int PieceWidthWithoutJoint, out int PieceHeightWithoutJoint, int PuzzleImgWidth, int PuzzleImgHeight, int Rows = 5, int Cols = 5) { //Create direction wise mask images Texture2D[] LeftJointMask = new Texture2D[JointMaskImage.Length]; int[] LeftJointMaskWidth = new int[JointMaskImage.Length]; int[] LeftJointMaskHeight = new int[JointMaskImage.Length]; Texture2D[] RightJointMask = new Texture2D[JointMaskImage.Length]; int[] RightJointMaskWidth = new int[JointMaskImage.Length]; int[] RightJointMaskHeight = new int[JointMaskImage.Length]; Texture2D[] TopJointMask = new Texture2D[JointMaskImage.Length]; int[] TopJointMaskWidth = new int[JointMaskImage.Length]; int[] TopJointMaskHeight = new int[JointMaskImage.Length]; Texture2D[] BottomJointMask = new Texture2D[JointMaskImage.Length]; int[] BottomJointMaskWidth = new int[JointMaskImage.Length]; int[] BottomJointMaskHeight = new int[JointMaskImage.Length]; SPieceInfo[,] ResultPiecesData = new SPieceInfo[Rows, Cols]; //Initialize pieces data for (int i = 0; i < Rows; i++) for (int j = 0; j < Cols; j++) ResultPiecesData[i, j] = new SPieceInfo((i * Cols) + j); int PieceHeight = PuzzleImgHeight / Rows; int PieceWidth = PuzzleImgWidth / Cols; PieceWidthWithoutJoint = PieceWidth; PieceHeightWithoutJoint = PieceHeight; for (int ArrayTav = 0; ArrayTav < JointMaskImage.Length; ArrayTav++) { LeftJointMask[ArrayTav] = JointMaskImage[ArrayTav]; RightJointMask[ArrayTav] = rotateImage(JointMaskImage[ArrayTav], 180); TopJointMask[ArrayTav] = rotateImage(JointMaskImage[ArrayTav], 270); BottomJointMask[ArrayTav] = rotateImage(JointMaskImage[ArrayTav], 90); #region "Resize Joint mask images for drawing inside mask image And calculate joints width and height" //Resize Joint mask images for drawing inside mask image // Image will be resized according to piece width int MaskImageWidth = (int)(PieceWidth * 0.3f); int MaskImageHeight = (int)((float)MaskImageWidth / ((float)JointMaskImage[ArrayTav].width / (float)JointMaskImage[ArrayTav].height)); LeftJointMask[ArrayTav] = resizeImage(LeftJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); RightJointMask[ArrayTav] = resizeImage(RightJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); TopJointMask[ArrayTav] = resizeImage(TopJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); BottomJointMask[ArrayTav] = resizeImage(BottomJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); //Calculate joints width and heights CalculateCustomJointDimensions(LeftJointMask[ArrayTav], out LeftJointMaskWidth[ArrayTav], out LeftJointMaskHeight[ArrayTav]); RightJointMaskWidth[ArrayTav] = LeftJointMaskWidth[ArrayTav]; RightJointMaskHeight[ArrayTav] = LeftJointMaskHeight[ArrayTav]; TopJointMaskWidth[ArrayTav] = LeftJointMaskHeight[ArrayTav]; TopJointMaskHeight[ArrayTav] = LeftJointMaskWidth[ArrayTav]; BottomJointMaskWidth[ArrayTav] = LeftJointMaskHeight[ArrayTav]; BottomJointMaskHeight[ArrayTav] = LeftJointMaskWidth[ArrayTav]; /* //Save these image saveTexture2D(LeftJointMask[ArrayTav], "c:\\Images\\LeftJoint.png"); saveTexture2D(RightJointMask[ArrayTav], "c:\\Images\\RightJointMask.png"); saveTexture2D(TopJointMask[ArrayTav], "c:\\Images\\TopJointMask.png"); saveTexture2D(BottomJointMask[ArrayTav], "c:\\Images\\BottomJointMask.png"); */ #endregion } #region "Argument Error Checking" //Joint mask image width and height should be same //Joint mask image should have only black and white pixels inside it if (JointMaskImage[0].width != JointMaskImage[0].height) { Debug.LogError("JointMaskImage width and height should be same"); return null; } else { bool ErrorFound = false; //If Non-Black or Non-White pixel found //Check for pixel colors in joint mask image for (int rowtrav = 0; rowtrav < JointMaskImage[0].height && !ErrorFound; rowtrav++) { for (int coltrav = 0; coltrav < JointMaskImage[0].width && !ErrorFound; coltrav++) { Color PixelColor = JointMaskImage[0].GetPixel(coltrav, rowtrav); if (PixelColor != Color.white || PixelColor != Color.black) { ErrorFound = true; //Debug.LogError("Only white and black pixels are allowed in JointMaskImage"); //return null; } } } } #endregion Color[][] CreatedMaskImage = new Color[PuzzleImgWidth][]; //Clear Instantiated mask image for (int i = 0; i < PuzzleImgWidth; i++) { CreatedMaskImage[i] = new Color[PuzzleImgHeight]; for (int j = 0; j < PuzzleImgHeight; j++) { CreatedMaskImage[i][j] = Color.white; } } #region "Color Pieces Alternatively And Generate random joint info And Draw joints" bool AlternatePiece = true; //if (ColorPieces) { Random.seed = System.DateTime.Now.Second; for (int RowTrav = 0; RowTrav < Rows; RowTrav++) { for (int ColTrav = 0; ColTrav < Cols; ColTrav++) { int PieceX = ColTrav * PieceWidth; int PieceY = RowTrav * PieceHeight; Color PieceColor = AlternatePiece ? Color.green : Color.red; for (int InternalRowTrav = PieceY; InternalRowTrav < PieceY + PieceHeight; InternalRowTrav++) for (int InternalColTrav = PieceX; InternalColTrav < PieceX + PieceWidth; InternalColTrav++) if (CreatedMaskImage[InternalColTrav][InternalRowTrav] == Color.white) CreatedMaskImage[InternalColTrav][InternalRowTrav] = PieceColor; #region "Generate Random joint info and Draw Joints From Mask Image" #region "Draw right joints according to piece joint information" if (ColTrav < Cols - 1) { int SelectedRandomJoint = Random.Range(1, JointMaskImage.Length) - 1; //Create random joint information int RndVal = (int)(Random.Range(1f, 18f) >= 10 ? 1 : 0); ResultPiecesData[RowTrav, ColTrav].AddJoint(new SJointInfo((EJointType)RndVal, EJointPosition.Right, RightJointMaskWidth[SelectedRandomJoint], RightJointMaskHeight[SelectedRandomJoint])); int JointX = PieceX + PieceWidth - 5; int JointY = PieceY + (PieceHeight / 2) - (RightJointMask[SelectedRandomJoint].height / 2); bool Result = false; SJointInfo RightJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Right, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Right Joints"); } else { if ( RightJointInfo.JointType == EJointType.Male ) drawJoint(ref CreatedMaskImage, RightJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #region"Draw left joints according to piece joint information" if (ColTrav > 0) { int SelectedRandomJoint = Random.Range(1, JointMaskImage.Length) - 1; //Create random joint information bool Result = false; SJointInfo PreviousRightJoint = ResultPiecesData[RowTrav, ColTrav - 1].GetJoint(EJointPosition.Right, out Result); if (Result == false) { Debug.LogError("Logical error in joints information left joint"); } else { SJointInfo CalcLeftJoint = new SJointInfo(PreviousRightJoint.JointType == EJointType.Female ? EJointType.Male : EJointType.Female, EJointPosition.Left, LeftJointMaskWidth[SelectedRandomJoint], LeftJointMaskHeight[SelectedRandomJoint]); ResultPiecesData[RowTrav , ColTrav].AddJoint(CalcLeftJoint); } int JointX = PieceX - LeftJointMask[SelectedRandomJoint].width + 5; int JointY = PieceY + (PieceHeight / 2) - (LeftJointMask[SelectedRandomJoint].height / 2); Result = false; SJointInfo LeftJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Left, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Left Joints"); } else { if (LeftJointInfo.JointType == EJointType.Male) drawJoint(ref CreatedMaskImage, LeftJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #region"Draw Top joints according to piece joint information" if (RowTrav < Rows - 1) { int SelectedRandomJoint = Random.Range(1, JointMaskImage.Length) - 1; //Create random joint information int RndVal = (int)(Random.Range(1f, 17f) >= 10 ? 1 : 0); ResultPiecesData[RowTrav, ColTrav].AddJoint(new SJointInfo((EJointType)RndVal, EJointPosition.Top, TopJointMaskWidth[SelectedRandomJoint], TopJointMaskHeight[SelectedRandomJoint] )); int JointX = PieceX + (PieceWidth / 2) - (TopJointMask[SelectedRandomJoint].width / 2); int JointY = PieceY + PieceHeight - 5; bool Result = false; SJointInfo TopJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Top, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Top Joints"); } else { if (TopJointInfo.JointType == EJointType.Male) drawJoint(ref CreatedMaskImage, TopJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #region"Draw Bottom joints according to piece joint information" if (RowTrav > 0) { int SelectedRandomJoint = Random.Range(1, JointMaskImage.Length) - 1; //Create random joint information bool Result = false; SJointInfo PreviousPieceTopJoint = ResultPiecesData[RowTrav - 1, ColTrav].GetJoint(EJointPosition.Top, out Result); if (Result == false) { Debug.LogError("Logical error in joints information Bottom joint"); } else { SJointInfo CalcBottomJoint = new SJointInfo(PreviousPieceTopJoint.JointType == EJointType.Female ? EJointType.Male : EJointType.Female, EJointPosition.Bottom, BottomJointMaskWidth[SelectedRandomJoint], BottomJointMaskHeight[SelectedRandomJoint] ); ResultPiecesData[RowTrav, ColTrav].AddJoint(CalcBottomJoint); } int JointX = PieceX + (PieceWidth / 2) - (BottomJointMask[SelectedRandomJoint].width / 2); int JointY = PieceY - BottomJointMask[SelectedRandomJoint].height; Result = false; SJointInfo BottomJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Bottom, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Top Joints"); } else { if (BottomJointInfo.JointType == EJointType.Male) drawJoint(ref CreatedMaskImage, BottomJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #endregion AlternatePiece = !AlternatePiece; } if (Cols % 2 == 0) AlternatePiece = !AlternatePiece; } } #endregion //Store mask image for testing purposes //System.IO.File.WriteAllBytes("c:\\Images\\MaskImage.png", CreatedMaskImage.EncodeToPNG()); Image = CreatedMaskImage; return ResultPiecesData; }
/// <summary> /// Load data from stream of file for puzzle maker. /// </summary> /// <param name="stream"></param> /// <returns></returns> private bool LoadStreamData(System.IO.Stream stream) { System.IO.BinaryReader bReader = null; try { using (bReader = new System.IO.BinaryReader(stream)) { //Get secret number to check file intigrity int secretNumber = bReader.ReadInt32(); if (secretNumber != 6640330) { bReader.Close(); Debug.LogError("Error reading file. Make sure this file is created with puzzle maker`s current version"); return false; } //Get basic variables data _NoOfPiecesInRow = bReader.ReadInt32(); _NoOfPiecesInCol = bReader.ReadInt32(); _PieceWidthWithoutJoint = bReader.ReadInt32(); _PieceHeightWithoutJoint = bReader.ReadInt32(); ColorPieces = bReader.ReadBoolean(); #region "Retrieve basic images" int lengthImageEncoded = bReader.ReadInt32(); byte[] imageEncoded = bReader.ReadBytes(lengthImageEncoded); _Image = new Texture2D(100, 100); _Image.LoadImage(imageEncoded); int lengthBackgroundImageEncoded = bReader.ReadInt32(); byte[] createdBackgroundImageEncoded = bReader.ReadBytes(lengthBackgroundImageEncoded); _CreatedBackgroundImage = new Texture2D(100, 100); _CreatedBackgroundImage.LoadImage(createdBackgroundImageEncoded); #endregion #region "Retrieve joint mask array" int lengthJointMaskArr = bReader.ReadInt32(); _JointMask = new Texture2D[lengthJointMaskArr]; for (int i = 0; i < lengthJointMaskArr; i++) { int TempLength = bReader.ReadInt32(); _JointMask[i] = new Texture2D(100, 100); byte[] TempMaskArr = bReader.ReadBytes(TempLength); _JointMask[i].LoadImage(TempMaskArr); } #endregion #region "Retreive Pieces Metadata" _CreatedImagePiecesData = new SPieceMetaData[_NoOfPiecesInCol, _NoOfPiecesInRow]; for (int RowTrav = 0; RowTrav < _NoOfPiecesInCol; RowTrav++) { for (int ColTrav = 0; ColTrav < _NoOfPiecesInRow; ColTrav++) { int pieceID = bReader.ReadInt32(); //Get joints info int JointInfoLength = bReader.ReadInt32(); SPieceInfo TempSPieceInfo = new SPieceInfo(pieceID); for (int i = 0; i < JointInfoLength; i++) { int jointType = bReader.ReadInt32(); int jointWidth = bReader.ReadInt32(); int jointHeight = bReader.ReadInt32(); int jointPosition = bReader.ReadInt32(); TempSPieceInfo.AddJoint(new SJointInfo((EJointType)jointType, (EJointPosition)jointPosition, jointWidth, jointHeight)); } //Get this piece image int pieceImgArrLength = bReader.ReadInt32(); byte[] pieceTempArr = bReader.ReadBytes(pieceImgArrLength); Texture2D pieceTempImage = new Texture2D(100, 100); pieceTempImage.LoadImage(pieceTempArr); pieceTempImage.wrapMode = TextureWrapMode.Clamp; //Insert this piece data in list _CreatedImagePiecesData[RowTrav, ColTrav] = new SPieceMetaData(TempSPieceInfo, pieceTempImage); } } #endregion bReader.Close(); } } catch (System.Exception ex) { throw new System.Exception("Exception in load data 2: " + ex.Message); //Debug.LogError("Puzzle Maker LoadData Method: " + ex.Message); } return true; }
/// <summary> /// Called when piece is colliding from its bottom side /// </summary> /// <param name="CollidingPieceId">Id of piece colliding with</param> /// <param name="ColP">Instance of piece colliding with</param> /// <param name="ColPPieceData">Metadata of piece colliding with</param> /// <param name="ColObjController">JPPieceController instance of piece colliding with</param> void OnBottomCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren<JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { //Get colliding piece position in grid int CPElementRow = 0; int CPElementCol = 0; PPPuzzleController.ArrayPosToRC(CollidingPieceId, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out CPElementRow, out CPElementCol); //Get this piece position in grid int PElementRow = 0; int PElementCol = 0; PPPuzzleController.ArrayPosToRC(ThisPieceData.ID, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out PElementRow, out PElementCol); if (ThisPieceData.ID > CollidingPieceId && PElementCol == CPElementCol && PElementRow == CPElementRow + 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); transform.position = new Vector3(ColP.transform.position.x, ColP.transform.position.y + JpPuzzleControllerInstance.PieceHeightInWorld, ColP.transform.position.z); ColP.transform.root.parent = transform; OnPieceJoined(); CheckForPuzzleComplete(transform); } } }
/// <summary> /// Called when piece is colliding from its left side /// </summary> /// <param name="CollidingPieceId">Id of piece colliding with</param> /// <param name="ColP">Instance of piece colliding with</param> /// <param name="ColPPieceData">Metadata of piece colliding with</param> /// <param name="ColObjController">JPPieceController instance of piece colliding with</param> void OnLeftCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren<JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { if (ThisPieceData.ID == CollidingPieceId + 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); transform.position = new Vector3(ColP.transform.position.x + JpPuzzleControllerInstance.PieceWidthInWorld, ColP.transform.position.y, ColP.transform.position.z); ColP.transform.root.parent = transform; OnPieceJoined(); CheckForPuzzleComplete(transform); } } }
void OnBottomCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren<JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { //Get colliding piece position in grid int CPElementRow = 0; int CPElementCol = 0; PPPuzzleController.ArrayPosToRC(CollidingPieceId, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out CPElementRow, out CPElementCol); //Get this piece position in grid int PElementRow = 0; int PElementCol = 0; PPPuzzleController.ArrayPosToRC(ThisPieceData.ID, JpPuzzleControllerInstance.PiecesInCol, JpPuzzleControllerInstance.PiecesInRow, out PElementRow, out PElementCol); if (ThisPieceData.ID > CollidingPieceId && PElementCol == CPElementCol && PElementRow == CPElementRow + 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); Vector3 CalculatedPos = new Vector3(); float LeftJointWorldScale = 0; float RightJointWorldScale = 0; float TopJointWorldScale = 0; float BotJointWorldScale = 0; float ColPLeftJointWorldScale = 0; float ColPRightJointWorldScale = 0; float ColPTopJointWorldScale = 0; float ColPBotJointWorldScale = 0; //Calculate required data CalculateDataForCollisionPlacement(ColPPieceData, out ColPLeftJointWorldScale, out ColPRightJointWorldScale, out ColPTopJointWorldScale, out ColPBotJointWorldScale); CalculateDataForCollisionPlacement(ThisPieceData, out LeftJointWorldScale, out RightJointWorldScale, out TopJointWorldScale, out BotJointWorldScale); //Calculate X CalculatedPos.x = ColP.transform.position.x - (ColPRightJointWorldScale / 2) + (ColPLeftJointWorldScale / 2) + (RightJointWorldScale / 2) - (LeftJointWorldScale / 2); //Calculate Y float CalcYWJ = ColP.transform.position.y + JpPuzzleControllerInstance.PieceHeightInWorld; CalculatedPos.y = CalcYWJ + (TopJointWorldScale / 2) - (BotJointWorldScale / 2) - (ColPTopJointWorldScale / 2) + (ColPBotJointWorldScale / 2); CalculatedPos.z = transform.position.z; transform.position = CalculatedPos; ColP.transform.root.parent = transform; OnPieceJoined(); CheckForPuzzleComplete(transform); } } }
/// <summary> /// Loads puzzle data from file stream of .pm file /// </summary> /// <param name="stream">Stream to load data from</param> /// <returns>Returns true if data loading is successfull false otherwise</returns> private bool LoadStreamData(System.IO.Stream stream) { System.IO.BinaryReader bReader = null; try { using (bReader = new System.IO.BinaryReader(stream)) { //Get secret number to check file intigrity int secretNumber = bReader.ReadInt32(); if (secretNumber != _secretVersionNo) { bReader.Close(); Debug.LogError("Error reading file. Make sure this file is created with puzzle maker`s current version"); return(false); } //Get basic variables data _noOfPiecesInRow = bReader.ReadInt32(); _noOfPiecesInCol = bReader.ReadInt32(); _pieceWidthWithoutJoint = bReader.ReadInt32(); _pieceHeightWithoutJoint = bReader.ReadInt32(); //Origional puzzle image int lengthImageEncoded = bReader.ReadInt32(); byte[] imageEncoded = bReader.ReadBytes(lengthImageEncoded); _origionalImage = new Texture2D(100, 100); _origionalImage.LoadImage(imageEncoded); //Puzzle image with joints lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _image = new Texture2D(100, 100); _image.LoadImage(imageEncoded); //Created background image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _createdBackgroundImage = new Texture2D(100, 100); _createdBackgroundImage.LoadImage(imageEncoded); //Top joint mask image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _topJointsMaskImage = new Texture2D(100, 100); _topJointsMaskImage.LoadImage(imageEncoded); //Bottom joint mask image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _botJointsMaskImage = new Texture2D(100, 100); _botJointsMaskImage.LoadImage(imageEncoded); //Left joint mask image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _leftJointsMaskImage = new Texture2D(100, 100); _leftJointsMaskImage.LoadImage(imageEncoded); //Right joint mask iamge lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _rightJointsMaskImage = new Texture2D(100, 100); _rightJointsMaskImage.LoadImage(imageEncoded); //Load joint mask array int lengthJointMaskArr = bReader.ReadInt32(); _jointMask = new Texture2D[lengthJointMaskArr]; for (int i = 0; i < lengthJointMaskArr; i++) { int TempLength = bReader.ReadInt32(); _jointMask[i] = new Texture2D(100, 100); imageEncoded = bReader.ReadBytes(TempLength); _jointMask[i].LoadImage(imageEncoded); } #region "Retreive Pieces Metadata" _CreatedPiecesData = new SPieceInfo[_noOfPiecesInCol, _noOfPiecesInRow]; for (int RowTrav = 0; RowTrav < _noOfPiecesInCol; RowTrav++) { for (int ColTrav = 0; ColTrav < _noOfPiecesInRow; ColTrav++) { int pieceID = bReader.ReadInt32(); //Get joints info int JointInfoLength = bReader.ReadInt32(); SPieceInfo TempSPieceInfo = new SPieceInfo(pieceID); for (int i = 0; i < JointInfoLength; i++) { int jointType = bReader.ReadInt32(); int jointWidth = bReader.ReadInt32(); int jointHeight = bReader.ReadInt32(); int jointPosition = bReader.ReadInt32(); TempSPieceInfo.AddJoint(new SJointInfo((EJointType)jointType, (EJointPosition)jointPosition, jointWidth, jointHeight)); } //Insert this piece data in list _CreatedPiecesData[RowTrav, ColTrav] = TempSPieceInfo; } } #endregion bReader.Close(); } } catch (System.Exception ex) { throw new System.Exception("Exception in load data 2: " + ex.Message); } return(true); }
/// <summary> /// Draws joint mask image for each side of joints for every piece which is used to later /// generate puzzle image for pieces /// </summary> /// <param name="TopJointMaskImage">Output mask image for top joints</param> /// <param name="BotJointMaskImage">Output mask image for bottom joints</param> /// <param name="LeftJointMaskImage">Output mask image for left joints</param> /// <param name="RightJointMaskImage">Output mask image for right joints</param> /// <param name="JointMaskImages">User provided joint mask images to be used</param> /// <param name="PieceHeightWithoutJoint">Output piece image height</param> /// <param name="PieceWidthWithoutJoint">Output piece image width</param> /// <param name="PuzzleImgHeight">Height of user provided puzzle image</param> /// <param name="PuzzleImgWidth">Width of user provided puzzle image</param> /// <param name="Cols">Total columns in puzzle</param> /// <param name="Rows">Total rows in puzzle</param> /// <returns>Returns created pieces metadata created during masks creation</returns> private SPieceInfo[,] DrawCustomPieceJointsMask(ref Color[][] TopJointMaskImage, ref Color[][] BotJointMaskImage, ref Color[][] LeftJointMaskImage, ref Color[][] RightJointMaskImage, Texture2D[] JointMaskImages, out int PieceWidthWithoutJoint, out int PieceHeightWithoutJoint, int PuzzleImgWidth, int PuzzleImgHeight, int Rows = 5, int Cols = 5) { int[] JointMaskWidth = new int[JointMaskImages.Length]; int[] JointMaskHeight = new int[JointMaskImages.Length]; //Create direction wise mask images Texture2D[] LeftJointMask = new Texture2D[JointMaskImages.Length]; Texture2D[] RightJointMask = new Texture2D[JointMaskImages.Length]; Texture2D[] TopJointMask = new Texture2D[JointMaskImages.Length]; Texture2D[] BottomJointMask = new Texture2D[JointMaskImages.Length]; SPieceInfo[,] ResultPiecesData = new SPieceInfo[Rows, Cols]; //Initialize pieces data for (int i = 0; i < Rows; i++) { for (int j = 0; j < Cols; j++) { ResultPiecesData[i, j] = new SPieceInfo((i * Cols) + j); } } int PieceHeight = PuzzleImgHeight / Rows; int PieceWidth = PuzzleImgWidth / Cols; PieceWidthWithoutJoint = PieceWidth; PieceHeightWithoutJoint = PieceHeight; for (int ArrayTav = 0; ArrayTav < JointMaskImages.Length; ArrayTav++) { LeftJointMask[ArrayTav] = JointMaskImages[ArrayTav]; BottomJointMask[ArrayTav] = HelperMethods.rotateImage(JointMaskImages[ArrayTav], 90); RightJointMask[ArrayTav] = HelperMethods.rotateImage(BottomJointMask[ArrayTav], 90); TopJointMask[ArrayTav] = HelperMethods.rotateImage(JointMaskImages[ArrayTav], 270); #region "Resize Joint mask images for drawing inside mask image And calculate joints width and height" //Resize Joint mask images for drawing inside mask image // Image will be resized according to piece width int MaskImageWidth = (int)(PieceWidth * 0.3f); int MaskImageHeight = (int)((float)MaskImageWidth / ((float)JointMaskImages[ArrayTav].width / (float)JointMaskImages[ArrayTav].height)); LeftJointMask[ArrayTav] = HelperMethods.resizeImage(LeftJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); RightJointMask[ArrayTav] = HelperMethods.resizeImage(RightJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); TopJointMask[ArrayTav] = HelperMethods.resizeImage(TopJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); BottomJointMask[ArrayTav] = HelperMethods.resizeImage(BottomJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); //Calculate joints width and heights CalculateCustomJointDimensions(LeftJointMask[ArrayTav], out JointMaskWidth[ArrayTav], out JointMaskHeight[ArrayTav]); #endregion } #region "Argument Error Checking" //Joint mask image width and height should be same //Joint mask image should have only black and white pixels inside it if (JointMaskImages[0].width != JointMaskImages[0].height) { Debug.LogError("JointMaskImage width and height should be same"); return(null); } else { bool ErrorFound = false; //If Non-Black or Non-White pixel found //Check for pixel colors in joint mask image for (int rowtrav = 0; rowtrav < JointMaskImages[0].height && !ErrorFound; rowtrav++) { for (int coltrav = 0; coltrav < JointMaskImages[0].width && !ErrorFound; coltrav++) { Color PixelColor = JointMaskImages[0].GetPixel(coltrav, rowtrav); if (PixelColor != Color.white || PixelColor != Color.black) { ErrorFound = true; //Debug.LogError("Only white and black pixels are allowed in JointMaskImage"); //return null; } } } } #endregion TopJointMaskImage = new Color[PuzzleImgWidth][]; BotJointMaskImage = new Color[PuzzleImgWidth][]; LeftJointMaskImage = new Color[PuzzleImgWidth][]; RightJointMaskImage = new Color[PuzzleImgWidth][]; //Clear Instantiated mask image for (int i = 0; i < PuzzleImgWidth; i++) { TopJointMaskImage[i] = new Color[PuzzleImgHeight]; BotJointMaskImage[i] = new Color[PuzzleImgHeight]; LeftJointMaskImage[i] = new Color[PuzzleImgHeight]; RightJointMaskImage[i] = new Color[PuzzleImgHeight]; } //Generate random joint info And Draw joints Random.seed = System.DateTime.Now.Second; Color PieceColor = Color.black; for (int RowTrav = 0; RowTrav < Rows; RowTrav++) { for (int ColTrav = 0; ColTrav < Cols; ColTrav++) { int PieceX = ColTrav * PieceWidth; int PieceY = RowTrav * PieceHeight; //Generate Random joint info and Draw Joints From Mask Image #region "Draw right joints according to piece joint information" if (ColTrav < Cols - 1) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information int RndVal = (int)(Random.Range(1f, 18f) >= 10 ? 1 : 0); ResultPiecesData[RowTrav, ColTrav].AddJoint(new SJointInfo((EJointType)RndVal, EJointPosition.Right, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint])); int JointX = PieceX + PieceWidth; int JointY = PieceY + (PieceHeight / 2) - (RightJointMask[SelectedRandomJoint].height / 2); bool Result = false; SJointInfo RightJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Right, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Right Joints"); } else { if (RightJointInfo.JointType == EJointType.Male) { drawJoint(ref RightJointMaskImage, RightJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } } #endregion #region "Draw left joints according to piece joint information" if (ColTrav > 0) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information bool Result = false; SJointInfo PreviousRightJoint = ResultPiecesData[RowTrav, ColTrav - 1].GetJoint(EJointPosition.Right, out Result); if (Result == false) { Debug.LogError("Logical error in joints information left joint"); } else { SJointInfo CalcLeftJoint = new SJointInfo(PreviousRightJoint.JointType == EJointType.Female ? EJointType.Male : EJointType.Female, EJointPosition.Left, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint]); ResultPiecesData[RowTrav, ColTrav].AddJoint(CalcLeftJoint); } int JointX = PieceX - LeftJointMask[SelectedRandomJoint].width; int JointY = PieceY + (PieceHeight / 2) - (LeftJointMask[SelectedRandomJoint].height / 2); Result = false; SJointInfo LeftJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Left, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Left Joints"); } else { if (LeftJointInfo.JointType == EJointType.Male) { drawJoint(ref LeftJointMaskImage, LeftJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } } #endregion #region "Draw Top joints according to piece joint information" if (RowTrav < Rows - 1) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information int RndVal = (int)(Random.Range(1f, 17f) >= 10 ? 1 : 0); ResultPiecesData[RowTrav, ColTrav].AddJoint(new SJointInfo((EJointType)RndVal, EJointPosition.Top, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint])); int JointX = PieceX + (PieceWidth / 2) - (TopJointMask[SelectedRandomJoint].width / 2); int JointY = PieceY + PieceHeight; bool Result = false; SJointInfo TopJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Top, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Top Joints"); } else { if (TopJointInfo.JointType == EJointType.Male) { drawJoint(ref TopJointMaskImage, TopJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } } #endregion #region "Draw Bottom joints according to piece joint information" if (RowTrav > 0) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information bool Result = false; SJointInfo PreviousPieceTopJoint = ResultPiecesData[RowTrav - 1, ColTrav].GetJoint(EJointPosition.Top, out Result); if (Result == false) { Debug.LogError("Logical error in joints information Bottom joint"); } else { SJointInfo CalcBottomJoint = new SJointInfo(PreviousPieceTopJoint.JointType == EJointType.Female ? EJointType.Male : EJointType.Female, EJointPosition.Bottom, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint]); ResultPiecesData[RowTrav, ColTrav].AddJoint(CalcBottomJoint); } int JointX = PieceX + (PieceWidth / 2) - (BottomJointMask[SelectedRandomJoint].width / 2); int JointY = PieceY - BottomJointMask[SelectedRandomJoint].height; Result = false; SJointInfo BottomJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Bottom, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Top Joints"); } else { if (BottomJointInfo.JointType == EJointType.Male) { drawJoint(ref BotJointMaskImage, BottomJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } } #endregion } } return(ResultPiecesData); }
/// <summary> /// Generate puzzle pieces from image. /// </summary> /// <param name="NoOfPiecesInRow">Total no of pieces in row of puzzle / total columns</param> /// <param name="NoOfPiecesInCol">Total no of pieces in Col of puzzle / total rows</param> /// <param name="Image">Main image for puzzle</param> /// <param name="JointMaskImage">Mask images for joints to be used to create joints for pieces in this puzzle</param> /// <param name="CreatedImageMask">Unknown</param> /// <returns>Returns generated pieces metadata</returns> private SPieceInfo[,] GenerateJigsawPieces(Texture2D Image, Texture2D[] JointMaskImage, out Texture2D CreatedImageMask, int NoOfPiecesInRow, int NoOfPiecesInCol) { #region "Argument Error Checking" if (NoOfPiecesInRow < 2) { throw new System.ArgumentOutOfRangeException("NoOfPiecesInRow", "Argument should be greater then 1"); } else if (NoOfPiecesInCol < 2) { throw new System.ArgumentOutOfRangeException("NoOfPiecesInCol", "Argument should be greater then 1"); } else if (Image == null) { throw new System.ArgumentNullException("No texture2d assigned to this class"); } #endregion _noOfPiecesInRow = NoOfPiecesInRow; _noOfPiecesInCol = NoOfPiecesInCol; _origionalImage = Image; Color[][] _PuzzleImageTopJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImageBotJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImageLeftJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImageRightJointMask = HelperMethods.Texture2DToColorArr(Image); Color[][] _PuzzleImage = HelperMethods.Texture2DToColorArr(Image); SPieceInfo[,] PiecesInformation = null; PiecesInformation = DrawCustomPieceJointsMask(ref _PuzzleImageTopJointMask, ref _PuzzleImageBotJointMask, ref _PuzzleImageLeftJointMask, ref _PuzzleImageRightJointMask, JointMaskImage, out _pieceWidthWithoutJoint, out _pieceHeightWithoutJoint, Image.width, Image.height, NoOfPiecesInCol, NoOfPiecesInRow); CreatedImageMask = HelperMethods.ColorArrToTexture2D(_PuzzleImageTopJointMask); //Create mask image for each side joints JointsMaskToJointsImage(ref _PuzzleImage, ref _PuzzleImageTopJointMask, ref _PuzzleImageBotJointMask, ref _PuzzleImageLeftJointMask, ref _PuzzleImageRightJointMask, PieceWidthWithoutJoint, PieceHeightWithoutJoint, Image.width, Image.height); _topJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageTopJointMask); _botJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageBotJointMask); _leftJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageLeftJointMask); _rightJointsMaskImage = HelperMethods.ColorArrToTexture2D(_PuzzleImageRightJointMask); _image = HelperMethods.ColorArrToTexture2D(_PuzzleImage); //Return data for puzzle pieces SPieceInfo[,] ResultData = new SPieceInfo[NoOfPiecesInCol, NoOfPiecesInRow]; for (int i = 0; i < NoOfPiecesInCol; i++) { for (int j = 0; j < NoOfPiecesInRow; j++) { ResultData[i, j] = PiecesInformation[i, j]; } } return(ResultData); }
/// <summary> /// Used to calculate required data for joining of pieces together /// </summary> void CalculateDataForCollisionPlacement(SPieceInfo PieceData, out float LeftJointWorldScale, out float RightJointWorldScale, out float TopJointWorldScale, out float BottomJointWorldScale) { bool LeftJointPresent = false; bool RightJointPresent = false; bool TopJointPresent = false; bool BotJointPresent = false; SJointInfo TempLeftJointInfo = PieceData.GetJoint(EJointPosition.Left, out LeftJointPresent); SJointInfo TempRightJointInfo = PieceData.GetJoint(EJointPosition.Right, out RightJointPresent); SJointInfo TempTopJointInfo = PieceData.GetJoint(EJointPosition.Top, out TopJointPresent); SJointInfo TempBotJointInfo = PieceData.GetJoint(EJointPosition.Bottom, out BotJointPresent); float PMPieceWidthWOJoint = (float)JpPuzzleControllerInstance.PuzzleMakerPieceWidthWithoutJoint; LeftJointWorldScale = LeftJointPresent && TempLeftJointInfo.JointType == EJointType.Male ? (float)TempLeftJointInfo.JointWidth / PMPieceWidthWOJoint : 0; RightJointWorldScale = RightJointPresent && TempRightJointInfo.JointType == EJointType.Male ? (float)TempRightJointInfo.JointWidth / PMPieceWidthWOJoint : 0; TopJointWorldScale = TopJointPresent && TempTopJointInfo.JointType == EJointType.Male ? (float)TempTopJointInfo.JointHeight / PMPieceWidthWOJoint : 0; BottomJointWorldScale = BotJointPresent && TempBotJointInfo.JointType == EJointType.Male ? (float)TempBotJointInfo.JointHeight / PMPieceWidthWOJoint : 0; }
/// <summary> /// Draws joint mask image for each side of joints for every piece which is used to later /// generate puzzle image for pieces /// </summary> /// <param name="TopJointMaskImage">Output mask image for top joints</param> /// <param name="BotJointMaskImage">Output mask image for bottom joints</param> /// <param name="LeftJointMaskImage">Output mask image for left joints</param> /// <param name="RightJointMaskImage">Output mask image for right joints</param> /// <param name="JointMaskImages">User provided joint mask images to be used</param> /// <param name="PieceHeightWithoutJoint">Output piece image height</param> /// <param name="PieceWidthWithoutJoint">Output piece image width</param> /// <param name="PuzzleImgHeight">Height of user provided puzzle image</param> /// <param name="PuzzleImgWidth">Width of user provided puzzle image</param> /// <param name="Cols">Total columns in puzzle</param> /// <param name="Rows">Total rows in puzzle</param> /// <returns>Returns created pieces metadata created during masks creation</returns> private SPieceInfo[,] DrawCustomPieceJointsMask(ref Color[][] TopJointMaskImage, ref Color[][] BotJointMaskImage, ref Color[][] LeftJointMaskImage, ref Color[][] RightJointMaskImage, Texture2D[] JointMaskImages, out int PieceWidthWithoutJoint, out int PieceHeightWithoutJoint, int PuzzleImgWidth, int PuzzleImgHeight, int Rows = 5, int Cols = 5) { int[] JointMaskWidth = new int[JointMaskImages.Length]; int[] JointMaskHeight = new int[JointMaskImages.Length]; //Create direction wise mask images Texture2D[] LeftJointMask = new Texture2D[JointMaskImages.Length]; Texture2D[] RightJointMask = new Texture2D[JointMaskImages.Length]; Texture2D[] TopJointMask = new Texture2D[JointMaskImages.Length]; Texture2D[] BottomJointMask = new Texture2D[JointMaskImages.Length]; SPieceInfo[,] ResultPiecesData = new SPieceInfo[Rows, Cols]; //Initialize pieces data for (int i = 0; i < Rows; i++) for (int j = 0; j < Cols; j++) ResultPiecesData[i, j] = new SPieceInfo((i * Cols) + j); int PieceHeight = PuzzleImgHeight / Rows; int PieceWidth = PuzzleImgWidth / Cols; PieceWidthWithoutJoint = PieceWidth; PieceHeightWithoutJoint = PieceHeight; for (int ArrayTav = 0; ArrayTav < JointMaskImages.Length; ArrayTav++) { LeftJointMask[ArrayTav] = JointMaskImages[ArrayTav]; BottomJointMask[ArrayTav] = HelperMethods.rotateImage(JointMaskImages[ArrayTav], 90); RightJointMask[ArrayTav] = HelperMethods.rotateImage(BottomJointMask[ArrayTav], 90); TopJointMask[ArrayTav] = HelperMethods.rotateImage(JointMaskImages[ArrayTav], 270); #region "Resize Joint mask images for drawing inside mask image And calculate joints width and height" //Resize Joint mask images for drawing inside mask image // Image will be resized according to piece width int MaskImageWidth = (int)(PieceWidth * 0.3f); int MaskImageHeight = (int)((float)MaskImageWidth / ((float)JointMaskImages[ArrayTav].width / (float)JointMaskImages[ArrayTav].height)); LeftJointMask[ArrayTav] = HelperMethods.resizeImage(LeftJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); RightJointMask[ArrayTav] = HelperMethods.resizeImage(RightJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); TopJointMask[ArrayTav] = HelperMethods.resizeImage(TopJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); BottomJointMask[ArrayTav] = HelperMethods.resizeImage(BottomJointMask[ArrayTav], MaskImageWidth, MaskImageHeight); //Calculate joints width and heights CalculateCustomJointDimensions(LeftJointMask[ArrayTav], out JointMaskWidth[ArrayTav], out JointMaskHeight[ArrayTav]); #endregion } #region "Argument Error Checking" //Joint mask image width and height should be same //Joint mask image should have only black and white pixels inside it if (JointMaskImages[0].width != JointMaskImages[0].height) { Debug.LogError("JointMaskImage width and height should be same"); return null; } else { bool ErrorFound = false; //If Non-Black or Non-White pixel found //Check for pixel colors in joint mask image for (int rowtrav = 0; rowtrav < JointMaskImages[0].height && !ErrorFound; rowtrav++) { for (int coltrav = 0; coltrav < JointMaskImages[0].width && !ErrorFound; coltrav++) { Color PixelColor = JointMaskImages[0].GetPixel(coltrav, rowtrav); if (PixelColor != Color.white || PixelColor != Color.black) { ErrorFound = true; //Debug.LogError("Only white and black pixels are allowed in JointMaskImage"); //return null; } } } } #endregion TopJointMaskImage = new Color[PuzzleImgWidth][]; BotJointMaskImage = new Color[PuzzleImgWidth][]; LeftJointMaskImage = new Color[PuzzleImgWidth][]; RightJointMaskImage = new Color[PuzzleImgWidth][]; //Clear Instantiated mask image for (int i = 0; i < PuzzleImgWidth; i++) { TopJointMaskImage[i] = new Color[PuzzleImgHeight]; BotJointMaskImage[i] = new Color[PuzzleImgHeight]; LeftJointMaskImage[i] = new Color[PuzzleImgHeight]; RightJointMaskImage[i] = new Color[PuzzleImgHeight]; } //Generate random joint info And Draw joints Random.seed = System.DateTime.Now.Second; Color PieceColor = Color.black; for (int RowTrav = 0; RowTrav < Rows; RowTrav++) { for (int ColTrav = 0; ColTrav < Cols; ColTrav++) { int PieceX = ColTrav * PieceWidth; int PieceY = RowTrav * PieceHeight; //Generate Random joint info and Draw Joints From Mask Image #region "Draw right joints according to piece joint information" if (ColTrav < Cols - 1) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information int RndVal = (int)(Random.Range(1f, 18f) >= 10 ? 1 : 0); ResultPiecesData[RowTrav, ColTrav].AddJoint(new SJointInfo((EJointType)RndVal, EJointPosition.Right, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint])); int JointX = PieceX + PieceWidth; int JointY = PieceY + (PieceHeight / 2) - (RightJointMask[SelectedRandomJoint].height / 2); bool Result = false; SJointInfo RightJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Right, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Right Joints"); } else { if (RightJointInfo.JointType == EJointType.Male) drawJoint(ref RightJointMaskImage, RightJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #region"Draw left joints according to piece joint information" if (ColTrav > 0) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information bool Result = false; SJointInfo PreviousRightJoint = ResultPiecesData[RowTrav, ColTrav - 1].GetJoint(EJointPosition.Right, out Result); if (Result == false) { Debug.LogError("Logical error in joints information left joint"); } else { SJointInfo CalcLeftJoint = new SJointInfo(PreviousRightJoint.JointType == EJointType.Female ? EJointType.Male : EJointType.Female, EJointPosition.Left, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint]); ResultPiecesData[RowTrav, ColTrav].AddJoint(CalcLeftJoint); } int JointX = PieceX - LeftJointMask[SelectedRandomJoint].width; int JointY = PieceY + (PieceHeight / 2) - (LeftJointMask[SelectedRandomJoint].height / 2); Result = false; SJointInfo LeftJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Left, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Left Joints"); } else { if (LeftJointInfo.JointType == EJointType.Male) drawJoint(ref LeftJointMaskImage, LeftJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #region"Draw Top joints according to piece joint information" if (RowTrav < Rows - 1) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information int RndVal = (int)(Random.Range(1f, 17f) >= 10 ? 1 : 0); ResultPiecesData[RowTrav, ColTrav].AddJoint(new SJointInfo((EJointType)RndVal, EJointPosition.Top, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint])); int JointX = PieceX + (PieceWidth / 2) - (TopJointMask[SelectedRandomJoint].width / 2); int JointY = PieceY + PieceHeight; bool Result = false; SJointInfo TopJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Top, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Top Joints"); } else { if (TopJointInfo.JointType == EJointType.Male) drawJoint(ref TopJointMaskImage, TopJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion #region"Draw Bottom joints according to piece joint information" if (RowTrav > 0) { int SelectedRandomJoint = Random.Range(1, JointMaskImages.Length) - 1; //Create random joint information bool Result = false; SJointInfo PreviousPieceTopJoint = ResultPiecesData[RowTrav - 1, ColTrav].GetJoint(EJointPosition.Top, out Result); if (Result == false) { Debug.LogError("Logical error in joints information Bottom joint"); } else { SJointInfo CalcBottomJoint = new SJointInfo(PreviousPieceTopJoint.JointType == EJointType.Female ? EJointType.Male : EJointType.Female, EJointPosition.Bottom, JointMaskWidth[SelectedRandomJoint], JointMaskHeight[SelectedRandomJoint]); ResultPiecesData[RowTrav, ColTrav].AddJoint(CalcBottomJoint); } int JointX = PieceX + (PieceWidth / 2) - (BottomJointMask[SelectedRandomJoint].width / 2); int JointY = PieceY - BottomJointMask[SelectedRandomJoint].height; Result = false; SJointInfo BottomJointInfo = ResultPiecesData[RowTrav, ColTrav].GetJoint(EJointPosition.Bottom, out Result); if (!Result) { Debug.LogError("Logical error in draw joints from mask image Top Joints"); } else { if (BottomJointInfo.JointType == EJointType.Male) drawJoint(ref BotJointMaskImage, BottomJointMask[SelectedRandomJoint], PieceColor, JointX, JointY); } } #endregion } } return ResultPiecesData; }
/// <summary> /// Creates a deep copy of this class /// </summary> /// <returns>Returns a deep copy of this class</returns> public SPieceInfo MakeCopy() { SPieceInfo Temp = new SPieceInfo(_ID); foreach (SJointInfo item in _Joints) Temp.AddJoint(item); return Temp; }
/// <summary> /// Loads puzzle data from file stream of .pm file /// </summary> /// <param name="stream">Stream to load data from</param> /// <returns>Returns true if data loading is successfull false otherwise</returns> private bool LoadStreamData(System.IO.Stream stream) { System.IO.BinaryReader bReader = null; try { using (bReader = new System.IO.BinaryReader(stream)) { //Get secret number to check file intigrity int secretNumber = bReader.ReadInt32(); if (secretNumber != _secretVersionNo) { bReader.Close(); Debug.LogError("Error reading file. Make sure this file is created with puzzle maker`s current version"); return false; } //Get basic variables data _noOfPiecesInRow = bReader.ReadInt32(); _noOfPiecesInCol = bReader.ReadInt32(); _pieceWidthWithoutJoint = bReader.ReadInt32(); _pieceHeightWithoutJoint = bReader.ReadInt32(); //Origional puzzle image int lengthImageEncoded = bReader.ReadInt32(); byte[] imageEncoded = bReader.ReadBytes(lengthImageEncoded); _origionalImage = new Texture2D(100, 100); _origionalImage.LoadImage(imageEncoded); //Puzzle image with joints lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _image = new Texture2D(100, 100); _image.LoadImage(imageEncoded); //Created background image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _createdBackgroundImage = new Texture2D(100, 100); _createdBackgroundImage.LoadImage(imageEncoded); //Top joint mask image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _topJointsMaskImage = new Texture2D(100, 100); _topJointsMaskImage.LoadImage(imageEncoded); //Bottom joint mask image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _botJointsMaskImage = new Texture2D(100, 100); _botJointsMaskImage.LoadImage(imageEncoded); //Left joint mask image lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _leftJointsMaskImage = new Texture2D(100, 100); _leftJointsMaskImage.LoadImage(imageEncoded); //Right joint mask iamge lengthImageEncoded = bReader.ReadInt32(); imageEncoded = bReader.ReadBytes(lengthImageEncoded); _rightJointsMaskImage = new Texture2D(100, 100); _rightJointsMaskImage.LoadImage(imageEncoded); //Load joint mask array int lengthJointMaskArr = bReader.ReadInt32(); _jointMask = new Texture2D[lengthJointMaskArr]; for (int i = 0; i < lengthJointMaskArr; i++) { int TempLength = bReader.ReadInt32(); _jointMask[i] = new Texture2D(100, 100); imageEncoded = bReader.ReadBytes(TempLength); _jointMask[i].LoadImage(imageEncoded); } #region "Retreive Pieces Metadata" _CreatedPiecesData = new SPieceInfo[_noOfPiecesInCol, _noOfPiecesInRow]; for (int RowTrav = 0; RowTrav < _noOfPiecesInCol; RowTrav++) { for (int ColTrav = 0; ColTrav < _noOfPiecesInRow; ColTrav++) { int pieceID = bReader.ReadInt32(); //Get joints info int JointInfoLength = bReader.ReadInt32(); SPieceInfo TempSPieceInfo = new SPieceInfo(pieceID); for (int i = 0; i < JointInfoLength; i++) { int jointType = bReader.ReadInt32(); int jointWidth = bReader.ReadInt32(); int jointHeight = bReader.ReadInt32(); int jointPosition = bReader.ReadInt32(); TempSPieceInfo.AddJoint(new SJointInfo((EJointType)jointType, (EJointPosition)jointPosition, jointWidth, jointHeight)); } //Insert this piece data in list _CreatedPiecesData[RowTrav, ColTrav] = TempSPieceInfo; } } #endregion bReader.Close(); } } catch (System.Exception ex) { throw new System.Exception("Exception in load data 2: " + ex.Message); } return true; }
void OnRightCollision(int CollidingPieceId, GameObject ColP, SPieceInfo ColPPieceData, JPPieceController ColObjController) { //Check if this is child of current holding piece then apply collision logic bool IsChildOfHoldingPiece = false; JPPieceController[] ChildrenControllers = transform.GetComponentsInChildren<JPPieceController>(); foreach (JPPieceController item in ChildrenControllers) { if (ThisPieceData.ID == item.ThisPieceData.ID) { IsChildOfHoldingPiece = true; break; } } if (ThisPieceData.ID == JpPuzzleControllerInstance.HoldingPieceID() || IsChildOfHoldingPiece) { if (ThisPieceData.ID == CollidingPieceId - 1) { //If is child of holding piece make it parent //Make this piece parent of all Transform Temp = transform.root; transform.parent = null; Temp.parent = transform; JpPuzzleControllerInstance.UnholdPiece(); Vector3 CalculatedPos = new Vector3(); float LeftJointWorldScale = 0; float RightJointWorldScale = 0; float TopJointWorldScale = 0; float BotJointWorldScale = 0; float ColPLeftJointWorldScale = 0; float ColPRightJointWorldScale = 0; float ColPTopJointWorldScale = 0; float ColPBotJointWorldScale = 0; //Calculate required data CalculateDataForCollisionPlacement(ColPPieceData, out ColPLeftJointWorldScale, out ColPRightJointWorldScale, out ColPTopJointWorldScale, out ColPBotJointWorldScale); CalculateDataForCollisionPlacement(ThisPieceData, out LeftJointWorldScale, out RightJointWorldScale, out TopJointWorldScale, out BotJointWorldScale); //Calculate X //Calculated X without joints float CalcXWJ = ColP.transform.position.x - JpPuzzleControllerInstance.PieceWidthInWorld; CalculatedPos.x = CalcXWJ - (ColPRightJointWorldScale / 2) + (ColPLeftJointWorldScale / 2) + (RightJointWorldScale / 2) - (LeftJointWorldScale / 2); //Calculate Y CalculatedPos.y = ColP.transform.position.y + (TopJointWorldScale / 2) - (BotJointWorldScale / 2) - (ColPTopJointWorldScale / 2) + (ColPBotJointWorldScale / 2); CalculatedPos.z = transform.position.z; transform.position = CalculatedPos; ColP.transform.root.parent = transform; OnPieceJoined(); CheckForPuzzleComplete(transform); } } else { //Wrong Piece } }