セカンドライフでタッチすると音がでるやつ

セカンドライフ制作
スポンサーリンク

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

コメント

タイトルとURLをコピーしました