I know how to make a standard rollover, but I want to make fancier, animated buttons. I tried making a repeat loop, but then only one button responds and nothing else can happen for a while. How can I have them all going at once?
You can really jazz up a simple projects with a little animation. A
moving button is almost always more interesting than a standard 2 or 3 state one, but can
pose a problem with how to make it work. Film loops are an option, but if the user
rolls out during the animation it snaps back and is noticeably rough. You can use
repeat loops, but then you block out any other lingo while the loop is running. This
is a perfect opportunity to use the actorList and the on stepFrame handler. You
could do something similar with an exitFrame handler and a global list, but Director's
actor list and stepFrame handlers are optimized for speed and efficiency.
Before we start coding, we need to decide what our button will
"do". For this example I have a simple block that rises for 15 frames and
then goes back down over the next 15. Since the motion is the same I can re-use the
same 15 cast members for both. After rendering the images and importing I need to
make sure the naming us in a useful form. I chose to simply use a "prefix"
followed by a number. Each graphic will be named "Button" and a number
like so...Button1, Button2, Button3, etc.
Now, we can rename all of these, or we can let lingo do it for us.
Here is a simple script I wrote for renaming sequential frames for lingo controlled
animations...
on rename whatCast, startMember, endMember, startNum, prefix
theOffset = startMember - startNum
repeat with x = startMember to endMember
member(x, whatCast).name = prefix & string(x - theOffset)
end repeat
end
on getBehaviorDescription me
return "Call this to rename a rang of castmember with a prefix and sequential
numbers. I.E. Member1, Member2, Member3, etc."
end
Now we are ready to start coding. The basic idea is to allow our mouseEnter and
mouseLeave handlers to tell the button what action or "state" it is to perform.
From that the stepFrame handler checks this variable and then does the appropriate
action each time the play head moves. Doing this we can have a virtually unlimited
number of buttons going at once. To speed up things we only add items to the actor
list when necessary and only if they are not already in the list. This is important
to keep the action from executing itself twice per frame. We also need to remove it
when it is no longer needed to free up memory, but be careful nit to do this inside the
stepFrame handler, as it can cause errors at runtime. (Another words, don't edit the
actorList while lingo is using it.)
Here is the basic handler. Notice how the mouseEnter and mouseLeave handlers only
change the "state" property. Everything else is done in the stepFrame
handler and the enterFrame handler does the "cleanup" of unneeded instances of
the script.
on beginSprite me
currentNum = startMember
state = 0
end
on mouseEnter me
--add to the actorList if not already there
if getOne(the actorList, me) = 0 then add the actorList, me
state = 1 --Go up
end
on mouseLeave me
state = 2 --Go down
end
on stepFrame me
case state of
0, 3 :
nothing
1 :
--go up
currentNum = currentNum + 1
if currentNum > endMember then currentNum = endMember
sprite(spriteNum).member = prefix & string(currentNum)
2 :
--go down
currentNum = currentNum - 1
if currentNum < startMember then currentNum = startMember
sprite(spriteNum).member = prefix & string(currentNum)
--check to see if the item is done
if currentNum = startMember and the rollover <> spriteNum then
--remove from the actorList on next enterFrame
state = 3
end if
end case
end
on exitFrame me
if state = 3 then
deleteOne the actorList, me
state = 0
end if
end
on getBehaviorDescription me
return "This behavior will animate a button using numbered cast members
with a set prefix when the mouse rolls over it and moves back off. It is important
to not skip any frames and that no extra zeros are used in the names. (I.E.
do not use 001, use 1)."
end
Drop it on the sprite and it will prompt you for the prefix of the cast member names,
the start frame and the end frame (of the animation). Give it a frame to initialize
the beginSprite handler in authoring mode (start on frame 2 or later for it to work
properly in authoring mode. If you start on frame 1 then the beginSprite handler
will not run, causing errors. This won;t happen in a projector.) Here is
an "overkill" example of the script in action...
Play with it and see what else you can add. Using additional "states"
you can have it play a different animation when the mouse leaves, have a click animation,
etc. Play with it and see what you can come up with.
As usual, you can also find all of these behaviors/scripts in the behavior database.
Contact
MMI
36 South Court Sq
Suite 300
Newnan, GA 30263
USA