Mud 版 (精华区)

发信人: anderson (危峦快剑), 信区: Mud
标  题: LPC中文介绍(12)
发信站: 紫 丁 香 (Wed May 13 19:45:20 1998), 转信

Subject: 数据类型: object(转寄) 
X-Forwarded-By: start (酒虫) 
X-Disclaimer: 天地创造 对本信内容恕不负责。 

发信人: maht (Trill), 信区: creator 
标 题: 数据类型: object 
发信站: 天地创造 (Wed Nov 12 16:57:36 1997), 转信 

第六章 数据类型:object 

第一节 序言 
这是 Lpc 入门的最后一节,到现在,如果前面几章都读过了,你应该 
能写出一些简单的 object,比如 room 。而且能给 room 写一些简单的 
特写,通过添加一些函数。 

第二节 作为数据类型的 object 
2.1 数据类型 object 
在这一章中,你将了解更复杂一些的数据类型:object。一个 object 
类型的变量是指向一个装入内存的真正存在的 object 。象别的数据类 
型一样,你用 object 后面跟一个变量名来声明:

object oTest; 

它有些特殊,它几乎没有什么操作符可以作用 object 这种数据类型。 
其实,也是的,让一个 room / npc 那是什么东西?而且一般的 efun, 
比如 write(), say() 也是不能操作 object 的,但是你会了解到,对于 
object 这中数据类型,有一些很重要的 efun。 

2.2 efun: this_object() 
这个 efun 返回一个 object,当前被执行的函数所在的那个 object。 
也就是说,在一个文件中,this_object() 提交的 object 是这样的: 
如果这个文件写的 object 如果自己被复制装入内存单独存在,那么就 
是这个 object,如果这个文件被继承了,那么就是继承的文件进行上一 
个过程,看它是不是单独存在,也就是没有再继承的文件了。可能有些 
难也理解,让我们看这个例子,比如你写了一个 object 叫 name.c,它 
被 player.c 继承了,那么 this_object() 实际返回的是 player.c 那个 
object,而不是 name.c 。我们再来看一个使用 this_object() 的实例: 

你想让一个 npc 走到一朵花旁边闻一下,但是条件是那个 npc 能自 
由运动,比如:没有晕倒,没有在战斗。 
你可以这么做: 

void eventSmellFlower() 

if( this_object()->can_act() ) 

write( this_object()->query( "name" ) + "走到花的边上闻了闻。\n" ); 
this_object()->add( "kee", 5 ); 



can_act() 在 npc.c 里面是没有定义的,而且可能它继承的任何 object 
中也没有定义。那么,如果写成这样: if ( can_act() ),driver 没有 
在当前文件和继承的所有文件里面找到 can_act(),那就会有个编译错 
误的,但是 this_object()->can_act() 就不会出现这样的错误,就算是 
can_act() 根本不存在,那么结果是返回 0 ,就是 if 测试的表达式的 
结果是假的。这样有人会问:那这个 efun 有必要存在吗?driver 在 
编译是会自动搜索它继承的所有 object,不是自然有 this_object 了 
吗? 确实,但是有时,这个 object (暂时叫做 A )会被别的 object (B) 
继承的,别的 object (B)可能会有这个函数,而且有时候 B 可能会重载 
A 和 A 继承的函数,而你不想让那些重载的函数失去作用,那么就采用 
this_object()-> 的形式。

2.3 调用别的 Object 里面的函数 
这就是我们引入 object 这种数据类型的最大好处了。它能让我们调 
用别的 Object 里面的函数。在上面的例子中,我们可以知道当前的 
Object 能不动。下面的例子,你可以增加一个 player 身上的钱。 
调用别的 object 里面的函数,可以用下面两种方法: 

object->function(parameters) 
call_other(object, "function", parameters); 

example: 
this_player()->add_money( "silver", 5 ); 
call_other( this_player(), "add_money", "silver", 5 ); 

在某些时候( 很不精确的说法 ),mud 是一个由玩家命令触发的函数 
调用的链式反应。当一个 player 触发了一个函数调用链,那么这个 player 
就是 eufn this_player() 返回的那个 object。就是说,因为 this_player() 
依赖那个触发事件序列那个 player,那么你应该小心的使用 this_player() 
这个 efun,如果你把 this_player() 放在一些函数,这些函数别调用通 
常可能是 driver 来调用的,或者不一定是 player 来触发的,那么使用 
this_player() 最好不要出现在那些函数里面。比如 create(), setup()。

2.4 lfun: init() 
在任何时候,一个“活的”的 object,接近一个 object (进入一个新 
房间,或者另一个 object 进入同一个 room ),init() 将自动被调用。 
利用这个,你可以写一些自动触发的效果,比如,你进入一家客栈,小 
二和你打招呼,看看这样一个例子: 

void init() { 
::init(); 
if ( this_object()->can_act() ) 

this_object()->eventGreet( this_player() ); 



eventGreet() 可以是下面那样: 

void eventGreet( object ob ) 

if ( !ob || environment( ob ) != environment( this_object() ) ) 

return ; 

else 

write( "小二说道:这位客官,您想要点什么?\n" ); 



efun environment() 返回一个 object 所在的环境,比如一个 player 所 
在的 room,一把剑所在的 player 等等。 

2.5 在你的 room 里面放入一个 object 
看下面的一个例子,你可以在一个 player 所在的房间放入一条蛇: 

void test() 

object env, snake; 

env = environment( this_player() ); 
if ( objectp( env ) ) 

snake = clone_object( "/clone/monster/snake" ); 
if ( objectp( snake ) ) 

snake->move( env ); 


}

例子中用到了一个 efun objectp ,这个 efun 判断传入的参数是不是一 
个真实的 object,如果是就返回真,否则就是假。efun clone_object() 
则试者把一个文件调入内存,变成一个 object。最后一个函数 move, 
这个显然不是一个 efun,但是总的来说,一般会调用 efun move_object 
把一个 object 放到另一个 object 的内部。 

小结 ( 也是 lpc 入门的小结 ) 
在本章,我们了解作为数据类型的 object。同时也了解一些 efun: 
this_object(), this_player() environment() clone_object() objectp() 
的使用。还有 init() 这个特别的函数的使用。 
到了现在,你应该有足够的知识编写一些漂亮的东西了。当然,我强 
调过一点,你必须了解你为之开发的 mud,了解它的 mudlib,它的风格, 
多多阅读 mud 带的文档和说明。当然只是了解 lpc 入门 介绍的东西, 
对 lpc 的了解是很基础的,如果你想更进一步,最好的方法是,多读 
程序,多写程序,积累经验。Lpc 只是 C 的很小的一个子集,有一点点 
的特殊的东西,是很容易掌握的。 

maht( trill ) 
11/12/97 3:53PM 
trill@XO Team 

--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.226.67]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.207毫秒