Animated Buttons

  1. Generic Button Script by Peter R. Bream Jr.
  2. Generic Button Script by Marvyn Hortman
  3. Generic Button Script by John Dowdell
  4. Generic Button Script by Matt Craig
  5. Generic Button Script by Kurt Cagle
  6. Generic Button Script by Mark Hagers
  7. Using QuickTime for Buttons by Gordon G. Miller, III

Generic Button Script: Peter R. Bream Jr.

1st: create two versions of your button one up and one down, be sure to use fill of the background color of the edges of the "down" button, or else, it won't look right. In the score, put your "up" button in a channel and give it the following handler: "switchButt (sprite#, cast#of down cast, macro(which contains the handler you want done when the button is pressed))
on switchButt spriteNum, castDown, macroName
  puppetSprite spriteNum, TRUE
  set flag = 0
  set SaveCast = the castNum of sprite spriteNum --saves the previous button
  put swapCast( spriteNum, saveCast, castDown) into flag
  puppetSound "click" --this is a sound I used to make it work
  repeat while the stillDown --this allows the person to move the cursor away
    put swapCast( spriteNum, saveCast, castDown, flag) into flag
  end repeat
  puppetSprite spriteNum, FALSE
  if flag = 1 then do macroName --macroName is your handler for the button
 end switchButt
 
on swapCast spriteNum, saveCast, castDown
  if rollover( spriteNum ) then
    set the castNum of sprite spriteNum = castDown
    updateStage
    return 1
  else
    set the castNum of sprite spriteNum = SaveCast
    updateStage
    return 0
  end if
end swapCast

MOST IMPORTANTLY, you must have a looping channel (go marker(0)) so that it will work
Peter R. Bream  Jr. 
University of North Carolina 
School of Medicine 
bream@med.unc.edu

Generic Script: Marvyn Hortman

Date:    Mon, 8 Aug 1994 16:43:47 -0500
From:   Marvyn Hortman (hortman_m@hccs.cc.tx.us)

> I have a factory to take care of my button animation. Depending on
> which method I want to use, I can track the rollover, etc. This lets
> the user move the mouse off the button before releasing their mouse
> button in order to not activate a button. By actually moving a
> different cast member and replacing it's graphic,
Hi! Thought I'd jump in here.

Forgive me, but instead of setting up a factory, couldn't you have just used the "stilldown" property to detect whether your mouse was still down over the area you wanted, and then switched the sprites accordingly?

I'm not second-guessing you, and maybe I don't understand exactly what you're trying to do, but I've used this in similar situations without having to create a factory for this purpose.

It works something like the following: (note this is an example of using "stillDown"--I'm not adding in the additional complexities of the thread on using one or two channels for multiple buttons--this is just to get the general idea and I'm doing this off the top of my head so my logic may not be quite right)


on mouseDown
  put the clickOn into originalSpriteClicked
  put the locH of sprite originalSpriteClicked into x
  put the locV of sprite originalSpriteClicked into y
  set the locH of sprite originalSpriteClicked = (x + 2)
  set the locV of sprite originalSpriteClicked = (y + 2)
  updateStage

  repeat while the stillDown
    if the mouseCast <> originalSpriteClicked then
      set the locH of sprite originalSpriteClicked = x
      set the locV of sprite originalSpriteClicked = y
      updateStage
    end if
  end repeat

  if the mouseCast = originalSpriteClicked then
    set the locH of sprite originalSpriteClicked = x
    set the locV of sprite originalSpriteClicked = y
    doSomeHandler
  else
    set the locH of sprite originalSpriteClicked = x
    set the locV of sprite originalSpriteClicked = y
  end if
end mouseDown


Generic Button Script: John Dowdell

Date:    Wed, 10 May 1995 12:53:35 EDT
From:    John Dowdell <71333.42@COMPUSERVE.COM>
Subject: Re: button switching problem
Todd Page writes on May 9, "I'm creating a movie that when you clickdown on a button with the mouse the sprite changes to a depressed button and stays untill the mouseUp, then it changes back to the original button. I have no problem with this if i use "pause", but I have sound in the movie also and the sound stops using "pause". I tried using "go to the frame" but the sprite change is only for a split second but the sound still plays. Should I play an external sound and use pause or what????????? Help!!!!!!!!!!!"

