Articles Archive
Articles Search
Director Wiki
 

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

Let's start with initializing some variables and basic information about the used pictures.

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

  maskMem = member("PuzzleMask")
  maskImg = member(maskMem).image -- Puzzle-Mask

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

  
  if (maskMem.width <> pictMem.width) or (maskMem.height <> pictMem.height) then
    alert ("Mask & Pict must have the same size!")
    return
  end if

  w = maskMem.width
  h = maskMem.height

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
      mc = maskImg.getPixel(x,y) -- mask-color
      
      -- is this color already in the list
      pos = getPos(lstCol, mc)
      
      -- if not -> append
      if pos = 0 then
        add lstCol, mc
      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
      mc = maskImg.getPixel(x,y) -- mask-color
      
      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

Copyright 1997-2024, Director Online. Article content copyright by respective authors.