首页 > 网站 > 媒体动画 > 正文

Authorware类和函数:authorware7程序设计基本的教学文章--脚本函数(1)

2024-09-08 19:24:40
字体:
来源:转载
供稿:网友

3.5  脚本函数

脚本函数(script function)是由设计人员利用aws自行编写的函数,与代码片段相比,脚本函数具有更加完备的功能。使用脚本函数就如同使用系统函数一样,可以向脚本函数传递参数,或者接收脚本函数的返回值。通过将常用的过程(例如3.4节中介绍的常用字符串处理过程)定义为脚本函数,可以大大提高设计人员的开发效率。

脚本函数可以有3种存在形式:内部脚本函数、外部脚本函数和字符串脚本函数。

与创建代码片段相比,创建脚本函数要稍微复杂一些,但是设计人员付出的这种努力会带来大量的回报。代码片段就像是预定义的宏,需要在程序中展开代码才能进行工作,而脚本函数是真正的函数,其实现细节被封装在【脚本函数】设计图标内部,便于对代码进行统一管理。设计人员可以随时补充和完善脚本函数的功能,只要保证函数接口(参数和返回值)不发生变化,这些修改工作不会给程序中的其他内容带来任何不利影响。

3.5.1  内部脚本函数

内部脚本函数存在于【脚本函数】设计图标之中。【脚本函数】设计图标并不是一种新的设计图标,而是运算设计图标的一种新形式。可以通过以下步骤创建一个【脚本函数】设计图标。

(1)向流程线上拖放一个运算设计图标,并以所需函数名对运算设计图标进行命名。该设计图标名必须是惟一的,不能与其他设计图标同名,但是可以与系统函数同名。现在将其命名为“box”。如图3-38所示。

(2)执行modify>icon>properties菜单命令,打开运算设计图标属性检查器,在属性检查器中打开contains script function复选框,将当前运算设计图标定义为【脚本函数】设计图标,如图3-39所示。

(3)单击属性检查器中的【ok】按钮。此时运算设计图标就变为【脚本函数】设计图标,如图3-40所示。此时设计图标的外观发生了变化。双击【脚本函数】设计图标打开【运算】窗口,可以像使用普通运算设计图标一样向其中输入代码。向“box”运算窗口中输入以下代码:

repeat with i:= 1 to 100

    box(1, 0, 0, i, i )

    i:=i+1

end repeat

图3-39  对运算设计图标进行属性设置

图3-40  【脚本函数】设计图标创建完毕

就创建了在【演示】窗口中绘制50个矩形这个简单的脚本函数。

现在运行程序不会在【演示】窗口中看到任何矩形。【脚本函数】设计图标是一种特殊的【运算】设计图标,它与普通【运算】设计图标的不同之处在于:当程序执行到流程线上的脚本设计图标时会略过它,并不自动执行其中的代码。脚本函数只能通过系统函数callscripticon进行调用。现在向【设计】窗口中添加一个【运算】设计图标,如图3-41所示,向“call box”设计图标中输入函数调用语句:

callscripticon(@"box")

就可以调用脚本函数box,在【演示】窗口中绘制矩形。由于authorware不会主动执行“box”设计图标,因此两个设计图标的相对位置关系并不重要:将“call box”设计图标放置在“box”设计图标之前会得到同样的运行结果。

对应的范例程序是chapter03文件夹下的scripticon-box.a7p。

 

    

图3-41  调用脚本函数

与系统函数相比,脚本函数同样可以具有参数和返回值。看一下系统函数callscripticon完整的调用语法:

result:= callscripticon(iconid@"icontitle" [,args] [,byvalue] [,owner])

其中惟一的必选参数是【脚本函数】设计图标的名称。可选参数args就是向被调用的脚本函数传递的参数,该参数可以是各种类型,包括从最简单的字符串类型到复杂的多维列表。脚本函数通过名为args的图标变量来接受传递过来的参数,通过名为result的图标变量返回执行结果。

例如要创建一个在【演示】窗口中随机绘制多个矩形的脚本函数randombox,首先为其创建图标变量args@"randombox",然后通过参数args指定绘制次数:

repeat with i:= 1 to args@"randombox"

--随机挑选一种覆盖模式

    setmode(random(0,4,1))

--随机设置边框的颜色

    setframe(1, rgb(random(0,255,1), random(0,255,1), random(0,255,1)))

