背景:
阅读文章

数据类型:object

[日期:2007-05-05] 来源:  作者: [字体: ]

第一节  序言
  这是 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 的很小的一个子集,有一点点
的特殊的东西,是很容易掌握的。

尊重作者 转载请注明出处52mud.com

收藏 推荐 打印 | 录入:sbso | 阅读:
相关内容      
本文评论   [发表评论]   全部评论 (0)
内容推送
52mud提供
一起回忆泥巴游戏QQ群68186072
52mud官方微信公众平台
热门评论