A Flash Developer Resource Site

Results 1 to 9 of 9

Thread: [RESOLVED] Karaoke Text: timer reset issue

  1. #1
    Junior Member
    Join Date
    Oct 2012
    Posts
    6

    resolved [RESOLVED] Karaoke Text: timer reset issue

    Hi guys,
    This is my first flash project, in fact I have very little programming experience at all, so please excuse me if this is a stupid question. I’m working on making a karaoke type text highlighting effect for children’s books. I’m using nested timers with viable delays and am having intermittent issues. If I click the listen button several times in a row sometimes the offHighlight function will get off count. I have identified 2 places that my code is not working right to allow this to happen.
    1. It would be ideal to be able to pass the wordCounter to the offHighlight function but it seems that Flash won’t allow this when using the timer class. So instead I created a counter within the offHighlight function to keep track.
    // start myHighlightOffTimer with variable delay
    myOffDelay = myTimingArray[event.target.currentCount-1] + 400;
    myHighlightOffTimer = new Timer (myOffDelay, 1);
    myHighlightOffTimer.addEventListener(TimerEvent.TI MER, offHighlight);
    myHighlightOffTimer.start();
    function offHighlight(event:TimerEvent){ //////////////////////////////////////////////////////////////////////////////////////////
    // set highlightOffFormat
    var highlightOffFormat:TextFormat = new TextFormat();
    highlightOffFormat.color = 0xF000000;
    // remove text highlight
    if (myOffWordCount < myWordCount){
    trace ("myOffWordCount " + myOffWordCount);
    myTextField.setTextFormat(highlightOffFormat, myIndexArray[myOffWordCount], myIndexArray[myOffWordCount+1]);
    myOffWordCount++;

    } else { // catch array out of bounds
    trace ("function offHighlight: myIndexArray out of bounds: " + myOffWordCount);
    }
    }
    2. It seems that when I stop and reset the offHighlight function the function will still continue to run and increment the counter.
    if (myHighlightOffTimer != null){
    myHighlightOffTimer.stop();
    myHighlightOffTimer.reset();
    };
    * * *Any help is greatly appreciated.

    Here is all of my AS3 code
    package {

    import flash.display.MovieClip;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.events.MouseEvent;

    public class Text extends MovieClip {
    // Declare variables ////////////////////////////////////////////////////////////////
    var myString:String = "Humpty Dumpty sat on a wall.";
    var myStringCopy:String = myString;
    var myWordArray:Array = myStringCopy.split(" ");
    var mySyllableCountArray:Array = [2, 2, 1, 1, 1, 3]; // need a syllable counting function returns mySyllableCountArray, adds one syllable for comma and 2 for period
    var myTimingArray:Array = new Array;
    var myStringLength:int = myString.length;
    var myWordCount:int = mySyllableCountArray.length;
    var myIndexArray:Array = new Array;
    var myTextField:TextField = new TextField();
    var myHighlightOnTimer:Timer;
    var myHighlightOffTimer:Timer;
    var myOnDelay:int = new int;
    var myOffWordCount:int = 0;
    var myOffDelay:int = new int;

    public function Text() {
    // constructor code
    // text formating /////////////////////////////////////////////////////
    var myTextFormat:TextFormat = new TextFormat();
    myTextFormat.font = "Arial";
    myTextFormat.size = 22;
    myTextFormat.align = "left";

    // create text field ///////////////////////////////// /////
    myTextField = new TextField();
    myTextField.width = 1000;
    myTextField.y = 50;
    myTextField.x = 10;
    myTextField.selectable = false;
    myTextField.defaultTextFormat = myTextFormat;
    myTextField.textColor = 0x000000;
    myTextField.text = myStringCopy;
    addChild(myTextField);

    // create listen button
    var myMovieClip:btnListen = new btnListen();
    myMovieClip.x = 100;
    myMovieClip.y = 150;
    addChild(myMovieClip);

    myMovieClip.addEventListener(MouseEvent.CLICK, clickListen);
    myMovieClip.buttonMode = true;

    // Find index locations between words
    findWordIndex();

    //Calculate timing
    calculateTimingArray();


    } // end constructor function Text////////////////////////////////////////////////////////////////////////////////////////////


    // finds spaces between words and records string index locations
    function findWordIndex(){
    var myIndex:int = 0; // captures locatin of spaces between words, Begins at 0 to mark beginning of first word
    var i:Number = 0; // Counter
    do { //
    myIndexArray[i] = myIndex; // records index locations to array
    myIndex = myStringCopy.indexOf(" ", myIndex+1); // moves to next character in string to start search for next space, returns -1 if no space found then will exit loop
    i++; // moves to next character
    if (myStringCopy.charAt(myIndex) == " "){ // if next character also a space
    myIndex++; // then moves to next character in string
    }
    } while ( myIndex != -1); // exit do while loop when myIndex -1
    myIndexArray[i] = myStringLength; // Records end of last word in string
    }

    function calculateTimingArray (){ /////////////////////////////////////////////////////////////////////////////////////////////////
    // calculate myTimingArray based on syllable count
    for ( var i:int = 0; i < mySyllableCountArray.length; i++){
    myTimingArray[i] = 90 + (mySyllableCountArray[i] * 150)
    };
    }

    function clickListen(event:MouseEvent) { ///////////////////////////////////////////////////////////////////////////////////////////
    // reset timers if they have been started
    if (myHighlightOnTimer != null){
    myHighlightOnTimer.stop();
    myHighlightOnTimer.reset();

    };
    if (myHighlightOffTimer != null){
    myHighlightOffTimer.stop();
    myHighlightOffTimer.reset();
    trace("myHighlightOffTimer.reset");
    };

    // reset counters
    myOffWordCount = 0;
    myOnDelay = 1000;

    // set text field color to black
    myTextField.textColor = 0xF000000;
    // start myHighlightOnTimer
    myHighlightOnTimer = new Timer (myOnDelay, myWordCount);
    myHighlightOnTimer.addEventListener(TimerEvent.TIM ER, onHighlight);
    myHighlightOnTimer.start();

    }

    function onHighlight(event:TimerEvent){ ///////////////////////////////////////////////////////////////////////////////////////////
    if (event.currentTarget.currentCount == 1){
    trace("onHighlight first tick");
    }

    // Set Text highlight format
    var highlightFormat:TextFormat = new TextFormat();
    highlightFormat.color = 0xFF0000;
    // Highlight text
    var myHighlightCount = event.currentTarget.currentCount;
    if (myHighlightCount <= myWordCount){
    myTextField.setTextFormat(highlightFormat, myIndexArray[myHighlightCount-1], myIndexArray[myHighlightCount]);
    } else {
    trace ("function onHighlight: myIndexArray out of bounds: " + myHighlightCount);
    }


    // start myHighlightOffTimer with variable delay
    myOffDelay = myTimingArray[event.target.currentCount-1] + 400;
    myHighlightOffTimer = new Timer (myOffDelay, 1);
    myHighlightOffTimer.addEventListener(TimerEvent.TI MER, offHighlight);
    myHighlightOffTimer.start();



    // change myHighlightOnTimer delay if not at the last tick
    if (event.target.currentCount < myWordCount){
    myOnDelay = myTimingArray[event.target.currentCount - 1]; // offset by 1, timing array tells when to highlight next word by giving enought time to read previous word
    myHighlightOnTimer.delay = (myOnDelay);
    } else if (event.target.currentCount == myWordCount){
    // last time through don't need to change delay for next tick
    } else { // catch array out of bounds
    trace ("function onHighlight: myTimingArray out of bounds" );
    }
    }

    function offHighlight(event:TimerEvent){ //////////////////////////////////////////////////////////////////////////////////////////
    // set highlightOffFormat
    var highlightOffFormat:TextFormat = new TextFormat();
    highlightOffFormat.color = 0xF000000;
    // remove text highlight
    if (myOffWordCount < myWordCount){
    trace ("myOffWordCount " + myOffWordCount);
    myTextField.setTextFormat(highlightOffFormat, myIndexArray[myOffWordCount], myIndexArray[myOffWordCount+1]);
    myOffWordCount++;

    } else { // catch array out of bounds
    trace ("function offHighlight: myIndexArray out of bounds: " + myOffWordCount);
    }



    }
    } // end class Text



    } // end package

  2. #2
    Senior Member cancerinform's Avatar
    Join Date
    Mar 2002
    Location
    press the picture...
    Posts
    13,449
    What you can do is to deactivate the button when a timer starts. And later you activate the button again.

    function offHighlight(event:TimerEvent){
    myBut.enabled = false;
    - The right of the People to create Flash movies shall not be infringed. -

  3. #3
    Junior Member
    Join Date
    Oct 2012
    Posts
    6
    Thank you for the suggestion, that should work. I would also be curious if anyone has any other ideas to work around this issue.

  4. #4
    Junior Member
    Join Date
    Oct 2012
    Posts
    6
    I think I just figured out WHY the timer reset isn't working properly. Maybe because I have multiple instances of the myHighlightOffTimer running at the same time, then when I call the reset & stop it is only deactivating one instance leaving the others still running. If anyone knows of any tutorials or other info that might help me solve this problem I would appreciate your help. If I come up with a solution I will post it.
    Thanks.

  5. #5
    :
    Join Date
    Dec 2002
    Posts
    3,518
    Maybe try something like this...
    PHP Code:
    package {
        
    import flash.display.*;
        
    import flash.events.*;
        
    import flash.text.*;
        
    import flash.utils.*;

    /*
    var t:Txt = new Txt("Humpty Dumpty sat on a wall. Humpty Dumpty had a great fall. All the kings");
    addChild(t);
    */
        
    public class Txt extends Sprite {
            private static const 
    BASE_AMOUNT:int 100;
            private static const 
    MULT_AMOUNT:int 300;
            private var 
    _string:String;
            private var 
    _syllableCountArray:Array;
            private var 
    _wordCount:uint;
            private var 
    _idex:uint;
            private var 
    _textField:TextField;
            private var 
    _highlightOffFormat:TextFormat;
            private var 
    _highlightFormat:TextFormat;
            private var 
    _defaultFormat:TextFormat;
            private var 
    _indexArray:Array = new Array();
            private var 
    _timingArray:Array = new Array();
            private var 
    _timer:Timer;

            public function 
    Txt($string:String) {
                
    _string $string;
                
    _syllableCountArray = new Array();
                
    _defaultFormat = new TextFormat();
                
    _defaultFormat.font "Arial";
                
    _defaultFormat.size 22;
                
    _defaultFormat.align "left";
                
    _defaultFormat.color 0x000000;
                
    _textField = new TextField();
                
    _textField.width 1000;
                
    _textField.50;
                
    _textField.10;
                
    _textField.selectable false;
                
    _textField.defaultTextFormat _defaultFormat;
                
    _textField.text _string;
                
    addChild(_textField);
                var 
    myMovieClip:btnListen = new btnListen();
                
    myMovieClip.100;
                
    myMovieClip.150;
                
    addChild(myMovieClip);
                
    myMovieClip.addEventListener(MouseEvent.CLICKclickListenfalse,true);
                
    myMovieClip.buttonMode true;
                
    _highlightFormat = new TextFormat();
                
    _highlightFormat.color 0xFF0000;
                
    _highlightOffFormat = new TextFormat();
                
    _highlightOffFormat.color 0x000000;
                
    findWordIndex();
                
    calculateTimingArray();
            }
            function 
    findWordIndex() {
                var 
    myIndex:int 0;
                var 
    i:uint 0;
                var 
    w:Array = _string.split(" ");
                do {
                    
    _syllableCountArray[i] = countSyllables(w[i]);
                    
    _indexArray[i] = myIndex;
                    
    myIndex _string.indexOf(" ",myIndex 1);
                    
    i++;
                    if (
    _string.charAt(myIndex) == " ") {
                        
    myIndex++;
                    }
                } while ( 
    myIndex != -1);
                
    _indexArray[i] = _string.length;
                
    _wordCount _syllableCountArray.length;
            }
            function 
    calculateTimingArray() {
                var 
    len:int _syllableCountArray.length;
                var 
    i:uint 0;
                for (
    0leni++) {
                    
    _timingArray[i] = BASE_AMOUNT + (_syllableCountArray[i] * MULT_AMOUNT);
                }
                
    trace(_syllableCountArray);
                
    trace(_timingArray);
            }
            private function 
    clickListen($e:Event):void {
                
    _idex 0;
                
    _textField.setTextFormat(_defaultFormat);
                if (
    _timer) {
                    
    _timer.removeEventListener(TimerEvent.TIMERonHighlight);
                    
    _timer.removeEventListener(TimerEvent.TIMERoffHighlight);
                    
    _timer null;
                }
                
    _timer = new Timer(50,1);
                
    _timer.addEventListener(TimerEvent.TIMERonHighlight);
                
    _timer.start();
            }
            private function 
    onHighlight($e:TimerEvent):void {
                
    _textField.setTextFormat(_highlightFormat_indexArray[_idex], _indexArray[_idex+1]);
                
    _timer = new Timer(_timingArray[_idex],1);
                
    _timer.addEventListener(TimerEvent.TIMERoffHighlight);
                
    _timer.start();
            }
            private function 
    offHighlight($e:TimerEvent):void {
                
    _textField.setTextFormat(_highlightOffFormat_indexArray[_idex], _indexArray[_idex+1]);
                if (++
    _idex _wordCount) {
                    
    _timer = new Timer(_timingArray[_idex 1] * 0.5,1);
                    
    _timer.addEventListener(TimerEvent.TIMERonHighlight);
                    
    _timer.start();
                }
            }
            
    // found function, modified it, may or may not work for you
            
    private function countSyllables($word:String):int {
                var 
    vowels:* = ['a','e','i','o','u','y'];
                var 
    currentWord:String $word;
                var 
    numVowels:int 0;
                var 
    lastWasVowel:Boolean false;
                for (var 
    c:uint=0currentWord.lengthc++) {
                    var 
    wc currentWord.charAt(c);
                    var 
    foundVowel:Boolean false;
                    for (var 
    v:* in vowels) {
                        
    //don't count diphthongs
                        
    if (vowels[v] == wc && lastWasVowel) {
                            
    foundVowel true;
                            
    lastWasVowel true;
                            break;
                        } else if (
    vowels[v] == wc && !lastWasVowel) {
                            
    numVowels++;
                            
    foundVowel true;
                            
    lastWasVowel true;
                            break;
                        }
                    }
                    
    //if full cycle and no vowel found, set lastWasVowel to false;
                    
    if (! foundVowel) {
                        
    lastWasVowel false;
                    }
                }
                
    //remove es, it's _usually? silent
                
    if (currentWord.length && 
                            
    currentWord.substring(currentWord.length 2) == "es") {
                    
    numVowels--;
                    
    // remove silent e
                
    } else if (currentWord.length &&
                            
    currentWord.substring(currentWord.length 1) == "e") {
                    
    numVowels--;
                }
                if (
    currentWord.charAt(currentWord.length 1) == ".") {
                    
    numVowels +=  2;
                }
                return (
    numVowels == ) ? numVowels;
            }
        }

    Hope this helps!

  6. #6
    Junior Member
    Join Date
    Oct 2012
    Posts
    6
    Dawsonk, thank you so much for all your suggestions, I'm really getting a lot out of the overhaul you made to my code. I can still spend the next week going through all your suggestions.

    I do, however, need the timing to be staggered so the previous word remains with the highlight on a little after the next word starts a new highlight. This will make it so the narrator can read along at a more natural pace. I may have found the solution by using a timer register something like this…
    function registerTimer(timer:Timer):void { ///////////////////////////////////////////////////////////////////////////////////////////////
    timerList.push(timer);
    }

    function stopAll():void { ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    for(var i:uint = 0; i < timerList.length; i++){
    timerList[i].stop();
    trace(i);
    }
    }
    ... where I call the registerTimer function every time a new timer is started, then call the stopAll function when the button is pushed.

  7. #7
    Junior Member
    Join Date
    Oct 2012
    Posts
    6
    Dawsonk, thank you so much for all your suggestions, I'm really getting a lot out of the overhaul you made to my code. I can still spend the next week going through all your suggestions.

    I do, however, need the timing to be staggered so the previous word remains with the highlight on a little after the next word starts a new highlight. This will make it so the narrator can read along at a more natural pace. I may have found the solution by using a timer register something like this…
    function registerTimer(timer:Timer):void {
    timerList.push(timer);
    }

    function stopAll():void {
    for(var i:uint = 0; i < timerList.length; i++){
    timerList[i].stop();
    }
    }
    ... where I call the registerTimer function every time a new timer is started, then call the stopAll function when the button is pushed.

  8. #8
    :
    Join Date
    Dec 2002
    Posts
    3,518
    Okay, sorry I misunderstood earlier. Here's a try using a single timer...
    PHP Code:
    package {
            
    import flash.display.*;
            
    import flash.events.*;
            
    import flash.text.*;
            
    import flash.utils.*;

    /*
    var t:Txt = new Txt("Humpty Dumpty sat on a wall. Humpty Dumpty had a great fall. All the kings");
    addChild(t);
    */
            
    public class Txt extends Sprite {
                    private static const 
    BASE_AMOUNT:int 100;
                    private static const 
    MULT_AMOUNT:int 300;
                    private static const 
    MAX_ON_AMT:int 1100;
                    private var 
    _string:String;
                    private var 
    _syllableCountArray:Array;
                    private var 
    _wordCount:uint;
                    private var 
    _textField:TextField;
                    private var 
    _highlightOffFormat:TextFormat;
                    private var 
    _highlightFormat:TextFormat;
                    private var 
    _defaultFormat:TextFormat;
                    private var 
    _indexArray:Array = new Array();
                    private var 
    _timingArray:Array = new Array();
                    private var 
    _timer:Timer;

                    public function 
    Txt($string:String) {
                            
    _string $string;
                            
    _syllableCountArray = new Array();
                            
    _defaultFormat = new TextFormat();
                            
    _defaultFormat.font "Arial";
                            
    _defaultFormat.size 22;
                            
    _defaultFormat.align "left";
                            
    _defaultFormat.color 0x000000;
                            
    _textField = new TextField();
                            
    _textField.width 1000;
                            
    _textField.50;
                            
    _textField.10;
                            
    _textField.selectable false;
                            
    _textField.defaultTextFormat _defaultFormat;
                            
    _textField.text _string;
                            
    addChild(_textField);
                            var 
    myMovieClip:btnListen = new btnListen();
                            
    myMovieClip.100;
                            
    myMovieClip.150;
                            
    addChild(myMovieClip);
                            
    myMovieClip.addEventListener(MouseEvent.CLICKclickListenfalse,true);
                            
    myMovieClip.buttonMode true;
                            
    _highlightFormat = new TextFormat();
                            
    _highlightFormat.color 0xFF0000;
                            
    _highlightOffFormat = new TextFormat();
                            
    _highlightOffFormat.color 0x000000;
                            
    findWordIndex();
                            
    calculateTimingArray();
                    }
                    private function 
    findWordIndex() {
                            var 
    myIndex:int 0;
                            var 
    i:uint 0;
                            var 
    w:Array = _string.split(" ");
                            do {
                                    
    _syllableCountArray[i] = countSyllables(w[i]);
                                    
    _indexArray[i] = myIndex;
                                    
    myIndex _string.indexOf(" ",myIndex 1);
                                    
    i++;
                                    if (
    _string.charAt(myIndex) == " ") {
                                            
    myIndex++;
                                    }
                            } while ( 
    myIndex != -1);
                            
    _indexArray[i] = _string.length;
                            
    _wordCount _syllableCountArray.length;
                    }
                    private function 
    calculateTimingArray() {
                            var 
    len:int _syllableCountArray.length;
                            var 
    i:uint 0;
                            var 
    t:int 0;
                            for (
    0leni++) {
                                    
    _timingArray[i] = new Array(2);
                                    
    // highlight on time
                                    
    _timingArray[i][0] = t;
                                    
    // highlight off time
                                    
    _timingArray[i][1] = MAX_ON_AMT;
                                    
    += BASE_AMOUNT + (_syllableCountArray[i] * MULT_AMOUNT);
                            }
                            
    trace(_syllableCountArray);
                            
    trace(_timingArray);
                    }
                    private function 
    clickListen($e:Event):void {
                            
    _textField.setTextFormat(_defaultFormat);
                            if (
    _timer) {
                                    
    _timer.removeEventListener(TimerEvent.TIMERdoTimer);
                                    
    _timer null;
                            }
                            
    _timer = new Timer(100,0);
                            
    _timer.addEventListener(TimerEvent.TIMERdoTimer);
                            
    _timer.start();
                    }
                    private function 
    doTimer($e:TimerEvent):void {
                            var 
    idex $e.currentTarget.currentCount 1;
                            var 
    len:int _syllableCountArray.length;
                            var 
    i:uint 0;
                            for (
    0leni++) {
                                    if (
    idex 100 == _timingArray[i][0]) {
                                            
    _textField.setTextFormat(_highlightFormat_indexArray[i], _indexArray[i+1]);
                                    }
                                    if (
    idex 100 == _timingArray[i][1]) {
                                            
    _textField.setTextFormat(_highlightOffFormat_indexArray[i], _indexArray[i+1]);
                                    }
                            }
                            if (
    idex 100 == _timingArray[len 1][1]) {
                                    
    _timer.stop();
                            }
                    }
                    
    // found function, modified it, may or may not work for you
                    
    private function countSyllables($word:String):int {
                            var 
    vowels:* = ['a','e','i','o','u','y'];
                            var 
    currentWord:String $word;
                            var 
    numVowels:int 0;
                            var 
    lastWasVowel:Boolean false;
                            for (var 
    c:uint=0currentWord.lengthc++) {
                                    var 
    wc currentWord.charAt(c);
                                    var 
    foundVowel:Boolean false;
                                    for (var 
    v:* in vowels) {
                                            
    //don't count diphthongs
                                            
    if (vowels[v] == wc && lastWasVowel) {
                                                    
    foundVowel true;
                                                    
    lastWasVowel true;
                                                    break;
                                            } else if (
    vowels[v] == wc && !lastWasVowel) {
                                                    
    numVowels++;
                                                    
    foundVowel true;
                                                    
    lastWasVowel true;
                                                    break;
                                            }
                                    }
                                    
    //if full cycle and no vowel found, set lastWasVowel to false;
                                    
    if (! foundVowel) {
                                            
    lastWasVowel false;
                                    }
                            }
                            
    //remove es, it's _usually? silent
                            
    if (currentWord.length &&
                                                    
    currentWord.substring(currentWord.length 2) == "es") {
                                    
    numVowels--;
                                    
    // remove silent e
                            
    } else if (currentWord.length &&
                                                    
    currentWord.substring(currentWord.length 1) == "e") {
                                    
    numVowels--;
                            }
                            if (
    currentWord.charAt(currentWord.length 1) == ".") {
                                    
    numVowels +=  2;
                            }
                            return (
    numVowels == ) ? numVowels;
                    }
            }


  9. #9
    Junior Member
    Join Date
    Oct 2012
    Posts
    6
    Thank you again dawsonk. This looks like it will do what I need, however I haven't had the chance to read through your code. I have marked the thread as resolved, but I hope I can still ask questions if I run into any.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center