Scrolling Images using Imaging Lingo
April 16, 2000
by Pat McClellan
Dear Handyman,
I have read your article on image scroller and find it extremely useful. I wonder can this be use for a huge image like map navigation? If this is not efficient, then the map will have to break down into pieces. But how to use Lingo to join the related map pieces together when needed?
Wong Boon Hong
Dear Boon Hong,
As you suggest in your question, moving a very large sprite around is not very efficient. Traditionally, the way to handle this would be to cut your large image into small sections, then swap them into two or more sprites with coordinated motion. This is still not a bad approach, but I can't resist showing you a new way to do it!
One of the coolest new features in Director 8 is the Imaging Lingo. This new feature is really a set of new Lingo commands that literally let you redraw bitmap cast members. It's now fairly easy to copy a section of one bitmap and paste it into another one -- or even into itself. The applications for this are almost endless.
In our situation, we can use the feature to copy portions of the large image into a smaller member which occupies the stage. In this way, the sprite onstage will have a bitmap graphic member that is no larger than the stage itself. As you move in a particular direction, the new graphic info will be copied from the source graphic image and the graphic onstage will be redrawn to show a new view. Is this more efficient than the "old way"? I'm not sure. I didn't do any speed tests on it, but I like the concept of it much better.
The specific Lingo command that we'll be using is copyPixels(). Here's how the syntax looks:
destinationImage.copyPixels(sourceImage, sourceRect, destinationArea,{optional parameters})
That can be a little intimidating at first, but it's really not too difficult. The function copyPixels() is applied to the image you want to change (what I called destinationImage). You have to provide it the sourceImage, the portion of that image to be copied (in rect format), and then the area of the destinationImage into which you want to paste the copied bits. This destination area can be in rect format, or expressed as a quad (see Gary Rosenzweig's Goo article for a cool use of the quad format.) There are some optional parameters you can supply, but we don't need them for this. Check the Lingo dictionary for more info on these optional parameters.
In the image scroller article I did before, I created the behavior so that you can define the window in which the image scrolls. In that situation, if the window was smaller than the stage, you would need to put another sprite on top of it to mask off the area outside the window. For this demo, I realized that we only need one sprite -- no mask. That's because the scrolling image will simply be pasted into the window rect. Take a look at the demo:
View the Shockwave demo (448K)
Shockwave 8 required. Director 8 download for Mac (2.7 MB)or Windows (2.5 MB).
In the first example above, the arrow buttons activate the slide for the graphic. The background color and the scrolling image are the same sprite. In the second example (it autoscrolls when the cursor gets toward the edge of the window), there are two images that scroll in two different windows. But again, this is all the same sprite -- a single cast member -- that is being displayed on the stage. That cast member is being dynmically redrawn on every exitFrame, copying a new portion of one of the source images into the respective window.
For people who have a strong concept about how Director works, this seems really strange... but also very exciting when you think about what dynamic image rendering can mean. This is precisely the mechanism that makes it possible to have the Sprite Transitions that are in the D8 Library Palette.
Back to this behavior. The code for this behavior is not a lot different than the behaviors in the other article. We do need a few new properties, such as pMyImage and pSourceImage. With this Imaging Lingo, there's a new property called image. They can be set using this syntax:
pMyImage = sprite(me.spriteNum).member.image
pSourceImage = pSourceMem.image
In this case, pSourceImage is a property that appears in the getPropertiesDescriptionList dialog box. We'll also have to set up initial values for the pWindowRect (the area of pMyImage into which we'll be copying the new image), and pSourceRect (the portion of the source image that we're copying). The pSourceRect will constantly be updated as the image moves, but the pWindowRect will remain constant (a static view window on the stage).
The handlers that check to see whether to slide, and if so, which direction to slide, remain the same. It's the slideRight, slideLeft, slideUp, and slideDown handlers that we need to change. This is where the adjustment of the pSourceRect will take place, as well as the actual copyPixels() operation. I'll show you the slideRight handler; you can see the others in the download.
on slideRight me
newRect = pSourceRect.offset(- pSpeed, 0)
if newRect.left > 0 then
pSourceRect = newRect
pMyImage.copyPixels(pSourceImage, pWindowRect, pSourceRect)
end if
end slideRight
In the download demo, I've included some other source images for you to play with. You can simply select a different source image in the gpdl dialog box, and that will become the new image in the window. In this way, you could change levels of a game by simply changing the source graphic. Good luck with your project.
Copyright 1997-2024, Director Online. Article content copyright by respective authors.