Articles Archive
Articles Search
Director Wiki
 

""Goo" With Director 8

April 12, 2000
by Gary Rosenzweig

This week in the Lingo Lounge we have a request. A reader asks: "There's this program called Goo, that lets you drag and stretch images from anywhere you click on the mouse. In Director 8, they have the image lingo and one example that lets you pull on the corners of the image to distort it, but not from anywhere inside the image. Is there a way to do this, a trick of some kind to emulate Goo?"

At first, I thought: well, no, there still isn't a way to do something like this. Then, a few seconds later it occurred to me that there is a way. Not only that, but it was pretty simple.

The new Director 8 imaging Lingo includes copyPixels, a command that lets you take a rectangular area of one image and copy it into a rectangular area of another. But you can also take that rectangular area and copy it into a quad area in another. This quad would be represented by four points, just like sprite quads. The rectangle's four corners would be stretched to match these four points, even if they do not represent a perfect rectangle. When the user clicks on a point in the image to drag it, we can look at the image as four separate rectangles. Figure 1 shows these rectangles and how the click point divides them.

Once the user clicks the image and holds down the mouse button, the fun begins. We take these four rectangles and create a list of four images. Then, every frame, we redraw the four images into the member. However, instead of using the original rectangle locations of these four images, we will use four quads. These four quads will be generated by the original edge positions of the four rectangles, plus the new location of the cursor.

Figure 2 shows what the quads would look like if the user drags down and to the right. Three points of each quad are the same as the original rectangles of the four images. However, the middle point of each rectangle is not locked to the cursor.

To create a program to do this, we only need one behavior. This should be attached to the image's sprite. This behavior starts off by recording constants, such as the width and height of the image, the location of the upper left corner of the sprite,and the original image so that it can be restored when the sprite ends. We will also use the property "pImageList" to store the four sub-images, as well as "pDrag" to determine if the user is currently stretching the image.

property pDrag
property pImageList
property pWidth, pHeight
property pClickPoint
property pOriginalImage
property pUpperLeft

on beginSprite me
  
  pDrag = FALSE
  pWidth = sprite(me.spriteNum).member.width
  pHeight = sprite(me.spriteNum).member.height
  pOriginalImage = duplicate(sprite(me.spriteNum).member.image)
  pUpperLeft = point(sprite(me.spriteNum).left,sprite(me.spriteNum).top)
  
end

When the user clicks down in the image, we record the click location relative to the upper left corner of the sprite. Then, we create a list of four new images, populating each with the quarter of the original image that it represents.

on mouseDown me
  
  pDrag = TRUE
  
  pClickPoint = the clickLoc - pUpperLeft
  x = pClickPoint.locH
  y = pClickPoint.locV
  
  origImage = sprite(me.spriteNum).member.image
  pImageList = []
  
  add pImageList, image(x,y,32)
  pImageList[1].copyPixels(origImage,rect(0,0,x,y),rect(0,0,x,y))
  
  add pImageList, image(pWidth-x,y,32)
  pImageList[2].copyPixels(origImage,rect(0,0,pWidth-x,y),rect(x+1,0,pWidth,y))
  
  add pImageList, image(x,pHeight-y,32)
  pImageList[3].copyPixels(origImage,rect(0,0,x,pHeight-y),rect(0,y+1,x,pHeight))
  
  add pImageList, image(pWidth-x,pHeight-y,32)
  pImageList[4].copyPixels(origImage,rect(0,0,pWidth-x,pHeight-y),rect(x+1,y+1,pWidth,pHeight))
  
end

For frames after the click, the "pDrag" property is TRUE. Every frame we then figure out the four quads that represent the new four sections of the image. We use copyPixels to copy the rectangles into these quads.

on exitFrame me
  
  if pDrag then
    
    x1 = pClickPoint.locH
    y1 = pClickPoint.locV
    
    pCurrentPoint = the mouseLoc - pUpperLeft
    x2 = pCurrentPoint.locH
    y2 = pCurrentPoint.locV
    
    origImage = sprite(me.spriteNum).member.image
    
    origImage.copyPixels(pImageList[1],\
     [point(0,0),point(x1,0),point(x2,y2),point(0,y1)],\
     rect(0,0,x1,y1))
    
    origImage.copyPixels(pImageList[2],\
     [point(x1,0),point(pWidth,0),point(pWidth,y1),point(x2,y2)],\
     rect(0,0,pWidth-x1,y1))
    
    origImage.copyPixels(pImageList[3],\
     [point(0,y1),point(x2,y2),point(x1,pHeight),point(0,pHeight)],\
     rect(0,0,x1,pHeight-y1))
    
    origImage.copyPixels(pImageList[4],\
     [point(x2,y2),point(pWidth,y1),point(pWidth,pHeight),point(x1,pHeight)],\
     rect(0,0,pWidth-x1,pHeight-y1))
    
  end if
  
end

The dragging stops when the user lifts up the mouse. We will also place an on endSprite handler in this behavior to restore the original member image when the sprite leaves the Stage or the movie stops.

on mouseUp me
  pDrag = FALSE
end

on mouseUpOutside me
  pDrag = FALSE
end

on endSprite me
  sprite(me.spriteNum).member.image = pOriginalImage
end

This last handler could also be used as an undo button. It will restore the image to its original picture. Since this program will allow the user to continually drag and distort the image, you could also store another version of the image just as every drag starts, and have a single-action undo that puts this image back into the member. The sample movie here lets you play with a face, a typical example of such an application. Have fun.

Director 8 Download for Mac or PC.

Gary Rosenzweig's latest book is "Advanced Lingo for Games." In it, you can find the source code for more than 20 complete games. More information about the book can be found at http://clevermedia.com/resources/bookstore/book4.html. It can be purchased there, or in your local bookstore.

Gary Rosenzweig is the Chief Engineer, founder, and owner of CleverMedia, a game and multimedia development company in Denver, Colorado. He is the author of ten books on Macromedia Director and Flash, including his latest, Special Edition Using Director MX.

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