# Snapping random letters into place

July 10, 2001
by Will Turnage

Hey Handyman,

I'd like to create a cool effect where you have letters floating around the screen and then have them snap into place when you rollover a certain part of the screen. I can't get it in Director, and if you can help me I would be greatly appreciative.

Jason Evans

Dear Jason,

Based on what you've described, here's an example of what this interface could look like:

To create this effect in a movie, you will have to write two different behaviors, one that will go on each of the floating letters and one that will go on each of the buttons. Most of the code will go into the behavior that controls the floating letters, so you should start that first. The first handler you should write will handle the random movement of the letters floating around the screen.

on travelRandomly me

randomDegree = random (360)
randomRadian = randomDegree * pi () / 360.0
newV = random (3) * sin (randomRadian)
newH = random (3) * cos (randomRadian)
pRandomVector = point (newH, newV)

end

This handler randomly picks a number between 1 and 360. Then it takes that degree value and converts it to radians. Once it has the degree in radians, it calculates the sin and cos of the angle and multiplies it by 3 (the number 3 is just an arbitrary multiplier used to make the numbers not quite speed across the screen, but also not move slowly either). The two numbers are then stored in a point that will determine how far your letter will randomly move each frame.

Next, you should create the movement of the letters across the screen. This is done each frame using an exitFrame handler.

on exitFrame me

pCurrentLoc = pCurrentLoc + pRandomVector
if (pCurrentLoc.locH >= (the stage).rect.width and pRandomVector.locH >= 0) then
pCurrentLoc.locH = 0
else if (pCurrentLoc.locH < 0 and pRandomVector.locH <= 0) then
pCurrentLoc.locH = (the stage).rect.width
end if
if (pCurrentLoc.locV >= (the stage).rect.height and pRandomVector.locV >= 0) then
pCurrentLoc.locV = 0
else if (pCurrentLoc.locV < 0 and pRandomVector.locV <= 0) then
pCurrentLoc.locV = (the stage).rect.height
end if
sprite (me.spriteNum).loc = pCurrentLoc

end

This handler uses the variable pCurrentLoc to store the location of the sprite. On each frame, it increments pCurrentLoc by the random amount you determined before. After you've moved the letter to its new location, you need to check to see if the letter has moved off screen. The code checks to make sure the letter hasn't run off each of the four edges of the stage. If it has, then it resets the location of the letter to the opposite edge of the stage.

The next step is to write the code that makes the letters snap into place to form words. There are several ways you can do this, but all methods require knowing where the letter should end up on screen. One way would be to add a property to the behavior and type in the specific location for each letter, however, an even easier way is to just have every letter start out in its exact location, like this:

Then all you have to do is put this handler in the behavior that goes on each letter.

on beginSprite me

pStartLoc = sprite (me.spriteNum).loc
pCurrentLoc = point(random ((the stage).rect.width), random ((the stage).rect.height))
sprite (me.spriteNum).loc = pCurrentLoc
me.travelRandomly ()

end

When each behavior begins, the first thing it does is store the on-screen location of the letter. Then it randomly picks a new location on screen, and moves the sprite to that location. Finally, it calls the travelRandomly handler to start the letter floating on-screen in a random direction. The best part of this approach is that this code is executed before the sprite is drawn on the screen for the first time. So even though the first frame of your movie looks like the picture above, when you run the movie it will never appear this way.

The final step in the letter's behavior is to trigger the movement that will move the letter to its fixed location on screen.

on snapToPosition me, framesToMove

pMoveVector = (pStartLoc - sprite (me.spriteNum).loc) / float (framesToMove)
pRandomVector = point (0, 0)
pMoveCounter = framesToMove

end

This handler is passed a number which tells the behavior how many frames it should take for the letters to reach their destination. In the sample movie above, this number was set to 15 frames, or half a second. The code uses this number to calculate how far the sprite should move for each of the next 15 frames. Next it sets the random movement vector to zero, and it stores the number of frames to countdown in a variable.

The final step requires a quick modification of the exitFrame handler you created earlier. Instead of automatically incrementing the sprite's location with the random vector, you have to check to see if the sprite is moving to its final destination. So you would replace the first line of your previous exitFrame handler with

if pMoveCounter > 0 then

pCurrentLoc = pCurrentLoc + pMoveVector
pMoveCounter = pMoveCounter - 1
if pMoveCounter = 0 then
pCurrentLoc = pStartLoc
end if
else
pCurrentLoc = pCurrentLoc + pRandomVector

end if

This code first checks to see if pMoveCounter is greater than zero. If it is, it means that the sprite should be moving to its fixed location on screen. It then increments the location of the sprite with the vector calculated in the snapToPosition handler. Next it subtracts one from the counter, and checks to see if the counter has reached zero. If the counter has reached zero, then it resets the location of the sprite to its original starting point.

And that's all there is to making the letters snap in place. The code for the colored buttons is incredibly simple, it just calls the snapToPosition handler on mouseEnter, and the travelRandomly behavior on mouseLeave.

A sample Director 8 movie is available for download in Macintosh or Windows format.

Will Turnage is a multimedia programmer based in New York City. In addition to his weekly role as Director Online's Multimedia Handyman, he is also the Technology Director for Sony Music's Client Side Technologies Group. You can read more about his work at http://will.turnage.com/.