Double Tap Detection

From Second Life Wiki
Revision as of 18:09, 27 August 2007 by Eyana Yohkoh (talk | contribs) (New page: {{LSL Header}} ====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. --~~~~ <pre> // Dash/d...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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)

// 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
        }
    }
}