That Lingo "pause" command will pause everything, Todd... audio, video, movie-in-a-window, toda. To keep things live people usually use one-frame loops of "go the frame" nature.

In your case, though, it sounds like the following generic button handling may help. It assumes that the "down" artwork for the button immediately follows the "up" artwork in the Cast.

 
  on mouseDown
    set image = the mouseCast
    set chan = the clickOn
    repeat while the stillDown
      set the castNum of sprite chan = image + rollover(chan)
      updateStage
    end repeat
    if rollover(chan) then........
  end mouseDown
 
This does not require that the button be "puppeted", as your previous handling did. (An animation channel's "puppet" property, if enabled, tells Director to ignore the Score and let Lingo pull the strings. At each frame advance Director consults the Score for instructions on each channel unless you puppet that channel.)
Regards,
John Dowdell
Macromedia Tech Support

Generic Button Script: Matt Craig

Date:    Wed, 11 Jan 1995 18:22:36 +1030
From:    Matt Craig 
One easy way to do it is to give your buttons similar names, with a different suffix, eg "button.up", "button.down"

then you could have a handler function in a movie script (called from a cast or sprite script) such as:

-- The following script 'hilites' a button depending on if the mouse is over the button or not. It first looks for a complementary ".down" castmember, and if this is not found, it just pushes the button down and right by 1 pixel. The function returns true only if the mouse is released over the button

on pressButton
  set sNum to the clickOn
  set cNum to the castNum of sprite sNum
  set cName to the name of cast cNum
  puppetSprite sNum,true
  set foundDown to false
  if cName > "" then
    set the itemDelimiter to "."
    set preName to item 1 of cName
    set the itemDelimiter to ","
    set downName to preName & ".down"
    set downNum to the number of cast downName
    if downNum > 0 and downNum <> cNum then
      set foundDown to true
      set the castNum of sprite sNum to downNum
      repeat while the mouseDown
        if rollover(sNum) then
          set the castNum of sprite sNum to downNum
        else
          set the castNum of sprite sNum to cNum
        end if
        updateStage
      end repeat
      if the castNum of sprite sNum = downNum then
        set the castNum of sprite sNum to cNum
        set myResult to true
      else
        set myResult to false
      end if
      puppetSprite sNum,false
      updateStage
      return myResult
    end if
  end if
  if not foundDown then
    set myH to the locH of sprite sNum
    set myV to the locV of sprite sNum
    set the locH of sprite sNum to myH + 1
    set the locV of sprite sNum to myV + 1
    repeat while the mouseDown
      if rollover(sNum) then
        set the locH of sprite sNum to myH + 1
        set the locV of sprite sNum to myV + 1
      else
        set the locH of sprite sNum to myH
        set the locV of sprite sNum to myV
      end if
      updateStage
    end repeat
    if the locH of sprite sNum = myH + 1 then
      set the locH of sprite sNum to myH
      set the locV of sprite sNum to myV
      set myResult to true
    else
      set myResult to false
    end if
    puppetSprite sNum,false
    updateStage
    return myResult
  end if
end 
and in the cast/sprite script all you would need is
 
on mouseDown
  if pressButton() then ...
end

Generic Button Script: Kurt Cagle

There's a property called "the clickon" which will contain the last sprite channel WITH A SCRIPT IN IT that was clicked on. This is at the heart of most button "engines". A real useful script I've developed for just such a problem is:
 
on PressButton myspritenum,myticks
    if voidP(spritenum) then
         set spritenum=the clickon
    else
         set spritenum=myspritenum
    end if
    if voidP(myticks) and myspritenum>0 then
         set myticks=30
    end if
    set castname=the name of cast (the castnum of sprite spritenum)
    puppetsprite spritenum,TRUE
    set oldtimer=the timer
    StartTimer
    repeat while (the mouseDown) or ((myspritenum>0) and (myticks<the timer))
         if rollover(spritenum) then
            set the castnum of sprite spritenum to the number of cast (castname&"Down")
         else
           set the castnum of sprite spritenum to the number of cast (castname)
         end if
         updateStage
     end repeat
     set the timer=oldTimer+the Timer
     set the castnum of sprite spritenum to the number of cast castname
     updateStage
     puppetsprite spritenum,FALSE
     if rollover(spritenum) then
          return spritenum
     else
          return 0
     end if
end PressButton
This routine relies on the down state of the button having the name of the up state of the button with "Down" appended to it (i.e., "myBtnDown" for "myBtn") It returns the sprite number of the button that was depressed if the user releases the mouse over the button, and 0 if the user releases outside the perimeter of the button.

It can also be used to automatically press a button for a specific interval. So, if I wanted to press the button in sprite channel 7 for a second (60 ticks) I'd type

    pressbutton 7,60
The timed button defaults to 30 ticks (i.e.
    pressbutton 7
is the same as
    pressbutton 7,30
Hope this helps.
 
Kurt Cagle
The Center for Multimedia
(206) 643-9039

Generic Button Script: Mark Hagers

Date:    Fri, 17 Nov 1995 18:14:15 +0100
From:    Mark Hagers 
Subject: generic button script revisited
I was informed by a friend of the fact that my generic button script, that I posted some months ago on this list, has made it to the director tips and scripts page, thanks to whoever put it there for the compliment. I have augmented the script with another script that goes into the frame script of any frame in an animation and provides for another aspect of button behaviour that many people want: it lets buttons hilite when the mouse is over them (without the mouse button being pressed) to give a visual clue of which items on screen are clickable. here it is:

this handler goes in a movie script:

  on rollTest theSpriteList
    repeat with i in theSpriteList
      set the visible of sprite i to rollover(i)
    end repeat
  end
the following handler goes into the frame script of any frame that contains buttons that should display this behaviour:
  on exitFrame
    rolltest [12,22,34]   -- or any combination of channels you want
    go to the frame
  end
The channels that are listed in the call to rollTest should contain the hilited version of the buttons. The unhilited versions should be in the same position in a lower numbered channel, or they could just be part of the background graphic (if you have one) which saves channels.

One caveat: upon leaving the frame to another the channels listed in the rollTest call will remain invisible. It's a good idea to have a handler that resets them all to visible and call that upon leaving. Alternatively you could reserve a number of channels for buttons throughout your application. They can then be made invisible from your startMovie handler so they don't flash into view when you move into a frame with a rolltest script.

The hilited versions can contain the call to the buttonDown script (they're the only objects that will be clicked, since they will appear as soon as the mouse is over them). Here's that script again (in a slightly modified version) for good measure:

  on trackButton altCast
    put the clickOn into spriteNumber
    put the castNum of sprite spriteNumber into baseCast
    repeat while the mouseDown
      if rollover(spriteNumber) then
        set the castNum of sprite spriteNumber to altCast
      else set the castNum of sprite spriteNumber to baseCast
      updateStage
    end repeat
    return rollover(spriteNumber)
  end
from the score script of the hilited button, call this script like this:
  on mousedown
    if trackButton(the number of cast "pushedButton") then
      doMyThing
      -- could be any handler or command you want the button to execute
    end if
  end
"pushedButton" or whatever you want to call it is just the cast name of your pressed button image.

These two script happily coexist, and together provide the full button behaviour of hiliting when pointed at, and cast switching when actually clicked.

As an aside I'd like to comment on the fact that these scripts for all their shortness do much the same as many other example scripts I've seen, which are sometimes many times the length and much more complicated than these scripts. Note that I do not use puppets or parent scripts here, simply because that is not necessary in this situation. I don't need complicated housekeeping and resetting of castNums or anything. I always strive for the _keep_it_simple_ approach and I think it pays off in maintainability and straightforwardness of your final application.


Animating Button with QuickTime: Gordon G. Miller, III

One idea that we often use to animate buttons is to use small 60x80 pixel quicktime movies in the design of the buttons. QuickTime can usually play more than one movie, if they are small enough, or save the animation effect for when an item is selected. Minimal scripting needed and it doesn't waste cast space.
Gordon G. Miller, III
Director
The MultiMedia Lab
Virginia Tech
Gordon.Miller@vt.edu