2007年12月28日 星期五

啥SL—【給初心者的話……前言與應用】

前言

  這篇文章呢,是要寫給學弟妹們看的,主要是因為當時寒假碰Second Life怎麼碰都不懂,不清楚他到底有怎樣的應用,當時我也沒發現有巴哈姆特這討論區,也沒有發現第二人生網,也沒有老師現在手上已經出版的LSL書籍,加上因為英文能力還不太夠,導致當時一直原地踏步,整個寒假下來可以說什麼也沒有碰(只有拼命地製作方塊……),也因為這樣,我知道碰Second Life的難處就是英文要夠強,所以多少想做點中文筆記希望有幫助到學弟妹們。

  也因此,老實說,現在要我重做一款Second Life有關的遊戲,我大概有把握做得比之前好……

  不過啦,我LSL大概只摸熟了50-60%,並不是完全都懂,所以我會將我所知道的程式中較主要功能分享給大家知道。題外話,梅老師說我在巴哈姆特啥有頭有臉,他錯了Orz……我在那裡根本沒發啥發言,只有留個msn,結果有一兩三個不認識的加我,一個想要創業,但現在已經沒興趣了,一個是景文科技大學也是想開發Second Life相關,大概就只是這樣吧……OK,以下進入主題。

  基本上我已經寫了一些Second Life的入門了,可以點入以下連結先搞清楚一下Second Life到底是什麼,到底有怎樣的東西在裡面,還有哪邊的論壇可以幫助你:

  【SecondLife入門】
  【在SL的華人地點(?)介紹】

  如果你要了解建造物品,可以看這篇文章:
  
【Creator入門】  

  而是要先了解Secon Life的程式碼LSL,可以看下列文章:
  
【LSL入門連結推鑒】
  【LSL程式基本架構】

  我其實沒想到兩組都會是跟Seond Life有關。那天被通知是一點半開始的關係因此而遲到,所以我是問同組的小賴才知道的,我想,你們應該也是被梅興老師逼的吧(淚)……(喂)

  所以本來是想講點可能的開發方向,但既然已經被老師鎖定為線上醫療和SLS(Social Learning Space),那就也沒辦法了,雖然當時老師也是想做跟線上教學有關,因為我執意想做單機遊戲,所以就妥協了個Second Life上的單機遊戲……如果是遊戲方面的idea我應該算有一些,但這兩樣我就真的有點苦惱了,老實說如果要我來做,我實在不清楚要怎麼做。

  不過,也不是說沒有其他方向的可能性,建議就是多把自己的想法提出來。所以在為學弟妹們想你們開發的方向前,我會先介紹在YouTube上看到跟Second Life相關的開發以及我們這屆專題所有有用到的主要功能。

YouTube影片



這個是和google map的相關應用




這是會發泡泡的東西,老實說有一點不是很了解這東西的應用,但是至少知道他有用到notecard,所以要開發時應該是可以利用notecard開發的,而這一點是我們那時專題所沒想到的



這是即時的資料,看起來像大氣系統……



這一樣是用即時資料,是氣像預報和飛機航班的系統……



有點類似於關鍵字廣告……



這個是我看過最屌的應用影片,因為這是我唯一摸不著這到底是用什麼開發的Second Life應用,只能從相關影片看到他有用到KML,我猜想很有可能是利用libsecondlife



這個老實説我也不太清楚是怎麼用的,但總之就是skype的視訊可以看到Second Life

  以上的影片大都是由http://nwn.blogs.com/nwn/、與http://digitalurban.blogspot.com/這兩個人分享的,所以還可以從You Tube看一下該使用者分享的影片再去看看還有哪些可能的應用……

