Double Tap Detection

From Second Life Wiki
Revision as of 16:28, 30 March 2008 by Uzume Grigorovich (talk | contribs) (lsl code tagging)
Jump to navigation Jump to search

Double Tap Detection without Timers

This is an example to show one method of detecting a double tap of a movement key without using a timer. --Eyana Yohkoh 19:09, 27 August 2007 (PDT)

<lsl> // Dash/dodge template script by Eyana Yohkoh // // ///////

// This script is an example of a way to detect a double tap on movement // keys to trigger a function. // There are multiple ways to detect a double tap, and this method quite // possibly is not the best, but this certainly works.


// debugging stuff: // integer debug = FALSE; // set this to TRUE if you want to hear debugging messages

debugging(string debugMsg) // if debug is TRUE, then this is what will send messages { // I put this in a function for ease of adding more debug messages

   if ( debug )            
   {
       llOwnerSay(debugMsg);
   }

}


// getting the time for the comparison ///////// float strTime; // used to store the current time float time;

getSeconds() {

   string timestamp    = llGetTimestamp();                 
                                       // first part of getting the current time with milliseconds
                                       // this gives a strange time format so it was easier for me
                                       // to just grab the very end of the time to get the
                                       // fractional seconds.
   string subTime      = llGetSubString(timestamp, 19, 25);                                        
   float wallclock     = llGetWallclock();
                           // this gets the current time in seconds
                           // can't use this for a check without the above stuff because
                           // it does not do decimal places
                           
   strTime = (float)subTime + wallclock;
                           // appending milliseconds to the end of the rounded off seconds
                           // you could just do without this and test with seconds and milliseconds
                           // but that would cause problems with the comparison check for when
                           // double tapping at the cusp of a completed minute
                           
   debugging((string)strTime);             // debug message for testing purposes

}

// comparing the stored time with the current tap time ///////////

float storedTime; // number will be stored at the end of a tap for comparison float recentTime; // stored immediately on tapping for comparing with the stored

compareTimes(float stored, float recent) // find the difference between the times { // example use: compareTimes(storedTime, recentTime)

   time = recent - stored;
   debugging((string)recent + " - " + (string)stored + " = " +  (string)time);

}


resetStored() {

   storedTime = 0;

}

float interval = 0.5; // time between double taps

                       // default interval is 0.5 seems to be a good number
                       // 0.2 is too fast for some people, 1.0 is far too slow


doubleTap() {

   if ( time < interval )
   {
       llSay(0, "Double tap detected");
   }

}

key avatar; requestPerms() // permissions we want to take: {

   integer permissions = PERMISSION_TAKE_CONTROLS;
   llRequestPermissions(avatar, permissions);          // avatar is snagged when object is attached

}

takeControls() // what controls to take. pared down for the example. {

   integer controls    =   CONTROL_FWD;
                           
   llTakeControls(controls, TRUE, TRUE);

}

default {

   on_rez(integer reznum)
   {
       llReleaseControls();            // release controls just in case
       resetStored();                  // reset all stored numbers
       debugging("Debug messages are turned on.");
   }
   run_time_permissions(integer perms)
   {
       if ( perms > 0 )            // if permissions are granted then take controls
       {
           takeControls();
       }
   }
   
   attach(key id)
   {
       if ( id != NULL_KEY )       // if id is NULL then it's not attached to a person!
       {
           avatar = id;            // store the key for later use without need to reset
           requestPerms();         // get permissions
       }
       else                        // since it's no longer attached, then no need for control
       {
           llReleaseControls();
       }
   }
   control(key id, integer held, integer change) 
   {
       integer pressed = held & change;
                   
       if ( pressed & CONTROL_FWD )
       {
           getSeconds();
           recentTime = strTime;                   // store the recent time 
                                                   // that was just found with getSeconds()
           compareTimes(storedTime, recentTime);   // comparing times
           doubleTap();                            // this will trigger for double taps!
           storedTime = recentTime;                // store the recent time for later in case
                                                   // this time was not a successful double tap
                                                   // but was possibly the first key press for the
                                                   // double tap
       }
   }

} </lsl>