ソラマメブログ

2008年03月02日

walking のスクリプティング講座3(その2)

では リスト版 から行ってみよう...
//
// File: dance_ring.lsl
// Date Author number of nodes
// 2007/9/10 walkinglint 82
//
// http://mina.slmame.com/e3291.html
// http://miz.slmame.com/e2400.html
key av_id;
string notecard_name = "dance_list";
integer read_line;
key query_id;
list dance_list = [];
integer i;
integer dance_num;
string dance_name;
list animation_list;

この辺は中で使う変数を宣言したり設定したりしている

notacard_name というのは 連続して実行するアニメーションの名前を入れておくノートカードの名前

ここから読み込んで次々に実行していけばよいというわけだね

読み込んだアニメーションの名前は dace_list というリストに入れておく

1つづつ取り出して実行する... 取り出されたのは dance_name に入れる
activate_load_and_animation() {
dance_list = [];
llOwnerSay("Now Loading..");
read_line = 0;
if (llGetInventoryType(notecard_name) == INVENTORY_NOTECARD) {
query_id = llGetNotecardLine(notecard_name, read_line); // request first line
} else {
llOwnerSay("Notecard " + notecard_name + " is not found");
}
}

ここで dance_list に notecard_name 中のアニメーションの名前を読み込むんだ

っていうか 読み込み始める って言うべきかな

読み込み方はまあ 決まったやり方があって 読み込むノートカードの名前と 読み込む行の番号を指定して llGetNotecardLine を実行すると

後に出てくる dataserver が起動されることになるんだ その時 読み込まれた文字列は data に入っている

まあ この辺は定式みたいなものだから そのまま使えばいいだけ w
animation() {
dance_num = 0;
dance_name = llList2String(dance_list, dance_num);
llOwnerSay(dance_name);
llStartAnimation(dance_name);
llSetTimerEvent(0.5);
}

あ この関数は最初 1回しか使われてないな ^^;

dance_list から最初の アニメーションを取り出して 起動して タイマーを 0.5秒毎に設定している

このタイマーは アニメーションが終わっているかどうかを確認するために使っているんだ 後で見るけど w
default {
on_rez(integer start_param) {
llSetTimerEvent(0.0);
}

最初はタイマーをクリアしてる
    attach(key avid) {
if (avid != NULL_KEY) {
llSetTimerEvent(0.0);
av_id = avid;
integer perm = llGetPermissions();
if ((perm & PERMISSION_TRIGGER_ANIMATION) == 0) {
llRequestPermissions(avid, PERMISSION_TRIGGER_ANIMATION);
} else {
activate_load_and_animation();
}
} else if (llStringLength(dance_name) != 0) {
llStopAnimation(dance_name);
}
}

装着したり外した時ここが呼ばれる

外した時は avid が NULL_KEY になっているので そのタイミングでアニメーションを止めてやればいいんだ

で 装着した時はタイマーをクリヤして パーミッションがあれば 最初に見た activate_load_and_animation を起動する

パーミッションがない場合は llRequestPermissions を起動するだが 多分
    run_time_permissions(integer perm) {
if (perm & PERMISSION_TRIGGER_ANIMATION) {
activate_load_and_animation();
}
}

これを起動することになるんだろう

この辺は決まったパターンなので そのまま使わせてもらう w

いずれにせよ パーミッションが得られたら activate_load_and_animation を起動する
    dataserver(key queryid, string data) {
if (queryid == query_id) {
if (data != EOF) {
// process data
if (llStringLength(data) != 0) {
dance_list = llListInsertList(dance_list, [data], llGetListLength(dance_list));
}
read_line++;
query_id = llGetNotecardLine(notecard_name, read_line);
} else {
llOwnerSay("Loading complete.");
animation();
}
}
}

activate_load_and_animation ではノートの読み込みを起動していて 結局 これが起動されるんだが

読まれた 1行分が data に入っている

入っていたら それを dance_list に追加していく

行番号を進めて 次の行を読みに行く

入ってなかったら 終わりというわけで 読み込み終了 ということで animation を起動する

animation では最初のアニメーションを起動して 0.5秒毎に timer を起動するように設定してたね
    timer() {
animation_list = llGetAnimationList(av_id);
if (llListFindList(animation_list, [llGetInventoryKey(dance_name)]) == -1) {
dance_num++;
if (dance_num == llGetListLength(dance_list)) {
dance_num = 0;
}
dance_name = llList2String(dance_list, dance_num);
llOwnerSay(dance_name);
llStartAnimation(dance_name);
}
}
}

で timer だが

アバターが実行しているアニメーションは llGetAnimationList で取り出せるので 起動したアニメーション dance_name がその中に入っているかどうかを調べることで

起動したアニメーションが終了したかどうかを調べることができる

終了していたら 次の アニメーションを取り出して起動する

dance_num は取り出すアニメーションの順番を保持しているので リストの終わりにきたかどうかを調べて 終わりにきてたら 最初に戻している

こんな所だ あはは

次は 時間版 を見るけど 多分 これより簡単だ w

(続く)

同じカテゴリー(walking のスクリプティング講座)の記事
 プロフィール写真の表示に問題 (2009-11-30 20:55)
 ミニ太陽系 (2009-03-21 06:03)
 関数から文字列を返したら何か問題になる? (2009-03-18 18:02)
 llListFindList って型って関係ないんだったっけ (2009-03-18 14:02)
 夏時間(PDT)の実験 (2009-03-08 22:04)
 15パズルの作り方(その3) (2009-03-08 06:03)
上の画像に書かれている文字を入力して下さい
 
<ご注意>
書き込まれた内容は公開され、ブログの持ち主だけが削除できます。