セカンドライフでタッチすると音がでるスクリプト。
特に連打防止機能をつけたものです。
具体的には1人に対して、 X 秒間次のクリックを防止します。
大勢からクリックされても、その1人1人に X 秒間のクリック防止機能が働きます。
当初は、連打すればするほどその人にペナルティー機能とかつけたりしましたが、
結局シンプルなコードへ落ち着きました。
技術的なアピールポイント
・メモリ断片化とかが発生しないように配列を使用していない
・少し冗長でもシンプルで分かりやすい
・連打防止のために時間を扱うが、ポーリングによる監視、タイマー割り込みを一切使用せずサーバーにやさしい
SimpleRendaBoushi5.lsl
// シンプルな連打防止機能付き再生機。5人まで管理。 // 自由に改造・配布OKです。 // code by natade // 最後に押してから、そのユーザーの情報を消すまでの時間 // 長いほど、ユーザーが押せなくなる時間が長くなる float G_fResetTimeSec = 60.0; // TRUE で最初に触った時のユーザーを表示させる // FALSE で表示させない integer G_bIsDrawName = TRUE; // 何の音を鳴らすか key G_kSoundData = "音声のUIDをここに"; // --------------------------------------------------------------- checkMemory() { if(llGetFreeMemory() < 128) { llOwnerSay("Sorry. I will complete reset for memory release."); llResetScript(); }} // メモリの再確保が必要であるため、配列は使わない key G_kTouchUser1 = NULL_KEY; key G_kTouchUser2 = NULL_KEY; key G_kTouchUser3 = NULL_KEY; key G_kTouchUser4 = NULL_KEY; key G_kTouchUser5 = NULL_KEY; integer G_bIsSetUser1 = FALSE; integer G_bIsSetUser2 = FALSE; integer G_bIsSetUser3 = FALSE; integer G_bIsSetUser4 = FALSE; integer G_bIsSetUser5 = FALSE; float G_fUserTimerSec1 = 0.0; float G_fUserTimerSec2 = 0.0; float G_fUserTimerSec3 = 0.0; float G_fUserTimerSec4 = 0.0; float G_fUserTimerSec5 = 0.0; integer G_bIsSetTimer = FALSE; // 新規のユーザーIDを取得する integer getNewUserId() { integer iNewUser = 1; float fMaxTime = G_fUserTimerSec1; // NULL_KEY を使用する if(G_kTouchUser1 == NULL_KEY) { return 1; } else if(G_kTouchUser2 == NULL_KEY) { return 2; } else if(G_kTouchUser3 == NULL_KEY) { return 3; } else if(G_kTouchUser4 == NULL_KEY) { return 4; } else if(G_kTouchUser5 == NULL_KEY) { return 5; } // 時間が最も長いのを再利用する if(fMaxTime < G_fUserTimerSec2) { iNewUser = 2; fMaxTime = G_fUserTimerSec2; } else if(fMaxTime < G_fUserTimerSec3) { iNewUser = 3; fMaxTime = G_fUserTimerSec3; } else if(fMaxTime < G_fUserTimerSec4) { iNewUser = 4; fMaxTime = G_fUserTimerSec4; } else if(fMaxTime < G_fUserTimerSec5) { iNewUser = 5; fMaxTime = G_fUserTimerSec5; } return iNewUser; } // 新規ユーザー登録 addNewUser(key kTouchUser) { integer iNewUser = getNewUserId(); // User 1 if(iNewUser == 1) { G_kTouchUser1 = kTouchUser; G_fUserTimerSec1 = 0.0; } // User 2 else if(iNewUser == 2) { G_kTouchUser2 = kTouchUser; G_fUserTimerSec2 = 0.0; } // User 3 else if(iNewUser == 3) { G_kTouchUser3 = kTouchUser; G_fUserTimerSec3 = 0.0; } // User 4 else if(iNewUser == 4) { G_kTouchUser4 = kTouchUser; G_fUserTimerSec4 = 0.0; } // User 5 else if(iNewUser == 5) { G_kTouchUser5 = kTouchUser; G_fUserTimerSec5 = 0.0; } } // クリックしたユーザー onTouch(key kTouchUser) { if(G_kTouchUser1 == kTouchUser) { return; } if(G_kTouchUser2 == kTouchUser) { return; } if(G_kTouchUser3 == kTouchUser) { return; } if(G_kTouchUser4 == kTouchUser) { return; } if(G_kTouchUser5 == kTouchUser) { return; } if(G_bIsDrawName) { llOwnerSay(llGetDisplayName(kTouchUser) + "さんが触りました…"); } addNewUser(kTouchUser); llPlaySound(G_kSoundData, 1.0); } actTimeCorrection() { float fDeltaTime = llGetTime(); // 時間を超えたものを削除する if(G_kTouchUser1 != NULL_KEY) { G_fUserTimerSec1 += fDeltaTime; if(G_fResetTimeSec <= G_fUserTimerSec1) { G_kTouchUser1 = NULL_KEY; } } if(G_kTouchUser2 != NULL_KEY) { G_fUserTimerSec2 += fDeltaTime; if(G_fResetTimeSec <= G_fUserTimerSec2) { G_kTouchUser2 = NULL_KEY; } } if(G_kTouchUser3 != NULL_KEY) { G_fUserTimerSec3 += fDeltaTime; if(G_fResetTimeSec <= G_fUserTimerSec3) { G_kTouchUser3 = NULL_KEY; } } if(G_kTouchUser4 != NULL_KEY) { G_fUserTimerSec4 += fDeltaTime; if(G_fResetTimeSec <= G_fUserTimerSec4) { G_kTouchUser4 = NULL_KEY; } } if(G_kTouchUser5 != NULL_KEY) { G_fUserTimerSec5 += fDeltaTime; if(G_fResetTimeSec <= G_fUserTimerSec5) { G_kTouchUser5 = NULL_KEY; } } llResetTime(); } default { state_entry() { } changed( integer change ) { if( change & CHANGED_INVENTORY ) { llResetScript(); } else if( change & CHANGED_OWNER ) { llResetScript(); } } touch_start(integer num_detected) { if(num_detected == 1) { key touch_key = llDetectedKey(0); checkMemory(); actTimeCorrection(); onTouch(touch_key); } } }
コメント