--随机设置填充颜色

    setfill(1, rgb(random(0,255,1), random(0,255,1), random(0,255,1)))

--随机设置矩形的位置和大小并进行绘制

    box(random(1,8,1), random(1,windowwidth,1), random(1,windowheight,1),﹁

                 random(1,windowwidth,1), random(1,windowheight,1))

end repeat

在上述过程中,系统函数random()根据【演示】窗口宽度(windowwidth)和高度(windowheight),随机决定矩形的大小、模式、颜色、位置和边框,然后由系统函数box在屏幕中进行绘制。图标变量args在这里决定了循环执行的次数,即绘制矩形的数目。在一个【运算】设计图标中输入以下函数调用语句,可以实现在【演示】窗口内部随机绘制10个矩形的目的。

callscripticon(@"randombox ", 10)

程序流程和运行结果如图3-42所示。接下来继续创建两个脚本函数:randomcircle和randomline,分别用于随机绘制圆形和线段。

    

图3-42  向脚本函数传递参数

--以下过程位于“randomcircle”设计图标中

repeat with i:= 1 to args@"randombox"

    setmode(random(0,4,1))

    setframe(1, rgb(random(0,255,1), random(0,255,1), random(0,255,1)))

    setfill(1, rgb(random(0,255,1), random(0,255,1), random(0,255,1)))

    box(random(1,8,1), random(1,windowwidth,1), random(1,windowheight,1), ﹁

random(1,windowwidth,1), random(1,windowheight,1))

end repeat

 

--以下过程位于“randomline”设计图标中

repeat with i:= 1 to args@"randomline"

    setmode(random(0,4,1))

    setframe(1, rgb(random(0,255,1), random(0,255,1), random(0,255,1)))

--随机挑选箭头样式

    setline(random(0,3,1))

    line(random(1,8,1), random(1,windowwidth,1), random(1,windowheight,1), ﹁

random(1,windowwidth,1), random(1,windowheight,1))

end repeat

然后在【运算】设计图标之中就可以通过以下函数调用语句,调用上述脚本函数开始绘图:

callscripticon(@"randomcircle",10)

callscripticon(@"randomline",10)

脚本函数调用语句不必手工输入。在创建新的脚本函数之后,函数面板中script icons类别下就会增加新的函数,如图3-43所示。双击函数名称,就可以直接将函数调用语句粘贴到【运算】窗口中,然后再根据需要补充调用参数就可以了。

 

图3-43  新的函数

chapter03文件夹中的范例程序randomdraw.a7p演示了上述3个脚本函数的使用:如图3-44所示,单击【continue】按钮,就可以在【演示】窗口中分别看到10个矩形、10个圆形和10条线段。

     

图3-44  范例程序randomdraw.a7p


3.5.2  变量与参数

上述脚本函数中都使用了计数变量i,该变量属于整个程序,而并非某个特定的脚本函数所有,任何设计图标都可能使用该变量。为避免脚本函数和其他过程之间相互影响,应该在脚本函数中尽量使用图标变量。

本节将3.4.3.2节中介绍的常用字符串处理过程转换为脚本函数,并藉此介绍如何在脚本函数中处理变量和参数。

对于reverse过程,在将其改写为脚本函数reverse时,除了利用图标变量args@"reverse"接收准备处理的字符串参数(string)之外,还应该利用图标变量result@"reverse"和i@"reverse"分别替换原有的变量result和i(result@"reverse"同时也作为脚本函数reverse的返回值):

result@"reverse":= ""

repeat with i@"reverse":= 1 to charcount(args@"reverse")

  result@"reverse":= substr(args@"reverse", i@"reverse", i@"reverse")^ ﹁

result@"reverse"

end repeat

这样就将脚本函数本身的数据封装在脚本函数内部,因为上述图标变量在脚本函数之外通常是不可见的。以后就可以通过函数调用语句:

result:= callscripticon(@"reverse", "authorware 7.0 is coming")

对脚本函数reverse进行调用,并将函数返回的结果"gnimoc si 0.7 erawrohtua"存储到全局变量result之中。变量result@"reverse"和result之间互不影响。

实际上在【脚本函数】设计图标之外仍然可以访问图标变量i@"reverse",但此时该变量的名称已经非常明显地告诉设计人员:这是一个仅仅属于“reverse”设计图标的变量。

