# Build Jigsaw Puzzle Pieces with Imaging Lingo

March 5, 2004
by Michael Pelzer

Intro

I built a jigsaw puzzle game to improve my daughter's mouse usage skills. I wanted to have the game take one of her favorite pictures and divide it into several pieces.

The challenge was how to cut the whole picture - on the fly - into pieces. The pieces should look like real jigsaw pieces, each with a unique shape.

I decided to use a mask for cutting the pieces with imaging lingo.

Preparation

My pictures must be the same size - so I used Fireworks for resizing them. Then I built a a black and white image of the jigsaw piece shapes. I did this by using a some jigsaw software, importing a black image, and then taking a screenshot of the cut-up black jigsaw puzzle. You can hand-draw yours or use a different method to create the puzzle mask.

Then I colored each piece of the puzzle a different color and changed the borders to gray.

Now the mask was ready. It contained n+1 different colors. It is important that the borders have one color, as this gives me the possibility to get a frame image as well.

Lingo Coding

In Director I created a cast library named "Pieces" as a container for all the single pieces.

on DeletePieces
-- delete the old/last pieces ...
repeat with n = 1 to the number of members of castLib("Pieces")
member(n, "Pieces").erase()
end repeat
end

Imaging Lingo

on BuildPieces
DeletePieces -- delete the old/last pieces ...

pictMem = member("venedig")
pictImg = member(pictMem).image -- Picture

return
end if

Then we want to know how many pieces are in the mask.

We can determine this by scaning the mask pixel by pixel, counting the different colors and storing them in a list.

-- how many colors/pieces has the mask?
lstCol = []

repeat with y = 0 to h-1
repeat with x = 0 to w-1

-- is this color already in the list
pos = getPos(lstCol, mc)

-- if not -> append
if pos = 0 then
end if
end repeat
end repeat

After that, we know how many colors are used and how many pieces we need, so we create empty bitmap members in the cast "Pieces".

-- the first color is for the border
put lstCol.count-1, lstCol

-- build for every color/piece an empty bitmap-image

repeat with n = 1 to lstCol.count
set newMem = new(#bitmap, castLib "Pieces")

newMem.image = image(w,h,24)

newMem.name = "P-" & n-1
end repeat

Finally, we scan the mask again pixel by pixel. We copy pixels from the source picture to a jigsaw piece image using the colors of the mask as a guide. The index of the color gives us the destination member.

-- now scan the mask ...

repeat with y = 0 to h-1
repeat with x = 0 to w-1

pos = getPos(lstCol, mc) -- index of the color-list
this = "P-" & pos-1

-- copy every pixel from the source-pict to one of the pieces
pc = pictImg.getPixel(x,y) -- picture-color
member(this).image.setPixel(x,y, pc)

end repeat
end repeat

end

That's all, now the cast "Pieces" holds all the jigsaw pieces.

Assembling the Game

All of the pieces have the same reg-point. So we can put them all to the stage and see the whole picture.

And because of the first member is the border, we can reduce the blend of its sprite and get a frame/background for the player.

For a full game, we shuffle the positions and need a behavior for moving the pieces.

You'll find that in the source of the movie.

Conclusion

This is another example about the wide possibilities of imaging Lingo. With imagination you can use this technique for other types of image processing as well.

Michael Pelzer lives and works in Vienna, Austria. He is a software developer with a focus on multimedia programming. He has worked with Director since 1997, developing CD-ROMs and Shockwave games. As a special project , he built a full Director/Lingo/PrintOmatic-Based layout application for Print/CD-ROM/Web-publishing of a price list with database-access. You can find him at www.pelzer.at or www.gamedesign.at