By setting the chosen image to be of the same width and height as the group that holds the puzzle pieces (that's where the 900 and 662 numbers came from), it becomes possible for us to transfer the matching rectangle of data from the full image to the puzzle piece in question. The following steps will guide you in transferring imageData:
makepuzzle
handler:on makepuzzle resetpuzzle put the number of images in group "pieces" into imagecount repeat with a = 1 to imagecount makepiece the short name of image a of group "pieces" end repeat end makepuzzle
makepuzzle
handler will go through each of the puzzle pieces and call another handler to do the transfer of data for that one piece. Here is the makepiece
handler:on makepiece piecename put the width of image piecename into piecewidth put the height of image piecename into pieceheight put empty into tempimage put the left of image piecename - the left of group "pieces" into dx put the top of image piecename - the top of group "pieces" into dy repeat with y = 1 to pieceheight put ((y+dy-1) * puzzlewidth + dx)*4 into sourcestart put char sourcestart+1 to sourcestart+piecewidth*4 of originalimage after tempimage end repeat set the imageData of image piecename to tempimage end makepiece
imageData
tests, we were only interested in one pixel at a time, but here, we want lots of rows of data. The arithmetic, ((y+dy-1) * puzzlewidth…, and so on, quickly pull out a whole row of pixels at a time. These rows are built up into a new variable, tempimage
, which is finally transferred into the actual puzzle piece.imageData
, we then need to move the pieces into random places, making the game ready for the user to play. This is done with a scatter
handler:on scatter repeat with a = 1 to the number of images in group "pieces" set the myloc of image a of group "pieces" to the loc of image a of group "pieces" put the short name of image a of group "pieces" into n if edgepiece(n) then set the loc of image a of group "pieces" to 40 + random(400),300 + random(400) else set the loc of image a of group "pieces" to 500 + random(500),300 + random(400) end if end repeat end scatter
edgepiece
function (which is called from the preceding scatter
handler) is this:function edgepiece pName return word 2 of pName = 1 or word 3 of pName = 1 or word 2 of pName = hcount or word 3 of pName = vcount end edgepiece
makepuzzle
handler calls a resetpuzzle
handler that is used to make sure that the pieces are back where they started, ready for a new picture to load. This is achieved when you use a property variable on each piece named myloc
, which records the initial location of the piece. Here's the resetpuzzle
handler:on resetpuzzle repeat with a = 1 to the number of images in group "pieces" if the myloc of image a of group "pieces" is not empty then set the loc of image a of group "pieces" to the myloc of image a of group "pieces" else set the myloc of image a of group "pieces" to the loc of image a of group "pieces" end if end repeat end resetpuzzle
myloc
is not already set, then the piece must be in its start position, and so, the resetpuzzle
handler goes ahead and records that location in the myloc
property.makepuzzle
and scatter lines) and try another test of the app. You should now be able to choose a picture and see it in the spread out puzzle pieces. Hopefully, you will see something like this:As mentioned in the preceding section, the right arithmetic made it relatively easy for us to extract a desired rectangle of imageData
from a larger image, and store it in a smaller image that was the size of that rectangle. However, there's one bit of magic that wasn't pointed out, the puzzle kept its shape! Even though we had completely replaced imageData
for the image, how did this happen? Setting imageData
doesn't interfere with
alphaData
of the image. The PNGs that we imported kept their original alpha channel and so still had the same shape, but just a different image.