2008年05月19日
プロフィール写真を取得・表示するフォトブック(完成版)

先日から配布している「CFT Visitors' Photobook」ですが、
プロフィールに写真を設定していない方への対応が完了し、
一応、現段階では完成、と考えています。
これまでのプログラムでは、
タッチした人のプロフィールに写真がない場合、
画像が見つけられなかった、とスクリプトエラーが表示されていました。
……が、プロフィール写真の設定がない場合、l
lListFindListのスクリプト同様、
「-1」という整数が返ってくることがわかり、
その場合の対処法を追加しました。
今後の改善点としては、
16人の方がタッチしてくれたあとでリストをリセットするため、
同じ方の写真が2枚表示される(日付は異なる)可能性があること。
リピーターは大歓迎ですから、それもまたいいかな、とは思っていますが。
下記、最新版のスクリプトを掲載しておきます。
スクリプトの閲覧できる現物もClub Fabulous Tokyoで配布中ですから、
すぐに触って遊んでみたい、という方はぜひどうぞ。
★ Photobook配布場所のご案内 ★
1.クラブのエントランス通路を直進。
2.茶色い建物(ダンスホール)2階にテレポート。
>> 床にテレポートハブを設置しています。
3.イラストレーション展覧会場を抜け、置くの部屋へ。
上記移動方法が面倒な方は、
エントランス床のインフォメーションマークをクリックし、
起動したテレポートパネルの「Free Scripts and Goods」をクリック。
-------------------------------------
key requestid;
string resident;
integer index;
integer number = 2;
list names = [];
integer name;
default
{
on_rez(integer start_param)
{
llResetScript();
}
state_entry()
{
llSetText("Visitors' Profile Photos\nTouch the panel and add your photo!\nBut if you don't set a photo in your SL profile,\nno photo will appear on the board.", <1,1,1>, 1);
llSetLinkTexture(LINK_ALL_CHILDREN, "woodpaneling", ALL_SIDES);
llMessageLinked(LINK_ALL_CHILDREN, 0, " ", NULL_KEY);
}
touch_start(integer num_detected)
{
resident = llKey2Name(llDetectedKey(0));
name = llListFindList(names, [resident]);
if(name == -1)
{
index = llFloor(llFrand(num_detected));
requestid = llHTTPRequest("http://world.secondlife.com/resident/"+(string)llDetectedKey(index),[HTTP_METHOD,"GET"],"");
names = names + [resident];
}
}
http_response(key request_id, integer status, list metadata, string body)
{
if (request_id == requestid)
{
integer i = llSubStringIndex(body,"http://secondlife.com/app/image/");
if(i != -1)
{
string photo = llGetSubString(body,i+32,i+67);
llSetLinkTexture(number, photo, 1);
}
if(i == -1)
{
llSay(0, "Sorry, " + resident + ". There's no photo in your profile.");
llSetLinkTexture(number, "woodpaneling", 1);
}
llMessageLinked(number, 0, (string)(llGetDate() + " " + resident), NULL_KEY);
number++;
if(number == 18)
{
number = 2;
names = [];
}
}
}
}
-------------------------------------
各命令の説明については、
過去のエントリー「プロフィールの写真を取得しパネルに表示するスクリプト」
をご覧くださいl。
この記事へのトラックバックURL
この記事へのコメント
Takaさん、こんばんは。
スクリプトを拝見させていただきましたが気になる点があったので指摘させていただきます。
touch_startイベントの中でアバター名を所得している部分で
resident = llKey2Name(llDetectedKey(0));
としていますが、
resident = llDetectedName(0);
で一発で取得できます。
llHTTPRequestの中のllDetectedKey引数のindexを
index = llFloor(llFrand(num_detected));
としていますが、これでは正確に取得できません(num_detectedが2の場合を考えてください)。
なぜこんな面倒な計算をしているのか分かりませんが、上のresidentを取得するときは0なのですから、ここも0にしないとなりません。
(もしnum_detectedが2の場合、residentは0番目なのにllHTTPRequest中のllDetectedKeyのindexは1番目になります)
http_responseイベントの中のif(i != -1)に対して
if(i == -1)
と条件判定していますが、elseで十分です。(決してその判定が間違いではないですが・・・。)
elseにすれば前の条件でTRUEであれば無条件にこの処理をしませんので、微妙に処理速度が速くなりますし、コードも少なくなります。
スクリプトを拝見させていただきましたが気になる点があったので指摘させていただきます。
touch_startイベントの中でアバター名を所得している部分で
resident = llKey2Name(llDetectedKey(0));
としていますが、
resident = llDetectedName(0);
で一発で取得できます。
llHTTPRequestの中のllDetectedKey引数のindexを
index = llFloor(llFrand(num_detected));
としていますが、これでは正確に取得できません(num_detectedが2の場合を考えてください)。
なぜこんな面倒な計算をしているのか分かりませんが、上のresidentを取得するときは0なのですから、ここも0にしないとなりません。
(もしnum_detectedが2の場合、residentは0番目なのにllHTTPRequest中のllDetectedKeyのindexは1番目になります)
http_responseイベントの中のif(i != -1)に対して
if(i == -1)
と条件判定していますが、elseで十分です。(決してその判定が間違いではないですが・・・。)
elseにすれば前の条件でTRUEであれば無条件にこの処理をしませんので、微妙に処理速度が速くなりますし、コードも少なくなります。
Posted by ささぴ at 2008年05月19日 19:07
ささびさん
ご指摘ありがとうございます!
アバター名の取得についてはその通りですね。
素人なもので、llHTTPRequestに関するご指摘については、
num_detectedが2になる場合など、
私には少々難しい部分もあります。
いろいろな方のアイディアを組み合わせて、
そこから違ったものを作るのを趣味としているもので……。
最後の条件節の部分は、修正してみます。
ありがとうございました。
ご指摘ありがとうございます!
アバター名の取得についてはその通りですね。
素人なもので、llHTTPRequestに関するご指摘については、
num_detectedが2になる場合など、
私には少々難しい部分もあります。
いろいろな方のアイディアを組み合わせて、
そこから違ったものを作るのを趣味としているもので……。
最後の条件節の部分は、修正してみます。
ありがとうございました。
Posted by mountainbook.tokyo at 2008年05月19日 19:17
touch_startの引数のnum_detectedというのは、そのときタッチした人の人数を返します。
まれですが同時に2人以上の人がタッチするとnum_detectedは1ではなくなりますし、デテクト系の関数で取得するときのインデックスにも関係します。
元のスクリプトで同時に2人がタッチした場合、touch_start(integer num_detected)のnum_detectedは2になります。
resident = llKey2Name(llDetectedKey(0))のときは「0」固定でキーを取得していますので1番目の人のきーを取得します。
(インデックスは0始まり)
で、処理していくとindex = llFloor(llFrand(num_detected))が出てきます。何をしているかというと
「0.0からnum_detected(2.0)までの間の乱数を取って、その小数点以下を切り捨てた整数にする」
ということをやっています。これですと乱数の値が0.0から1.999...の間で発生し、その小数点以下を切り捨てるので、indexは0または1(たぶん確立5割)となります。
次のllHTTPRequest内のllDetectedKey(index)で取得するキーは1番目の人になるのか2番目の人になるのか運任せです。
運悪く2番目の人のキーを取得してしまうと、名前は1番目の人、プロフの画像は2番目の人ということが起こりえるわけです。
touch_startイベントがどの程度シビアに判定しているか分かりませんが、スクリプトを書く上では可能性のあることに対して対策をしておかなければ不具合の原因となるわけです。
まれですが同時に2人以上の人がタッチするとnum_detectedは1ではなくなりますし、デテクト系の関数で取得するときのインデックスにも関係します。
元のスクリプトで同時に2人がタッチした場合、touch_start(integer num_detected)のnum_detectedは2になります。
resident = llKey2Name(llDetectedKey(0))のときは「0」固定でキーを取得していますので1番目の人のきーを取得します。
(インデックスは0始まり)
で、処理していくとindex = llFloor(llFrand(num_detected))が出てきます。何をしているかというと
「0.0からnum_detected(2.0)までの間の乱数を取って、その小数点以下を切り捨てた整数にする」
ということをやっています。これですと乱数の値が0.0から1.999...の間で発生し、その小数点以下を切り捨てるので、indexは0または1(たぶん確立5割)となります。
次のllHTTPRequest内のllDetectedKey(index)で取得するキーは1番目の人になるのか2番目の人になるのか運任せです。
運悪く2番目の人のキーを取得してしまうと、名前は1番目の人、プロフの画像は2番目の人ということが起こりえるわけです。
touch_startイベントがどの程度シビアに判定しているか分かりませんが、スクリプトを書く上では可能性のあることに対して対策をしておかなければ不具合の原因となるわけです。
Posted by ささぴ at 2008年05月19日 21:11
ささぴさん
とても勉強になりました。
早速、修正版を次のエントリーに入れました!
とても勉強になりました。
早速、修正版を次のエントリーに入れました!
Posted by mountainbook.tokyo
at 2008年05月20日 07:49
at 2008年05月20日 07:49












