Double Tap Detection
From Second Life Wiki
| LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Tutorials |
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 } } }
Double-tap detection - this example warps user at maximum velocity.
[Functional code, paste to script, add to object, wear object, double tap forward key to test.]
// // BETLOG Hax // AEST: 20080801 2227 [SLT: 20080801 0527] //========================================================================= // ---LICENCE START--- // http://creativecommons.org/licenses/by-sa/3.0/ // ie: Attribution licence: // Give me credit by leaving it in the script I created. // Supply my original script with your modified version. // Refer to the wiki URL from which you copied this script. // https://wiki.secondlife.com/wiki/Double_Tap_Detection // ---LICENCE END--- //========================================================================= //---------------------------------- // SHARED CONFIGURATION //---------------------------------- // CONFIGURATION float gDoubleTap = 0.1; //---------------------------------- // CORE CODE integer gWarpActive = FALSE; //---------------------------------- default { state_entry() { if (llGetAttached()) llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS); } attach(key id) { if (llGetAttached()) llRequestPermissions(llGetOwner(),PERMISSION_TAKE_CONTROLS); } run_time_permissions(integer perms) { if(~perms & PERMISSION_TAKE_CONTROLS) llReleaseControls(); else { llTakeControls(0 | CONTROL_FWD | CONTROL_BACK | CONTROL_LEFT | CONTROL_RIGHT // | CONTROL_ROT_LEFT // | CONTROL_ROT_RIGHT | CONTROL_UP | CONTROL_DOWN // | CONTROL_LBUTTON // | CONTROL_ML_LBUTTON ,TRUE, TRUE); llOwnerSay("Ready - Doubletap frequency: "+(string)gDoubleTap); } } control(key id, integer pressed, integer change) { integer start = pressed & change; integer end = ~pressed & change; integer held = pressed & ~change; integer unheld = ~(pressed | change); //---------------------------------- if (start & (CONTROL_FWD|CONTROL_BACK |CONTROL_UP|CONTROL_DOWN |CONTROL_LEFT//|CONTROL_ROT_LEFT |CONTROL_RIGHT//|CONTROL_ROT_RIGHT )) { if (llGetTime() <= gDoubleTap) { if (-change == gWarpActive) //try to ensure only the key being *intentionally* double tapped is used. gWarpActive = 1; } } //---------------------------------- if (end & (CONTROL_FWD|CONTROL_BACK |CONTROL_UP|CONTROL_DOWN |CONTROL_LEFT//|CONTROL_ROT_LEFT |CONTROL_RIGHT//|CONTROL_ROT_RIGHT )) { gWarpActive = -change; //try to ensure only the key being *intentionally* double tapped is used. llResetTime(); } //---------------------------------- if (held & CONTROL_FWD) { if (gWarpActive > 0) { llPushObject( llGetOwner() ,llRot2Fwd(llGetRot())*0x7FFFFFFF//forward ,ZERO_VECTOR ,FALSE ); } } //---------------------------------- // ADD THE REST OF THE KEYS/DIRECTIONS HERE // ,-llRot2Fwd(llGetRot())*0x7FFFFFFF //back // ,llRot2Left(llGetRot())*0x7FFFFFFF //left // ,-llRot2Left(llGetRot())*0x7FFFFFFF //right // ,llRot2up(llGetRot())*0x7FFFFFFF //up // ,-llRot2Up(llGetRot())*0x7FFFFFFF //down } }

