引言:
本文首先通过简单的入门脚本讲述了LSL程序开发的基本概念和知识,然后在进阶部分创建了一个交通工具的实例,并对这个例子进行了详细分析和解释。
在第二人生中进行脚本编程对于那些没有编程经验的人来说是非常复杂的,就是对于有编程经验的人也是一个挑战,因为它和其他通常的编程语言不同,用到了“状态”。
入门:编写第一个脚本
既然要开始介绍编程基础,那么就要从基本元素开始,不太复杂的例子,因为它就能概括一切了。首先创建一个立方体,进入编辑框的Content属性面板,按下new script按钮。当你打开脚本的时候,你将看到如下内容:
| default { state_entry() { llSay(0, "Hello, Avatar!"); } touch_start(integer total_number) { llSay(0, "Touched."); } } |
这是个非常简单的程序,每个脚本都会自动创建它。当进入到这个世界里,脚本会说:“Hello,Avatar!”,当被出没的时候,说:“Touched”。试一下吧。点击你的立方体。它应该说被点击了。
函数/状态
好了,这是怎么工作的呢?在LSL术语里,default和主“函数”或“状态”类似,是每个事物开始的地方。函数“state_entry()”和“touch_start()”和开关一样,当它们被打开时在大括号中的事件发生。“state_entry()”意思是每次脚本进入到世界中,它被调用或者“打开”。“touch_start()”意思是每当物体被触摸时被调用。在两个大括号里,都有一个IISay()的函数。IISay是说一些东西。第一个数字是使用的频道(有几百万个频道可用,但是一般avatars只在0频道交流,因而大家可以通过共同的0频道听到别人说的话)。第二个参数是要说的内容字符串。一个字符串基本就是一系列字符,通过””定义。注意参数是被逗号隔开的。
这是对你的第一个第二人生代码的总览。下面,你将学习关于分支和变量的知识。
注释
什么是注释?注释就是帮助你理解别人或自己代码的多余说明。它帮助人们了解代码正在做什么,你可能在阅读几个月前的代码时忘记了编码过程,需要用到它。这里只有一种单行注释。如果你需要一个长注释,你需要将多个单行注释并在一起。单行注释使用“//”定义,右边的所有内容是“注释”。注释也被用来忽略掉一行(或多行)代码。它在调试过程中非常有用。
还要说明的是注释帮助人们理解,所以不要注释那些显而易见的内容。一个长代码即使是使用良好的编码排版也容易引起误解,所以不要认为排版了就不需要注释了。
空白
空白是在行行代码间多余的空行。你可以注意到每行最后都有一个分号(;)。这是显示行结束的标志。使用分号,你可以在一行放置多行代码。但是,不推荐这样因为比较难以阅读。另外注意函数和状态块不需要最后的翻好。因为他们在继续其他的工作,分号意味着“这行已经结束了”。当然,你也可以将一行代码分为2行。但是要注意两件事情:
·字符串不能被分隔开;
·函数参数不能被分隔开,一个参数不能在两行出现;
使用空白,你可以有一个便于阅读和理解的编程风格。有一些程序员选择使用的风格,也有一些他们必须遵循的风格:
·分号必须是行尾的标识,除了在注释内;
·如果一行太长你分开了它,那么第二行必须有一个缩进;
·对于每个块(循环,函数等),代码都必须进行缩进;
排版命令是可以用在状态和函数上的(还有循环,以及{}内的内容)。最流行的风格是(可以用LSL脚本编辑器自动排版):
| //Here is a single line comment //Here is a state definition with format one default{ //The code that should be here } //Notice how the '{' is right beside the state name //Here is format number 2 //The format is one I use more, and also the one //a lot of script editors use. I recommend using this one, not //only because it is easy to read, but also because it //is the default format in the LSL script editor //Here is a state definition with format one default { //The code that should be here } //Notice how in this case, the '{' is after the state name //This method makes it generally clearer to see the functions blocks //Also note how the code inside is indented, which helps programmers easily //see where the code blcoks are. |
使用变量
变量保存着大量的数据。你需要使用它们来记录事情。比如,如果你正在做一个步进计数器,你需要记住上一个数值,因此可以保持增加步长。这就需要变量的使用了。变量可以是数字,小数,字符串,和其他LSL(林登脚本语言)所支持的数据类型,诸如vector和rotation。
为了创建变量,首先需要定义。下表列出了一些数据类型:
|
数据类型 |
定义 |
| 整数 | 从-2147483648到2147483647的非小数数值。它用来技术和保存重要数字,因为比浮点型精确。 |
| 浮点数 | 浮点数是有小数部分的数字,没有整数精确。范围在1.175494351E-38 和3.402823466E+38之间 |
| Vector | 向量是一组3个数字,通常用来标识RGB杨色或者xyz坐标。 |
| Rotation | Rotation用来标识回转和名称。包括x,y,z和s数值。 |
| Key | Key用来应用第二人生中的对象,比如用户,一个物体等等。 |
| 字符串 | 一个字符串是一组字符,用做语言交流。 |
| 列表 | 列表是一些变量的集合。 |
下面是个例子:
| integer counter = 0; default { state_entry() { llSay(0, "Hello, Avatar!"); } touch_start(integer total_number) { counter++; string touchtimes = "Touched " + (string)counter + " times"; llSay(0, touchtimes); } } |
这个程序是一个触摸计数器。每次你点击一下立方体(触摸),计数器增加。它告诉你触摸了该物体多少次。
声明变量
变量通过如下格式声明:
[type of variable] [name of variable]
例子:
· integer myNumber
· float hello
· string word534
变量名必须满足如下要求:
·不超过256个字符
·可以由数字和字母组成
·第一个字符必须是字母
给变量赋值
在我们的程序中,我们在声明时赋值。你也可以将声明和定义分开:
integer counter;
counter = 0;
为了设定一个数值,你将它放在等号左边。等号右边是任何有效值。你可以使用如下:
|
操作符 |
定义 |
| + | 相加数值和字符,如thisString = “Hello” + “And Welcome!” |
| - | 相减 |
| * | 相乘 |
| / | 相除 |
| % | 取余(11%3=2) |
| ++ | 增加1 |
| -- | 减1 |
在我们的程序里:
counter = counter + 1;
也可以写作
counter++;
当然,字符串也可以进行加法。如:
| thisString = Hello + Welcome //thisString is equal to Hello Welcome |
注意字符串一定要放在双引号里,以免编译器出错。
在我们程序里有:
| string touchtimes = "Touched " + (string)counter + " times"; |
这里有一个(string)。这个是一个类型转换操作符。它将一个变量转化为另外一个变量。你需要它是因为你只允许使用加减等等操作符来操作相同的变量。它的使用格式如下:
( [type of variable] ) [variable to be converted];
如 string welcome = (string)numberOfTimes;
没种转换都必须显式定义(意思是你必须要清楚写出,除非是一些隐式的转换,如整型到浮点型,字符串到key)。下面是支持显式转换的:
· Integer
§ Integer to String
§ Integer to List
· Float
§ Float to Integer
§ Integer to String
§ Integer to List
· Vector
§ Vector to String
§ Vector to List
· Rotation
§ Rotation to String
§ Rotation to List
· Key
§ Key to List
· String
§ String to List
§ String to Integer
§ String to Float
§ String to Vector
§ String to Rotation
注意当我们使用IISay()的时候我们没有将字符串变量放在括号里,因为我们需要的是字符串代表的值而不是“touchtimes”这个字符串。
“++”和“--”操作符
尽管这两个操作符不需要在右边有等号,它们也可以有。这种情况下它们被视为普通的变量赋值:
myInteger = otherInteger;
但是有一些使用规则:
| integer counter = 0; integer counter2 = counter++; |
这里你可能认为首先counter加1,然后将counter赋值给counter。刚好相反!它首先将counter赋值给counter2,然后counter加1。要首先使counter加1,这样写:
| integer counter = 0; integer counter2 = ++counter; |
最后看一眼程序
程序首先声明一个计数器,赋值为0.每次触摸,增加1。然后声明一个字符串,将其定义为“Touched x time”,这里x等于counter的值。每次touch_start()发生,它就会报告一次该字符串。
