セカンドライフでタッチすると音がでるスクリプト。
特に連打防止機能をつけたものです。
具体的には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);
}
}
}





コメント