其它連結

  還有其他的網站可以去看看Second Life有什麼其他可能的應用與好玩的東西,像是Second Life News、Linden Lab官網、Second Life Grid(這東西好像跟建東西有關,但目前我還沒研究)、libsecondlife(可利用C#去操控Second Life裡面的帳號,他也有提供一些api可用)、Sloodle(教學平台相關),這些都是我在我之前文章還沒有提到的,或許大家可以過去看看,雖然都是英文看起來應該會挺辛苦的……

相關連結:
啥SL—【給初心者的話……我們的專題主程式介紹】
啥SL—【給初心者的話……專題開發可能的方向……】

啥SL—【ParticleSystem(分子系統)】

  分子系統是一個在3D世界中很常聽到的東西,我們玩的3D遊戲常會有火的流動特效或水噴灑的特效都要靠他,在LSL可利用llParticleSystem(list parameters)這個method,可以點入連結觀看他list內的參數,老實說我想一開始剛碰LSL的人應該看不懂,不過說實在話的,裡面有一大堆參數我也不是很了解,所以LSL有提供範例給我們參考,他那個範例很簡單,就是你可以改變每個參數,一個一個去試。

啥SL—【Teleport(傳送)】


  TelePort的功能其實沒有想像地那麼簡單,說要傳送就直接用一個method直接可以傳送,他的原理是很奇怪的。原理是先讓使用者坐在某個地方,然後讓他站起來。所以在Second Life,往往會把Sit On here這個Pie Mwnu上的字改為"Teleport",因此有時候字沒有更改的時候,按Sit On Here也可以傳送。

  所以他是利用llSitTarget(vector offset, rotation rot)、llAvatarOnSitTarget()、llUnSit(key id)與changed Event這四個做搭配。

  除了以上連結的範例,我自己也有寫一個範例程式如下:

vector color = <0,1,1>; // set float text color to blue
string staticText = "Teleport to ground !!";
default
{
state_entry()
{
llSetText(staticText, color, 2.0);
llSetSitText("Teleport"); // change "sit" option to "Teleport"
llSitTarget(<0.0,>, ZERO_ROTATION); // needed for llAvatarOnSitTarget to work

if(llAvatarOnSitTarget() != NULL_KEY) // if someone is sitting
llUnSit(llAvatarOnSitTarget()); // unsit him
}
changed(integer change)
{
if (change & CHANGED_LINK)
{ // if a link change occurs (sit or unsit)
llResetScript();
}
}
}

  簡單來講,就是先讓使用者坐在某物件時,利用llSitTarget讓他坐到一個相對位置(就是離這物件多遠的位置,也就是修改vector),至於rotation就是更改使用者坐下時的角度,而之後因為坐下時啟動了changed event,所以整個程式Reset一次,因為Reset一次後他會跑一次state_entry,他測到有人坐在上面,所以他就用llUnsit讓使用者站起來,所以整體看起來很像是用傳送的。

  其實我的寫法是有點怪的,因為這是為了測試我想法對不對的程式碼,所以要是能的話請直接參考連結內的範例程式。

  要注意的是,利用這種方法有可能會因為你的顯示卡不夠力或網路lag導致你有時候好像傳送到異空間一樣(如圖)。

啥SL—【結界師……】

  今天在專一看到熊哥在看《結界師》……主角一直站在方塊的結界上(如圖)跳來跳去……

  我除了很直覺地想到洛克人也有類似的關卡設計外……還想到了Second Life的方塊(茶),只要有人扮成結界師的主角右鍵Create就產生一堆結界了呢!Zzz




有影片有真相呀!

2007年12月21日 星期五

啥SL—【Event—Attach】

這是我做的裝備,每個裝備都有用到attach event

  Attach Event就是當使用者把一物體穿上(右鍵選Pie Menu的Attach或Wear)所啟動的Event
,就是把
attach(key attached)放入state內就可以啟動,attached這個key值所代表的意義是該穿上物品的key值,如果脫下時就是NULL_KEY。因此可以用這個來判斷使用者穿上時與脫下時的狀態。

  範例程式如下:

default
{
attach(key attached)
{

//object has been attached
if (attached != NULL_KEY)
{
llSetScale(<0.01,0.01,0.6>);

}//end if (attached != NULL_KEY) // object has been attached

// object has been detached
else
{
llSetScale(<0.05,0.05,3>);

}//end else // object has been detached

}//end state default attach(key attached)
}


  llSetScale(vector scale)這個method是改變大小用的,裡面傳的vector是改變物體x、y、z方向的大小,簡單來講,這個程式碼是會讓使用者穿上後改變該物體大小,脫下後又變大小。其實這個範例的靈感是想說,他放在地板上看起來很平常,結果一讓使用者戴上後就變成別的東西……

  關於Attach有一點要記住,穿上的物品是無法消失的,所以無法使用llDie。

啥SL—【Event—Timer】


  所有跟時間有關的程式在這裡有,而這邊要提的只有timer這個Event。

  而要啟動這個Event,要使用
llSetTimerEvent(float sec)這個method,這個method一啟動,代表他每sec秒就會啟動一次timer()這個event,而當sec=0時,就會停止啟動。

  之前在介紹LSL架構時有提到timer這個event和其他event有不同的地方,在於state轉換後這個event會繼續啟動,因此建議在轉換state時可以在
state_exit裡寫下llSetTimerEvent(0);部分程式碼範例如下:
state_exit()
{
  llSetTimerEvent(0);
}
  state_exit意思就是在轉態轉移時他一定會先啟動state_exit內的程式再轉到下一個state。

  現在,展示一下Timer的使用範例:

default
{
touch_start(integer total_number)
{
llSetTimerEvent(1);
}

timer()
{
second++;

if(second==10)
{
llSay(0,"Good Bye!Master!");
llDie();
}

llSay(0,(string)(10-second));
}
}

  llDie意思就是讓該物消失,所以這程式碼會每秒啟動一次timer(),到了10秒時會消失。

啥SL—【Event—Collision】

Collision

  如同字義,就是碰撞,只要你把collision(integer num_detected)、collision_start(integer num_detected)、collision_end(integer num_detected)、land_collision(vector pos)
、land_collision_start(vector pos)
、land_collision_end(vector pos)
這幾個Event放入程式碼就會因為物體受到碰撞而啟動該Event內的程式。

  在這邊先來說說collision和land_collision有什麼差別好了,前者是只要有使用者(AGENT)和物件(object)觸碰就會啟動,後者是只要碰到土地才會啟動。而獲得的參數資料,前者是測到有幾個人或物同時碰到,後者是測碰到該物的土地位置。

  而有start、end以及沒有這兩個字樣的event都和之前的Seonsor與Touch一樣,剛開始碰撞,和碰撞結束以及持續碰。

  不過因為他這event並不像那樣
Seonsor那樣有什麼重複和單一次碰,所以只要有碰撞他都會偵測,搞得我覺得這三樣好像功用差不多,雖然持續碰撞確實是會持續一陣子啟動,但我使用的效果並沒有那麼好,感覺他的感應太過於敏感。

  總之,以下是範例程式碼:

default
{
collision_start(integer num_detected)
{
llSay(0,"Don't kiss my ass!!!");
}

collision(integer num_detected)
{
llSay(0,"Don't fuck me!!");
}
collision_end(integer num_detected)
{
llSay(0,"Don't leave me!!!");
}

land_collision_start(vector pos)
{
llSay(0,"I touch the land!!");
}

land_collision(vector pos)
{
llSay(0,"I can't leave the land!!!");
}

land_collision_end(vector pos)
{
llSay(0,"Go to find another land!!!");
}

}


  嗯,因為實驗結果和我預期的有一點不太一樣,所以我不太好解釋,建議去試著寫看看。

  還有,
collision、collision_start、collision_end這三個event如果要特別過慮某種物件可以使用llCollisionFilter(string name, key id, integer accept)這個method,這個method在我們的遊戲當中是很重要的成份,他降低了event一直被碰撞啟動的麻煩……不過還是不夠完美,因為他只能特別針對一個物件過濾,不能對多個物件過濾,所以在我們的遊戲當中,魔王本來是要只能對我們的武器感應到碰撞,但因為這個限制,我們只能寫只對"Object"物件過濾。

  看不懂?那看以下使用範例應該會比較快:

default
{
state_entry()
{
llCollisionFilter("shortlin Yue", NULL_KEY, TRUE);
}

collision_start(integer num_detected)
{
llSay(0, "Oh my god, you are shortlin!!");
}
}


  上面這個程式碼呢,就是我"shortlin Yue"或著名叫"shortlin Yue"的物件去碰他,他就會說話了,其他東西碰到就不會說話,所以name是傳物體或使用者名字,id就是該使用者或物體的key值,但這裡可有可無,當是NULL_KEY時就代表沒有特別限制"哪一個"特別的物件或使用者,而accept是要傳0或1的布林值,當是TRUE時,就代表只允許,FALSE就代表不允許。

  所以當時我們的專題本來是想用這個方法特別限定只會測到我們的武器,可惜的是我們的武器有很多樣,這個method多寫又沒有用(他只針對最後一個),所以我們最後才寫了
llCollisionFilter("Object", NULL_KEY, FALSE);因為我們的地板是叫"Object",為了避免魔王每次碰地板都會啟動event所以才這樣寫。