Double Tap Detection
Jump to navigation
Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized 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
}
}