Friday, February 21, 2014

iOS Jigsaw puzzle demo

A while ago someone on StackOverflow asked a question about creating a jigsaw puzzle game. He was not really sure what would be the best way to create puzzle pieces from a camera roll image.


At the beginning I suggested him to create a mask image for each piece and if pieces would be the same size and same count all the time, it would be enough. But I know that's not really a good way, so I decided to make a quick jigsaw puzzle demo, just to prove to myself that I can do it + gain extra experience.



So let's cut to the chase: I uploaded my experiment here: JigsawDemo and it has following features:

  1. Provide column/row count and it will generate necessary puzzle pieces with correct width/height;
  2. The more columns/rows - the smaller the width/height and outer/inner puzzle shape form;
  3. Each time randomly generated piece sides;
  4. Can randomly position / rotate pieces at the beginning of launch;
  5. Each piece can be rotated by tap, or by two fingers (like real puzzle pieces) - but once released, it will snap to 90/180/270/360 degrees;
  6. Each piece can be moved if touched on its “touchable shape” boundary (which is mostly the same visible puzzle shape, but WITHOUT inner shapes);

But this is just a demo, so:

  1. No checking if piece is in its right place;
  2. If more than 100 pieces - it starts to lag, because, when picking up a piece, it goes through all subviews until it finds correct piece. (For the sake of the demo, I left it that way..).


Puzzle piece creating explained in steps:

  1. Provide puzzle image; 
  2. Provide puzzle column and row count;
  3. Based on image size/width - we calculate each piece's width and height;
  4. Based on calculated width and height, we calculate piece's side shape deepness (in demo it is simply quarter of width/height - then it looks good in all sizes);
  5. Calculate puzzle piece side types randomly, keeping in mind these rules:

    • puzzle sides on the outside will always be straight;
    • puzzle sides on the inside will never be straight - either outer shape or inner shape;
    • left side of the next puzzle piece will have opposite shape. (If first piece right side was outer shape, then next piece left side will be inner shape).
  6. For each piece we calculate frames for image cropping, so that each cropped image would fill its puzzle piece;
  7. Then we create bézier paths for visual image clipping (so that it really would look like a real jigsaw puzzle piece) and bézier paths for touch recognition. We can use the same bézier path, but as I tested this demo, I noticed, that it is pretty hard to pinch rotate a piece, if a piece is small and have at least two inner side shapes - thus, I decided to create another bézier path shape for easier touch recognition - for each visual image clipping path, every inner side shape will be saved as straight side;
  8. Then we create UIImageView for each puzzle piece. We crop it, position it, add touch recognition shape, add border line shape. We also add rotation and panning gesture recognisers;

That's it - puzzle pieces are ready to be visible and interacted with! 

No comments:

Post a Comment