Shining a Flashlight with Alpha Channels

by Gary Rosenzweig

The new Imaging Lingo is sure to be the most talked about feature of Director 8. There's so much that can be done with it that even the developers that have played with it during the beta test haven't begun to scratch the surface.

This week, let's recreate an old favorite behavior: the flashlight. This is where the entire image is invisible, except the spot under the cursor. This area can be seen, just as if the room was dark and flashlight was shining on this one part.

With Director 7 and before, this was possible by using ink effects like lightest and darkest. However, it was hard to get it to work with other graphics in the same space, plus creating nice fuzzy edges was not possible where colors were involved. With Director 8, we can do a flashlight effect with Imaging Lingo. There are actually many ways to go about doing this. You can use copyPixels with a mask to copy only a portion of the image into another image that is on the Stage, for instance.

Alpha channels, however, make this as easy as possible. All we need to do is set the alpha channel of the entire image to 0, thus making it all invisible and transparent. Then, if we place a circle of black in the middle of the alpha channel, we get a portion of the image that is visible. Check out the Shockwave movie below.

NOTE: Shockwave 8 required
D8 download for Mac or Windows.

As you move the cursor over the Shockwave movie, the image is revealed under the cursor. The actual alpha channel is altered by using a 256-color grayscale bitmap in the Cast. We simply create a blank alpha channel, and then use copyPixels to place the grayscale bitmap somewhere inside this alpha channel image. We then apply this alpha channel to the image on the Stage by using setAlpha. Here is the code. Much of it actually deals with positioning the visible area.

property pEmptyAlpha
property pViewPortal
property pViewRect
property pMouseOffset

on beginSprite me
  
  -- set alpha to completely transparent
  sprite(me.spriteNum).member.image.setAlpha(0)
  
  -- get a copy of this empty alpha channel
  pEmptyAlpha = sprite(me.spriteNum).member.image.extractAlpha()
  
  -- get the grayscale image to be used as a view area
  pViewPortal = member("view area").image
  pViewRect = pViewPortal.rect
  
  -- determine the middle of the view area
  pMouseOffset = point(pViewRect.width/2,pViewRect.height/2)
  
end

on exitFrame me
  
  -- determine the location of the cursor
  loc = the mouseLoc - pMouseOffset
  
  -- create a new alpha channel to use
  newAlpha = duplicate(pEmptyAlpha)
  
  -- figure out where the view area will go
  rec = pViewRect + rect(loc,loc)
  
  -- insert the view area into the alpha channel
  newAlpha.copyPixels(pViewPortal,rec,pViewRect)
  
  -- set the alpha channel
  sprite(me.spriteNum).member.image.setAlpha(newAlpha)
  
end

Check out the movie source. Try playing with the "view area" bitmap. You can easily change the shape of the visible area. You can also use shades of gray to fade the image around the edges.