1 (edited by wrybread 2009-07-28 21:29:25)

Topic: How to repeat an action while a button is pressed?

I'm trying to make it so when a user presses a button in my widget, the action keeps repeating until the button is released.

For example, the below code will trace the word "pressed!" when the button is pressed, but will not repeat the message while the button is pressed. I'd like to repeat the word while the button is pressed, and stop repeating when the user releases the button. Any tips on making this happen?


on (press) {
trace("pressed!");
}

Re: How to repeat an action while a button is pressed?

For this type of behavior, you typically set up an interval (using setInterval) in the onPress handler, and kill it in the onRelease and onReleaseOutside handlers (using clearInterval).

3 (edited by wrybread 2009-08-01 15:37:18)

Re: How to repeat an action while a button is pressed?

Thanks, works really well. For anyone else coming down this road, here's two methods of having an action repeat itself while the button is being held. The first method is simple and starts repeating right away, the second method repeats the action only if the button is held for a longer period.

In this sample the function previous_video(), which is on the main timeline, is being triggered. Note that I'm specifying _level0, which isn't the best idea since it makes it so your widget won't work in virtual Chumbies.

on (press) {
     _level0.buttonInterval = setInterval(_level0.previous_video, 500);  // repeat every 500ms
}

on (release) {
    clearInterval(_level0.buttonInterval);
}

on (releaseOutside) {
    clearInterval(_level0.buttonInterval);
}

The above works well, but I found it hard to get precise control. So this other method allows an action to be triggered when first pressed, and then repeated only if the button is held for awhile.

This block of code is located in the button:

on (press) {
     _level0.previous_video();  // execute the function immediately
     _level0.buttonTimeout = setTimeout(_level0.previous_video_changer, 750);  // start repeating if button is held more than 750ms
}

on (release) {
    clearInterval(_level0.buttonInterval);
    clearInterval(_level0.buttonTimeout);
}

on (releaseOutside) {
    clearInterval(_level0.buttonInterval);
    clearInterval(_level0.buttonTimeout);
}

This block of code is located on the main timeline:

function next_video_changer() {
    _level0.buttonInterval = setInterval( _level0.next_video, 50 );  // repeat the action every 50ms
}

In the above recipe, the previous_video() function is triggered immediately when the button is pressed, but if the button is held for longer than 500ms, it triggers the next_video_changer() function, which launches an interval to trigger the next_video() function every 50ms.

You can see the latter method in action in my ChumbySpy widget:

http://www.chumby.com/guide/widget/ChumbySpy

Click the ? icon at top right to access the settings, then turn off "Randomize" and turn on "Show URL & Channel", then click the left and right edges of the screen to advance to previous and next camera. Note how if you hold your finger on the screen the cameras advance quickly.

Re: How to repeat an action while a button is pressed?

i don't know the right variables to use, but you could probably say

on (press) {
  while (this.ispressed) {
    trace('Pressed!');
  }
}

Re: How to repeat an action while a button is pressed?

There is no property of a button that indicates that it's currently pressed, nor would you want to use a while loop in this manner in a handler. Indeed, while loops waiting on some sort of event are very dangerous in Actionscript, since they effectively lock the movie and cause "Actionscript stuck" errors.

Developers should always architect their movies around being asynchronous.

wrybread's strategy is the correct one.