按照类似的方法,可以将encode、decode、wordreverse和casereverse过程分别转换为脚本函数。

--以下是脚本函数encode

result@"encode":= ""

repeat with i@"encode":= 1 to charcount(args@"encode")

    ascii@"encode":= string(code(substr(args@"encode",i@"encode", i@"encode")))

    reverse@"encode":= ""

    repeat with j@"encode":= 1 to charcount(ascii@"encode")

      reverse@"encode":= substr(ascii@"encode", j@"encode", j@"encode")^ ﹁

reverse@"encode"

    end repeat

    result@"encode":= result@"encode"^reverse@"encode"^" "

end repeat

脚本函数也可以互相调用。由于前面已经定义了具有反转字符串功能的函数reverse,实际上可以将函数encode简化为:

result@"encode":=""

repeat with i@"encode":=1 to charcount(args@"encode")

    ascii@"encode":=string(code(substr(args@"encode", i@"encode", i@"encode")))

    reverse@"encode":=callscripticon(@"reverse",ascii@"encode")

    result@"encode":=result@"encode"^reverse@"encode"^" "

end repeat

但是为了在后续章节中能够更好地描述各种脚本函数的工作方式,本书并没有采用上述简化代码。

--以下是脚本函数decode

result@"decode":= ""

repeat with i@"decode":= 1 to wordcount(args@"decode")

    ascii@"decode":= getword(i@"decode", args@"decode")

    reverse@"decode":= ""

    repeat with j@"decode":= 1 to charcount(ascii@"decode")

      reverse@"decode":= substr(ascii@"decode", j@"decode", j@"decode")^ ﹁

reverse@"decode"

    end repeat

    result@"decode":= result@"decode"^ char(reverse@"decode")

end repeat

现在脚本函数便于调用的优势已经凸显出来,多次调用脚本函数encode,可以非常方便地对一个字符串进行多次加密,从而获得较为理想的加密强度。

string:= "authorware 7.0 is coming"

--通过3次调用encode函数,对变量string的内容进行3重加密

repeat with i:= 1 to 3

    string:= callscripticon(@"encode",string)

end repeat

--必须通过3次调用decode函数,才能对变量string的内容完全解密

repeat with i:= 1 to 3

   string:=callscripticon(@"decode",string)

end repeat

函数encode并不是一个商业化的加密程序,它的作用仅仅是示范如何对字符串进行处理。不要使用它对同一字符串进行5次以上的加密,因为每次加密的结果都会以指数方式增长,很容易就会超出变量string的存储容量(512kb)。

--以下是脚本函数wordreverse

result@"wordreverse":= ""

repeat with i@"wordreverse":= 1 to wordcount(args@"wordreverse")

result@"wordreverse":= getword(i@"wordreverse",args@"wordreverse")^" "﹁

^result@"wordreverse"

end repeat

result@"wordreverse":= substr(result@"wordreverse", 1, ﹁

charcount( result@"wordreverse")-1)

 

--以下是脚本函数casereverse

result@"casereverse":=""

repeat with i@"casereverse":=1  to charcount(args@"casereverse")

 result@"casereverse":=result@"casereverse"^test(code(substr(﹁

args@"casereverse", i@"casereverse", i@"casereverse"))>64&code(substr(﹁

args@"casereverse", i@"casereverse" , i@"casereverse" ))<91, ﹁

lowercase(substr(args@"casereverse", i@"casereverse" , ﹁

i@"casereverse" )),(test(code(substr(args@"casereverse", i@"casereverse" , ﹁

i@"casereverse" ))>96&code(substr(args@"casereverse", i@"casereverse" , ﹁

i@"casereverse" ))<123, uppercase(substr(args@"casereverse", i@"casereverse" ,﹁

i@"casereverse" )),substr(args@"casereverse", i@"casereverse" , ﹁

i@"casereverse" ))))

end repeat

到目前为止这些脚本函数都只接收1个参数。从系统函数callscripticon的使用语法也可以看出,只能向脚本函数传递一个参数args。由于一个列表型变量可以包含多个元素,每个元素的值和数据类型也可以不同,因此可以将需要处理的多个数据集中放置在一个列表型变量中,再将该列表型变量作为参数传递给脚本函数,这就达到了向脚本函数传递多个参数的目的。

