#52003/3/20 13:44:48
贴一个简单教程:
------------------------------------------------------------------
父子脚本系列<一> : 父子脚本基础(OOP)(作者:partical)
在Director中,功能最为强大的可谓称之为其lingo中的父子脚本了,而其中的lingo编程思路即为面向对象的编程(OOP)[Object-Oriented]。使用OOP可以在内存中创建类似现实世界对象的结构。对象是OOP的基础,对于OOP而言应该支持抽象、封装、继承和多态。
1,父脚本和子对象的关系
父脚本就像一个模版一样,表示一个对象的属性和所要执行的程序。当创建一个父脚本的实例时,即生成了一个子对象。这时这个子对象就拥有了父脚本的属性和可执行的程序。
例:创建父脚本(exobj):
property pexample
on new me,aexample
pexample=aexample
return me
end
on example me
if pexample then
put "true"
else if pexample=false then
put "false"
end if
return pexample
end
输入上述代码后,将其属性设为Parent Script,名称为exobj。
打开消息对话框(ctrl+M),输入child1=new(script "exobj",true)此时你就已经创建了一个子对象,名称为child1。(new(script "exobj",true)是一种创建子对象的写法,exobj为父脚本cast的名称,true为变量值[on new me,aexample中aexample的值])
child1子对象是驻留再内存中的,你可以用put child1来观察。
在消息框中再输入child1.example(),此时你会看见消息框中跳出字符串"true",此时是调用了父脚本中的一个函数example,此函数侦测子对象建立时所给变量的值,如果是true则返回字符串"true"反之则返回"false"。
重复上述操作,再创建一个子对象child2,设aexample的值为false,则消息框中将返回字符串"false"。
*一个父脚本可以有多个子对象。
2,祖先
对象具有从其他对象继承行为和属性的能力。lingo中有一个对象属性被称为ancestor(祖先)。一旦一个对象有ancestor属性,消息就会被发送给祖先,反之如果没有处理程序,就会出错。特别要注意的是祖先可以还有祖先,而且消息会一直被发送上去。
例:利用先前的例子作为祖先,再创建一个父脚本(exobj2)
property ancestor
on new me,aexample2
ancestor=new(script"exobj",aexample2)
return me
end
on example2 me
me.example()
return me
end
ancestor(祖先)属性变量是一定要声明的。
ancestor=new(script"exobj",aexample2)是将ancestor属性变量初始化。
如此一来,下边所有要访问ancestor都需要用me,即me.example()是调用了祖先脚本exobj,它是通过ancestor访问的。
再消息框中,你先输入child3=new(script"exobj2",true)建立一个子对象,再输入child3.example2(),这时会输出值"true",这是因为子对象使用了它的一个函数example2,而example2则是利用祖先调用了exobj的过程,才会输出"true"值来。如果在example2过程中再加入别的语句,比如 put(the stage).width;put "ok"等,它也都会全部执行。
通过该例子,我们可以很简单的创建一个带有陨石的太空场景,祖先可以创建精灵通道位置、属性(ink,puppet,member)等,而父脚本则可以设置精灵的位置、移动速度等情况,你可以创建多个父脚本来分别定义多种状态的陨石,再用多个子对象来调用。
父子脚本系列<二> : DIY OOP(作者:Zac Belado 翻译:partical)
首先,创建一个帧脚本,将它放在第五帧的位置,目的是为了在该帧上循环。
on exitFrame
Go to the frame
end
什么是对象?
这是最基本的,对象就是让你在director中写一组类(一群属性的集合)的代码,它能让你在多种情况下修改而使用。甚至可以写一段代码在你的director项目中到处、重复使用它。现在让我们看一个十分有针对性的例子。创建一个增加值到字段中的对象,这个对象将告诉你什么字段将被记住,因此不必去追踪它。这个对象将添加自己到the actorlist中,所以这是在我们的影片里最优先的操作:
on startMovie
set the actorList to []
end startMovie
如上代码只是预防当对象出现如下问题时the actorList被堵塞的写法:
1)在你编写时可能会出现问题,旧版本的对象在修改后还保持着当时的代码(还未编译)。
2)我们不希望许多对象都在同一个字段上运行,这样会搞混的。
什么是the actorlist?
根据lingo帮助中的描述:它是当前影片中所有子对象的集合(列表)。
the actorlist是一个可以放置对象以至于在任何时候用于发送、接收stepframe事件的列表,甚至当转至其他影片时对象仍保留在这个表中。或者更简单的说,它是一个存放对象的地方,当你想随时使它们执行或在每帧时执行就可以用它。你可以用所有列表的属性来用在它的身上。它是用来组织、间接、跟踪对象的非常好的方法。 写对象第一个你所要回答的问题就是如何合理的保存你的字段(或者是数字)以便于对象的访问。每个对象都可以设置一些属性;这些属性都是可修改的,只对该对象有效,并且在运行时一直有效。可以将它们认为是仅用于该对象的全局变量。所以我们可以确定属性是绑定在一个字段上的。
打开script窗口,设为父脚本(parent script)取名为“numberCruncher”,写入:
property myField
这条语句告诉lingo编译器你想为这个名叫myfield的变量开辟一个内存空间,并于名为“numberCruncher”的父脚本进行关联。(将script的属性设为父脚本,这是非常重要的)
专业术语的开始
为什么刚才的script是一个父脚本?
父脚本这个名词是用于director中的,它用来产生一个新的对象(子对象)。可以把它看作为是一个用来创建对象的模版。当你用父脚本创建了一个对象时,也要将它的属性和方法中的信息传给所创建的对象,这样才能使创建出来的对象具有它(父脚本)本身的属性和方法。
现在我们要创建一个方法(父脚本),并且产生出对象(子对象)。
on new me, theFieldName, defaultvalue
-- 将字段名称存放在对象的属性里
set myField to theFieldName
-- 将字段默认值存放在对象的属性里
set the text of field myField to string (defaultvalue)
-- 将对象添加到actorlist列表中
add the actorList, me
-- 返回值
return me
end new
为了创建对象,要在startMovie句柄加入:
on startMovie
set the actorList to []
--创建一个对象名叫“thisobject”
set thisObject to new (script "numberCruncher", "numbers", 0)
end
在许多相同的地方,你可以用一个新的关键字来创建一个新的位图或文本域,也照样可以创建出新的对象来。在我们的例子里,director将把对象的信息放置到“thisobject”这个变量里。此时这段信息即为对象在内存中的位置。就像:
在这个例子中,new方法只是十分简单的传递了三个变量(对象信息,文本域的名称,整形数值),theFieldName改变新创建的文本域卡司的名称,defaultvalue改变文本域里面的内容。
在这其中,仅有一件事时要注意的,就是要记得在方法后面加上“me”,这是让这个对象知道哪里发送请求给不同的方法。 set thisObject to new (script "numberCruncher", "numbers", 0)
上述语句符合父脚本的创建结构:
on new me, theFieldName, defaultvalue
现在我们已经成功的创建了一个对象,可以让它作写事情了。
你是否记得我们已经成功的将对象的信息添加到the actorList里了,所以我们可以为这个对象添加stepframe方法了。
on stepFrame me
-- 从这个对象的文本域中取出文本
set thisText to the text of field myField
-- 将文本转化为整形值
set thisText to value (thisText)
-- 将整形值加1再转为字符串形赋给文本域
set the text of field myField to ?
string (thisText + 1)
end
在the actorList列表中的这个对象,director将发送一个stepframe方法给它,重新创建对象,这时它将会独立的运行而不须控制