2010年10月03日
講座3回目っす
折り返しの3回目っす。
4回目は3週間後なので、間違えないで来てくださいっす。
どうもぺんぎんっす( ◎v◎ )
講座の原稿っす。
後半部分は原稿ナシでやってたっす。
なので、ログで確認してくださいっす。
AグループとBグループで違いが出たのが面白いっす。
//------------------
// 第3回 お題
//------------------
//////////////////////////////////////////////////////
// リンクされたオブジェクトを扱います。
//////////////////////////////////////////////////////
// 1.3プリムをリンクさせたオブジェクトを作る
// 2.ルートプリムに「お題」を入れる
//*******************
// グローバル変数
//*******************
integer count;
vector TEXT_COLOR = <0.0, 0.75, 0.0>;
//********************
// state default
//********************
default
{
state_entry()
{
count = 0;
llSetText("", TEXT_COLOR, 1.0);
}
touch_start(integer total_number)
{
integer detected_link_num = llDetectedLinkNumber(0);
if(detected_link_num == LINK_ROOT)
{
llOwnerSay("count: " + (string)count);
}
else if(detected_link_num == 2)
{
count++;
llSetText((string)count, TEXT_COLOR, 1.0);
}
else if(detected_link_num == 3)
{
count--;
llSetText((string)count, TEXT_COLOR, 1.0);
}
}
}
では3回目の講座を始めるっすね
宿題の
「多少はマシになったウェルカムマット」
は今のうちに自分に渡してくださいっす
ちょっと時間を取るっすね
前回はここでワンポイントやったんっすけど
今回はお題とカブる部分が多いので省略っす
あと、今回の講座で使う3プリムのオブジェクトも
今のうちに出すなり作るなりしてくださいっす
試して、動かしながら聞いてもらえば良いっすよ
準備ができたヒトからTypeWith.MEのURLをもらってくださいっす
前にある玉にタッチするとURL出るっすよ
そろそろ良いっすかね?
解説始めるっすよ
お題は「切り替えボタン」っす
ポーズスタンドに直接使えそうなネタを持ってきたっす
応用範囲も広いっすからね
細かいところを見ていく前に、
全体での動きを確認しておくっす
宿題でやってきたと思うんっすけどね
タッチしたのが
A.ルートプリムなら
数字をOwnerSay
B.リンク番号2のプリムなら
数字に1を加えて、フローティングテキストで表示
C.リンク番号3のプリムなら
数字から1を引いて、フローティングテキストで表示
という動きになってたと思うっす
フローティングテキストっていうのは、その名の通り
オブジェクトの上に浮かんでるテキストのことっす
お題は緑色のテキストが浮かぶっすね
では、お題を細かく見ていくっす
いつも通り上から順番に…と行きたいんっすけど、
いきなり「グローバル変数」っていうのが強調されてるっすね
「グルーバル変数」と対になるのが「ローカル変数」っす
「変数」は前回の講座で出てきたやつっす
名前を付けた容器のイメージっだったっすね
実は、変数はどこでも宣言できるわけじゃないっす
1.一番上
2.ユーザ関数の中
3.イベントの中
の3つっす
2.の「ユーザ関数」は「自作関数」とも言って、
名前通り、自分で作った関数のことっす
講座でやるかはビミョーっす
オフィスアワーではやるっすよ
(たぶん)
で、変数を宣言した場所によってグローバルかローカルかが決まるっす
[1.一番上]で宣言するとグローバル変数に、
[2.ユーザ関数の中]や[3.イベントの中]で宣言すると
ローカル変数になるっす
グローバル変数とローカル変数の違いについて説明するっす
TypeWith.Meを見てくださいっす
お題で、宣言した変数は3つあるっす
一番上で宣言した count と TEXT_COLOR
touch_startイベントで宣言した detected_link_num っす
コメントの通り、count と TEXT_COLOR がグローバル変数で
そうじゃない detected_link_num がローカル変数っす
グローバル変数とローカル変数の違いは
その宣言した変数を扱うことのできる範囲っす
(この範囲は「変数のスコープ」とも言うっす)
ローカル変数の範囲は
宣言したのがユーザ関数の中ならその関数の中だけ、
宣言したのがイベント内ならそのイベント内だけ有効っす
グローバル変数の範囲は全部っす
ユーザ関数であろうが、
イベントの中だろうが有効っす
例えstateが複数あったとしてもっす
パネルに、お題で使われてる変数の有効範囲を色分けしたっす
変数の容器というイメージからすると
グローバル変数は詰め替えボトル、
中身を入れ替えて何回も使う感じっす
ローカル変数は使い捨て、
用がすんだら容器ごとポイッという感じっすね
ここからstate defaultに入っていくっす
イベントは2つっすね
state_entry と touch_start っす
state_entry は count に 0 を代入して
フローティングテキストを消してるだけっす
state_entryは大丈夫っすよね?
touch_startイベントの中身は、
タッチされたのが
A.ルートプリムなら
数字をOwnerSay
B.リンク番号2のプリムなら
数字に1を加えて、フローティングテキストで表示
C.リンク番号3のプリムなら
数字から1を引いて、フローティングテキストで表示
というものっす
(大事なことなので2回言ったっす)
ここも上から順番に見ていくっすね
integer detected_link_num = llDetectedLinkNumber(0);
前回の講座で似たようなことやったっすね
今回のお題は
ローカル変数のdetected_link_numを宣言して
llDetectedLinkNumber(0)の値を代入してるっす
リンクされたオブジェクトの各プリムには
「リンクナンバー」が割り当てられてるのは良いっすよね?
ルートプリムが1で、以下2,3,4とリンクされたプリム数だけ続くっす
llDetectedLinkNumberで
「何番のプリムがタッチされたのか」っていう番号を取得してるわけっす
意外と忘れやすいのは
リンクされていない1プリムのオブジェクトのリンクナンバーは0ってことっす
要注意っすよ
次、if文その1[一致/不一致]っす
簡単な話が「左辺と右辺が同じ?」ってことっす
お題の
if(detected_link_num == LINK_ROOT)
これはdetected_link_numの値がLINK_ROOTと同じなら「真」となって、
中の処理、llOwnerSayが行われるわけっす
よーく見てほしいのは、== と、イコールが2つ重ねてあるところっす
単に1つの = だと代入になっちゃうっすよ
== で1つの演算子を表すので、= と = の間にスペースはないっす
さらに厄介なことに、
if(detected_link_num = LINK_ROOT)
とイコールが1つだけになってても
スクリプトが[保存]できちゃうっす
「文法的には正しい」っすからね
次の文
else if(detected_link_num == 2)
ここは
「そうではなく、(もし)detected_link_numが2と等しいなら…」
っていうのを表してるっす
どう「そうではなく」なのかと言うと、
上のif文、if(detected_link_num == LINK_ROOT)
これのことっす
detected_link_num == LINK_ROOT が「偽」のとき、
かつ、detected_link_num == 2が「真」のときに
else if(detected_link_num == 2) の中の処理が行われるっす
さらに下の
else if(detected_link_num == 3)
これも同じっす
detected_link_num == LINK_ROOT が「偽」のとき、
かつ、detected_link_num == 2が「偽」のとき、
かつ、detected_link_num == 3が「真」のときに
else if(detected_link_num == 3) の中の処理が行われるっす
まとめると、
detected_link_numがLINK_ROOTと等しいなら
llOwnerSay("count: " + (string)count);
detected_link_numがLINK_ROOTじゃなくて2のとき
count++;
llSetText((string)count, TEXT_COLOR, 1.0);
detected_link_numがLINK_ROOTでも2でもなく、3のとき
count--;
llSetText((string)count, TEXT_COLOR, 1.0);
という処理が行われるわけっす
次でラストっす
今回は説明を早めに切り上げて、
「ポーズスタンドって、そもそもどんなの?」
っていうテーマで話し合いの時間を取りたいっす
もうちょっとで説明は終わるっすよ
残りは count++; と count--; っす
それぞれ「インクリメント」「デクリメント」と言って
すごく良く見かけるものっす
これも++, -- と2つ重ねて1つの演算子っす
スペース入れちゃダメっすよ
宿題は最後に発表するとして、
今回分の説明は以上っす
あとの時間は
「ポーズスタンドって、そもそもどんなの?」
について考えていくっす
こちらから当てることはしないので
思いついたら即発言で良いっすよ
後からログを見れば良いっすからね
どっちのグループが盛り上がるっすかね?
では、自由に発言してくださいっす
そろそろ時間っすね
講座としては締めさせてもらうっす
さぁ、お待ちかねの宿題発表っす
宿題その1(イメージ)
それぞれの考える「ポーズスタンド」を文章にしてもらうっす
・ポーズスタンドというからにはコレが無いとね!
・こんな機能があれば便利
みたいなことを、文章のスタイルについては問わないっすから
自由に書いてくださいっす
箇条書きでも良いっすよ
次回の講座で提出してもらうっす
ノートカードに書いて、
名前をtxt3_(各自の名前)
パーミッションはフルパーミッションに変えて出してくださいっす
宿題その2(次回の予習)
お題をTypeWith.Meに貼り付けるのでちょっと待ってくださいっす
貼り付けたっす
これについて分からないところは調べて来てくださいっす
ちょっとずつお題も長くなってきたっすね
次回の講座は3週間後になるっす
23日(土)の、いつもの時間からっす
時間の余裕はあるっすから、じっくりやってみてくださいっす
オフィスアワーは水曜日・土曜日、変わらずやるっす
質問等あればどうぞっす
名前出しNGの方はこの後に言ってくださいっす
連絡等はこれくらいっすかね
ではお疲れさまでしたっす
//-----------------
// 第4回 お題
//-----------------
//******************
// グローバル変数
//******************
string ANIM_NAME = "run";
key sitting_av = NULL_KEY;
//******************
// state default
//******************
default
{
state_entry()
{
llSitTarget(<0.0, 0.0, 2.0>, ZERO_ROTATION);
}
changed(integer change)
{
if(change & CHANGED_LINK)
{
key av = llAvatarOnSitTarget();
if(sitting_av)
{
if(av)
{
llUnSit(av);
}
else
{
llStopAnimation(ANIM_NAME);
sitting_av = NULL_KEY;
}
}
else
{
if(av)
{
sitting_av = av;
llRequestPermissions(sitting_av, PERMISSION_TRIGGER_ANIMATION);
}
}
}
}
run_time_permissions(integer perm)
{
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation("sit");
llStartAnimation(ANIM_NAME);
}
}
}
今回はパネルがないとキビシイので、パネルも見てくださいっす。
名前出しNGのヒトがいないか待ってる状態なので、
月曜日にログとセットで置いておくっすね。
[2010/10/03 22時ごろ追加]
今回のポイントのまとめっす。
1.グローバル変数とローカル変数
グローバル変数が登場してきたわけっすね。
お題のcountのように、イベントを抜けた後でも値を
保持させるために使うっす。
ローカル変数は宣言したところだけで有効なので、
default
{
state_entry()
{
integer a = 3;
}
touch_start(integer total_number)
{
llOwnerSay((string)a);
}
}
これはエラーが出るっす。
touch_startイベントではaを宣言されてないっすからね。
あともう1つ、
グローバル変数と同名のローカル変数を宣言した場合っす。
integer a = 2; // グローバル変数のaに代入
default
{
touch_start(integer total_number)
{
integer a = 3; // ローカル変数のaに代入
llOwnerSay((string)a);
}
}
タッチすると、3とOwnerSayされるはずっす。
グローバル変数と同じ名前のローカル変数を宣言した場合、
そのローカル変数のスコープ内では、ローカル変数としてのみ
取り扱われるっす。
上の例でtouch_startイベントで宣言したaの値、
3がOnwerSayされる仕掛けっす。
グローバル変数のaとローカル変数のaは別のもの、
と考えると分かりやすいのかもっすね。
integer a = 2; // グローバル変数のaに代入
default
{
touch_start(integer total_number)
{
integer a = 3; // ローカル変数のaに代入
llOwnerSay((string)a); // ローカル変数のa
}
collision_start(integer total_number)
{
llOwnerSay((string)a); // グローバル変数のa
}
}
2.if文その1[一致/不一致]とelse if
等しいなら真は==で
等しくないなら真は!=でやるっす。
!=はお題では出てこなかったっすけど、こっちも良く使うっす。
ここはイケると思うっす。
問題はelse ifっす。
if ~ else if ~ else は条件に当てはまれば全てやるのではなく、
上から順番に調べて行って、当てはまった最初の1つだけ、
中の処理を行うっす。
例えばっすけど、
default
{
touch_start(integer total_number)
{
integer a = 3;
if(a != 2)
{
llOwnerSay("A");
}
else if(a == 3)
{
llOwnerSay("B");
}
else if(a < 4)
{
llOwnerSay("C");
}
else
{
llOwnerSay("D");
}
}
}
タッチすると何とOwnerSayされるかやってみてくださいっす。
A、B、CとOwnerSayされるように見えるっすけど、
一番最初に条件に当てはまった、AとだけOwnerSayするっす。
要注意っすね。
3.インクリメントとデクリメント
パネルにはチラッと書いてあるんっすけど、
a++; という書き方の他に、
++a; という書き方もあるっす。
単独で書いた場合はどちらも同じ結果になるっす。
http://wiki.secondlife.com/wiki/LSL_Script_Efficiency
には前置インクリメントの++aを使えと書いてあるんっすけど、
先ほど、いつも講座をやってる場所で試してみたっす。
(Server 10.09.21.21014)
ループで100万回(ケタは合ってるっすよ)回してみたところ、
実行速度には違いが見られなかったっす。
さらにllGetFreeMemoryで見ても同じだったっす。
ということは、作法の問題になるんっすかねぇ。
作法としてなら++a; が適当っす。
単独で使う場合では前置も後置も同じ結果っすけど、
他と組み合わせて使うと違う結果になることもあるっす。
default
{
touch_start(integer total_number)
{
integer a = 3;
integer b;
b = a++; // ここと
llOwnerSay("前置:" + (string)a + ", " + (string)b);
a = 3;
b = ++a; // ここに注目
llOwnerSay("後置:" + (string)a + ", " + (string)b);
}
}
まず上のb = a++; と書くと、
b = a; // 先に代入してから
a = a + 1; // 1を加える
そして下のb = ++a; と書くと、
a = a + 1; // 先に1加えてから
b = a; // bに代入
というわけで、結果が違ってくるわけっす。
インクリメントばかりの話になったので、デクリメントっす。
default
{
touch_start(integer total_number)
{
integer a = 5;
while(a--) // ここと
{
llOwnerSay((string)a);
}
a = 5;
while(--a) // ここに注目
{
llOwnerSay((string)a);
}
}
}
これはまだ出てきてないwhile文のループなんっすけど、
前置/後置で結果が違うっす。
aが0のときにループを抜けるんっすけど、
その判定のタイミングが違ってくるっす。
while(a--) はaを評価してから-1を、
while(--a) はaを-1してから評価してるっす。
結果として上のループでは0もOwnerSayするんっすけど、
下のループでは0はOwnerSayされなくなるわけっす。
組み合わせで使う場合、
前置(++aのパターン)は先に加減算してから代入などの処理を
後置(a++のパターン)は代入などをした後に加減算をする
と覚えれば良いっすかね。
4.ポーズスタンドってどんなモノ?
講座のどこかでは入れたかったっす。
タイミング的にはビミョーだったかもしれないっすけどね。
作るモノが、そもそもどんなモノか分かっていないと、
作りようが無いっすからね。
最終的にイメージしたモノが作れればベストなんっすけどね。
ある程度の妥協は仕方ないっす。
とりあえず、イメージだけでも固めてもらえれば良いっす。
4回目は3週間後なので、間違えないで来てくださいっす。
どうもぺんぎんっす( ◎v◎ )
講座の原稿っす。
後半部分は原稿ナシでやってたっす。
なので、ログで確認してくださいっす。
AグループとBグループで違いが出たのが面白いっす。
//------------------
// 第3回 お題
//------------------
//////////////////////////////////////////////////////
// リンクされたオブジェクトを扱います。
//////////////////////////////////////////////////////
// 1.3プリムをリンクさせたオブジェクトを作る
// 2.ルートプリムに「お題」を入れる
//*******************
// グローバル変数
//*******************
integer count;
vector TEXT_COLOR = <0.0, 0.75, 0.0>;
//********************
// state default
//********************
default
{
state_entry()
{
count = 0;
llSetText("", TEXT_COLOR, 1.0);
}
touch_start(integer total_number)
{
integer detected_link_num = llDetectedLinkNumber(0);
if(detected_link_num == LINK_ROOT)
{
llOwnerSay("count: " + (string)count);
}
else if(detected_link_num == 2)
{
count++;
llSetText((string)count, TEXT_COLOR, 1.0);
}
else if(detected_link_num == 3)
{
count--;
llSetText((string)count, TEXT_COLOR, 1.0);
}
}
}
では3回目の講座を始めるっすね
宿題の
「多少はマシになったウェルカムマット」
は今のうちに自分に渡してくださいっす
ちょっと時間を取るっすね
前回はここでワンポイントやったんっすけど
今回はお題とカブる部分が多いので省略っす
あと、今回の講座で使う3プリムのオブジェクトも
今のうちに出すなり作るなりしてくださいっす
試して、動かしながら聞いてもらえば良いっすよ
準備ができたヒトからTypeWith.MEのURLをもらってくださいっす
前にある玉にタッチするとURL出るっすよ
そろそろ良いっすかね?
解説始めるっすよ
お題は「切り替えボタン」っす
ポーズスタンドに直接使えそうなネタを持ってきたっす
応用範囲も広いっすからね
細かいところを見ていく前に、
全体での動きを確認しておくっす
宿題でやってきたと思うんっすけどね
タッチしたのが
A.ルートプリムなら
数字をOwnerSay
B.リンク番号2のプリムなら
数字に1を加えて、フローティングテキストで表示
C.リンク番号3のプリムなら
数字から1を引いて、フローティングテキストで表示
という動きになってたと思うっす
フローティングテキストっていうのは、その名の通り
オブジェクトの上に浮かんでるテキストのことっす
お題は緑色のテキストが浮かぶっすね
では、お題を細かく見ていくっす
いつも通り上から順番に…と行きたいんっすけど、
いきなり「グローバル変数」っていうのが強調されてるっすね
「グルーバル変数」と対になるのが「ローカル変数」っす
「変数」は前回の講座で出てきたやつっす
名前を付けた容器のイメージっだったっすね
実は、変数はどこでも宣言できるわけじゃないっす
1.一番上
2.ユーザ関数の中
3.イベントの中
の3つっす
2.の「ユーザ関数」は「自作関数」とも言って、
名前通り、自分で作った関数のことっす
講座でやるかはビミョーっす
オフィスアワーではやるっすよ
(たぶん)
で、変数を宣言した場所によってグローバルかローカルかが決まるっす
[1.一番上]で宣言するとグローバル変数に、
[2.ユーザ関数の中]や[3.イベントの中]で宣言すると
ローカル変数になるっす
グローバル変数とローカル変数の違いについて説明するっす
TypeWith.Meを見てくださいっす
お題で、宣言した変数は3つあるっす
一番上で宣言した count と TEXT_COLOR
touch_startイベントで宣言した detected_link_num っす
コメントの通り、count と TEXT_COLOR がグローバル変数で
そうじゃない detected_link_num がローカル変数っす
グローバル変数とローカル変数の違いは
その宣言した変数を扱うことのできる範囲っす
(この範囲は「変数のスコープ」とも言うっす)
ローカル変数の範囲は
宣言したのがユーザ関数の中ならその関数の中だけ、
宣言したのがイベント内ならそのイベント内だけ有効っす
グローバル変数の範囲は全部っす
ユーザ関数であろうが、
イベントの中だろうが有効っす
例えstateが複数あったとしてもっす
パネルに、お題で使われてる変数の有効範囲を色分けしたっす
変数の容器というイメージからすると
グローバル変数は詰め替えボトル、
中身を入れ替えて何回も使う感じっす
ローカル変数は使い捨て、
用がすんだら容器ごとポイッという感じっすね
ここからstate defaultに入っていくっす
イベントは2つっすね
state_entry と touch_start っす
state_entry は count に 0 を代入して
フローティングテキストを消してるだけっす
state_entryは大丈夫っすよね?
touch_startイベントの中身は、
タッチされたのが
A.ルートプリムなら
数字をOwnerSay
B.リンク番号2のプリムなら
数字に1を加えて、フローティングテキストで表示
C.リンク番号3のプリムなら
数字から1を引いて、フローティングテキストで表示
というものっす
(大事なことなので2回言ったっす)
ここも上から順番に見ていくっすね
integer detected_link_num = llDetectedLinkNumber(0);
前回の講座で似たようなことやったっすね
今回のお題は
ローカル変数のdetected_link_numを宣言して
llDetectedLinkNumber(0)の値を代入してるっす
リンクされたオブジェクトの各プリムには
「リンクナンバー」が割り当てられてるのは良いっすよね?
ルートプリムが1で、以下2,3,4とリンクされたプリム数だけ続くっす
llDetectedLinkNumberで
「何番のプリムがタッチされたのか」っていう番号を取得してるわけっす
意外と忘れやすいのは
リンクされていない1プリムのオブジェクトのリンクナンバーは0ってことっす
要注意っすよ
次、if文その1[一致/不一致]っす
簡単な話が「左辺と右辺が同じ?」ってことっす
お題の
if(detected_link_num == LINK_ROOT)
これはdetected_link_numの値がLINK_ROOTと同じなら「真」となって、
中の処理、llOwnerSayが行われるわけっす
よーく見てほしいのは、== と、イコールが2つ重ねてあるところっす
単に1つの = だと代入になっちゃうっすよ
== で1つの演算子を表すので、= と = の間にスペースはないっす
さらに厄介なことに、
if(detected_link_num = LINK_ROOT)
とイコールが1つだけになってても
スクリプトが[保存]できちゃうっす
「文法的には正しい」っすからね
次の文
else if(detected_link_num == 2)
ここは
「そうではなく、(もし)detected_link_numが2と等しいなら…」
っていうのを表してるっす
どう「そうではなく」なのかと言うと、
上のif文、if(detected_link_num == LINK_ROOT)
これのことっす
detected_link_num == LINK_ROOT が「偽」のとき、
かつ、detected_link_num == 2が「真」のときに
else if(detected_link_num == 2) の中の処理が行われるっす
さらに下の
else if(detected_link_num == 3)
これも同じっす
detected_link_num == LINK_ROOT が「偽」のとき、
かつ、detected_link_num == 2が「偽」のとき、
かつ、detected_link_num == 3が「真」のときに
else if(detected_link_num == 3) の中の処理が行われるっす
まとめると、
detected_link_numがLINK_ROOTと等しいなら
llOwnerSay("count: " + (string)count);
detected_link_numがLINK_ROOTじゃなくて2のとき
count++;
llSetText((string)count, TEXT_COLOR, 1.0);
detected_link_numがLINK_ROOTでも2でもなく、3のとき
count--;
llSetText((string)count, TEXT_COLOR, 1.0);
という処理が行われるわけっす
次でラストっす
今回は説明を早めに切り上げて、
「ポーズスタンドって、そもそもどんなの?」
っていうテーマで話し合いの時間を取りたいっす
もうちょっとで説明は終わるっすよ
残りは count++; と count--; っす
それぞれ「インクリメント」「デクリメント」と言って
すごく良く見かけるものっす
これも++, -- と2つ重ねて1つの演算子っす
スペース入れちゃダメっすよ
宿題は最後に発表するとして、
今回分の説明は以上っす
あとの時間は
「ポーズスタンドって、そもそもどんなの?」
について考えていくっす
こちらから当てることはしないので
思いついたら即発言で良いっすよ
後からログを見れば良いっすからね
どっちのグループが盛り上がるっすかね?
では、自由に発言してくださいっす
そろそろ時間っすね
講座としては締めさせてもらうっす
さぁ、お待ちかねの宿題発表っす
宿題その1(イメージ)
それぞれの考える「ポーズスタンド」を文章にしてもらうっす
・ポーズスタンドというからにはコレが無いとね!
・こんな機能があれば便利
みたいなことを、文章のスタイルについては問わないっすから
自由に書いてくださいっす
箇条書きでも良いっすよ
次回の講座で提出してもらうっす
ノートカードに書いて、
名前をtxt3_(各自の名前)
パーミッションはフルパーミッションに変えて出してくださいっす
宿題その2(次回の予習)
お題をTypeWith.Meに貼り付けるのでちょっと待ってくださいっす
貼り付けたっす
これについて分からないところは調べて来てくださいっす
ちょっとずつお題も長くなってきたっすね
次回の講座は3週間後になるっす
23日(土)の、いつもの時間からっす
時間の余裕はあるっすから、じっくりやってみてくださいっす
オフィスアワーは水曜日・土曜日、変わらずやるっす
質問等あればどうぞっす
名前出しNGの方はこの後に言ってくださいっす
連絡等はこれくらいっすかね
ではお疲れさまでしたっす
//-----------------
// 第4回 お題
//-----------------
//******************
// グローバル変数
//******************
string ANIM_NAME = "run";
key sitting_av = NULL_KEY;
//******************
// state default
//******************
default
{
state_entry()
{
llSitTarget(<0.0, 0.0, 2.0>, ZERO_ROTATION);
}
changed(integer change)
{
if(change & CHANGED_LINK)
{
key av = llAvatarOnSitTarget();
if(sitting_av)
{
if(av)
{
llUnSit(av);
}
else
{
llStopAnimation(ANIM_NAME);
sitting_av = NULL_KEY;
}
}
else
{
if(av)
{
sitting_av = av;
llRequestPermissions(sitting_av, PERMISSION_TRIGGER_ANIMATION);
}
}
}
}
run_time_permissions(integer perm)
{
if(perm & PERMISSION_TRIGGER_ANIMATION)
{
llStopAnimation("sit");
llStartAnimation(ANIM_NAME);
}
}
}
今回はパネルがないとキビシイので、パネルも見てくださいっす。
名前出しNGのヒトがいないか待ってる状態なので、
月曜日にログとセットで置いておくっすね。
[2010/10/03 22時ごろ追加]
今回のポイントのまとめっす。
1.グローバル変数とローカル変数
グローバル変数が登場してきたわけっすね。
お題のcountのように、イベントを抜けた後でも値を
保持させるために使うっす。
ローカル変数は宣言したところだけで有効なので、
default
{
state_entry()
{
integer a = 3;
}
touch_start(integer total_number)
{
llOwnerSay((string)a);
}
}
これはエラーが出るっす。
touch_startイベントではaを宣言されてないっすからね。
あともう1つ、
グローバル変数と同名のローカル変数を宣言した場合っす。
integer a = 2; // グローバル変数のaに代入
default
{
touch_start(integer total_number)
{
integer a = 3; // ローカル変数のaに代入
llOwnerSay((string)a);
}
}
タッチすると、3とOwnerSayされるはずっす。
グローバル変数と同じ名前のローカル変数を宣言した場合、
そのローカル変数のスコープ内では、ローカル変数としてのみ
取り扱われるっす。
上の例でtouch_startイベントで宣言したaの値、
3がOnwerSayされる仕掛けっす。
グローバル変数のaとローカル変数のaは別のもの、
と考えると分かりやすいのかもっすね。
integer a = 2; // グローバル変数のaに代入
default
{
touch_start(integer total_number)
{
integer a = 3; // ローカル変数のaに代入
llOwnerSay((string)a); // ローカル変数のa
}
collision_start(integer total_number)
{
llOwnerSay((string)a); // グローバル変数のa
}
}
2.if文その1[一致/不一致]とelse if
等しいなら真は==で
等しくないなら真は!=でやるっす。
!=はお題では出てこなかったっすけど、こっちも良く使うっす。
ここはイケると思うっす。
問題はelse ifっす。
if ~ else if ~ else は条件に当てはまれば全てやるのではなく、
上から順番に調べて行って、当てはまった最初の1つだけ、
中の処理を行うっす。
例えばっすけど、
default
{
touch_start(integer total_number)
{
integer a = 3;
if(a != 2)
{
llOwnerSay("A");
}
else if(a == 3)
{
llOwnerSay("B");
}
else if(a < 4)
{
llOwnerSay("C");
}
else
{
llOwnerSay("D");
}
}
}
タッチすると何とOwnerSayされるかやってみてくださいっす。
A、B、CとOwnerSayされるように見えるっすけど、
一番最初に条件に当てはまった、AとだけOwnerSayするっす。
要注意っすね。
3.インクリメントとデクリメント
パネルにはチラッと書いてあるんっすけど、
a++; という書き方の他に、
++a; という書き方もあるっす。
単独で書いた場合はどちらも同じ結果になるっす。
http://wiki.secondlife.com/wiki/LSL_Script_Efficiency
には前置インクリメントの++aを使えと書いてあるんっすけど、
先ほど、いつも講座をやってる場所で試してみたっす。
(Server 10.09.21.21014)
ループで100万回(ケタは合ってるっすよ)回してみたところ、
実行速度には違いが見られなかったっす。
さらにllGetFreeMemoryで見ても同じだったっす。
ということは、作法の問題になるんっすかねぇ。
作法としてなら++a; が適当っす。
単独で使う場合では前置も後置も同じ結果っすけど、
他と組み合わせて使うと違う結果になることもあるっす。
default
{
touch_start(integer total_number)
{
integer a = 3;
integer b;
b = a++; // ここと
llOwnerSay("前置:" + (string)a + ", " + (string)b);
a = 3;
b = ++a; // ここに注目
llOwnerSay("後置:" + (string)a + ", " + (string)b);
}
}
まず上のb = a++; と書くと、
b = a; // 先に代入してから
a = a + 1; // 1を加える
そして下のb = ++a; と書くと、
a = a + 1; // 先に1加えてから
b = a; // bに代入
というわけで、結果が違ってくるわけっす。
インクリメントばかりの話になったので、デクリメントっす。
default
{
touch_start(integer total_number)
{
integer a = 5;
while(a--) // ここと
{
llOwnerSay((string)a);
}
a = 5;
while(--a) // ここに注目
{
llOwnerSay((string)a);
}
}
}
これはまだ出てきてないwhile文のループなんっすけど、
前置/後置で結果が違うっす。
aが0のときにループを抜けるんっすけど、
その判定のタイミングが違ってくるっす。
while(a--) はaを評価してから-1を、
while(--a) はaを-1してから評価してるっす。
結果として上のループでは0もOwnerSayするんっすけど、
下のループでは0はOwnerSayされなくなるわけっす。
組み合わせで使う場合、
前置(++aのパターン)は先に加減算してから代入などの処理を
後置(a++のパターン)は代入などをした後に加減算をする
と覚えれば良いっすかね。
4.ポーズスタンドってどんなモノ?
講座のどこかでは入れたかったっす。
タイミング的にはビミョーだったかもしれないっすけどね。
作るモノが、そもそもどんなモノか分かっていないと、
作りようが無いっすからね。
最終的にイメージしたモノが作れればベストなんっすけどね。
ある程度の妥協は仕方ないっす。
とりあえず、イメージだけでも固めてもらえれば良いっす。
Posted by ぺんぎん at 00:17│Comments(2)
│デジアカ
この記事へのコメント
追記の部分でインクリメントの前置と後置がまぜて使われているので、
あたまが爆発しました><
プログラム部分の
b = a++; // ここと は b = ++a;で、
b = ++a; // ここに注目 は b = a++;
次の説明文の
まず上のb = a++; は b = ++a;で、
そして下のb = ++a;は b = a++;
では、ないでしょうか。
(勿論、ちゃんと読んでいるのか試されているのだと思いますが....)
あたまが爆発しました><
プログラム部分の
b = a++; // ここと は b = ++a;で、
b = ++a; // ここに注目 は b = a++;
次の説明文の
まず上のb = a++; は b = ++a;で、
そして下のb = ++a;は b = a++;
では、ないでしょうか。
(勿論、ちゃんと読んでいるのか試されているのだと思いますが....)
Posted by ねこねこ at 2010年10月04日 21:45
指摘どうもっす。
見事に逆になってたっすね。
もうちょっと下に書いた
「前置(++aのパターン)は先に加減算してから代入などの処理を、
後置(a++のパターン)は代入などをした後に加減算をする」
っていうので覚えてもらえれば良いっすね。
見事に逆になってたっすね。
もうちょっと下に書いた
「前置(++aのパターン)は先に加減算してから代入などの処理を、
後置(a++のパターン)は代入などをした後に加減算をする」
っていうので覚えてもらえれば良いっすね。
Posted by ぺんぎん
at 2010年10月04日 22:31