同理,如果将脚本函数设计为返回一个列表型变量,那么脚本函数实际上也能返回多个(种)值。

字符排序过程sortchar实际上需要使用两个参数:string和ascending,前者是待排序的字符串,后者指定排序方式(升序或降序)。现在就为“sortchar”【脚本函数】设计图标创建列表型变量args@"sortchar",通过它使脚本函数sortchar能够接受两个参数。

--以下是脚本函数sortchar

result@"sortchar":=""

charlist@"sortchar":=[]

ascending@"sortchar":=args@"sortchar"[2]

repeat with i@"sortchar":=1 to charcount(args@"sortchar"[1])

    addlinear(charlist@"sortchar", substr(args@"sortchar"[1], i@"sortchar", ﹁

i@"sortchar"))

end repeat

sortbyvalue(charlist@"sortchar",ascending@"sortchar")

repeat with i@"sortchar":=1 to charcount(args@"sortchar"[1])

    result@"sortchar":=result@"sortchar"^charlist@"sortchar"[i@"sortchar"]

end repeat

上述代码中以粗体显示的代码是获取第2个参数的语句。现在可以通过两种方式调用sortchart函数:

string:= "authorware 7.0 is coming"

--对变量string中的字符串以降序排序

string1:= callscripticon(@"sortchart", [string, 0])

--对变量string中的字符串以升序排序

string2:= callscripticon(@"sortchart", [string, 1])

对函数sortchar中的粗体代码进行修改,可以实现更为灵活的参数传递。例如可以将函数sortchar中第2个参数设置为可选参数,如果调用者没有给出排序方式,则函数sortchar自动以升序方式排序。实现代码如下所示:

-- ascending@"sortchar"的默认值为true,如果参数列表存在第2个元素,则以该元素

--指定排序方式

if listcount(args@"sortchar")>1 then

    ascending@"sortchar":=args@"sortchar"[2]

  else  ascending@"sortchar":=true

end if

现在以下两种函数调用方式是等价的(对变量string中的字符串以升序排序):

string1:= callscripticon(@"sortchart", [string])

string2:= callscripticon(@"sortchart", [string, 1])

可以通过以下代码进一步拓宽参数的使用方式:

if listcount(args@"sortchar")>1 then

    ascending@"sortchar":=args@"sortchar"[2]

else  if  listcount(args@"sortchar")=1 then

       ascending@"sortchar":=true

     else

--如果参数不是一个列表,则将其转换为列表再进行处理

       args@"sortchar":=list(args@"sortchar")

       ascending@"sortchar":=true

end if

现在下列三种函数调用方式都是等价的。

string1:= callscripticon(@"sortchart", [string])

string2:= callscripticon(@"sortchart", [string, 1])

string3:= callscripticon(@"sortchart", string)

以下是脚本函数sortchar的最终版本:

result@"sortchar":=""

charlist@"sortchar":=[]

if listcount(args@"sortchar")>1 then

    ascending@"sortchar":=args@"sortchar"[2]

else  if  listcount(args@"sortchar")=1 then

       ascending@"sortchar":=true

     else

       args@"sortchar":=list(args@"sortchar")

       ascending@"sortchar":=true

end if

repeat with i@"sortchar":=1 to charcount(args@"sortchar"[1])

    addlinear(charlist@"sortchar", substr(args@"sortchar"[1], i@"sortchar", ﹁

                    i@"sortchar"))

end repeat

sortbyvalue(charlist@"sortchar",ascending@"sortchar")

repeat with i@"sortchar":=1 to charcount(args@"sortchar"[1])

    result@"sortchar":=result@"sortchar"^charlist@"sortchar"[i@"sortchar"]

end repeat

读者可能已经注意到这些脚本函数总是首先将图标变量result的内容清空。这一操作是必需的,否则在下次调用脚本函数时,上次的调用结果将继续参加下次的处理过程。

chapter03文件夹下的范例程序scripticon.a7p演示了这些脚本函数的功能。如图3-45所示,读者可以在演示窗口上方的文本输入框中自由输入字符串,然后单击不同的按钮调用脚本函数对输入的字符串进行处理。注意在单击encode按钮后,才能使用decode按钮对加密后的字符串进行解密,并且在单击decode按钮之前,其他按钮处于禁用状态。

图3-45  范例程序scripticon.a7p

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表