女子十二乐坊mp3下载:如何设计场景?

来源:百度文库 编辑:杭州交通信息网 时间:2024/04/30 08:34:18

房间是构成这整个世界的要素之一,在此我们提供了一个房间的标准物件来让所有的房间继承。而如同其他的物件一般,你需要写一个 create() 来设定房间中的叙述、出口、物品、生物等等。这里,我喜欢说你用 create() 这个函式来赋予这个房间的属性。一般来说,要建造一个简单的房间,你只要赋予它基本的属性即可。当然,我们不认为一个区域中几十个房间没有任何的机关或秘密,是个会吸引玩家一游的好地方。

  下面,提到了一些建造房间所需要留意的事项,也会配合一些例子来说明。

  一、基本篇

  一个基本的房间,要有 short <短叙述> 、 long <长叙述>、 exits <出口>

  1. 当你在写一个房间的 long <长叙述>时,其格式为:

  set("long", @LONG
  房间的叙述.......
  LONG
  );

  其中 @LONG 和 LONG 是互相对应的,你可以用任何字接在 @ 后面,但是前后两个字一定要一样,这样系统才能判别,而房间的叙述写完时,一定要换行后再接第二个 LONG ,且同一行不能再有其他任何的字元,不然系统无法判定叙述是否该结束了,会造成编译时的错误。

  而为求区域看起来外观上整齐、统一,房间的长叙述中每一行的长度必须一样,而一行的长度建议为 29 到 32 个中文字,约占萤幕的三分之二。并且一个房间的叙述最好不要低於三行,区域各个房间的叙述重复性降到越低越好,这样你的区域看起来才不会太过阳春。当然,有时候为了某些目的,比如一个迷宫,你可能会相邻的几个房间都用到一样的叙述,那自然不在此限。

  2. 一个房间的出口则以下列格式赋予:

  set("exits", ([
  "方向" : "连接到的房间之档名",
  ...........
  ]);

  在这里,为了一个以后区域开放后搬移目录的便利性,建议采用__DIR__ 这个由系统提供的巨集来写路径,比如说:

  "west" : __DIR__"path3",
  和
  "west" : "/u/d/davidoff/goathill/path3",

  是完全一样的。但前者显然在以后目录的搬移上方便的多。而在下面会提到设定房间中的物品或生物时,也建议采用这种方式写作。

  3. item_desc 这是用来设定个别景物的描述,当玩家用 look 这个指令时就会作用。其格式为:

  set("item_desc", ([
  "景物名称" : "景物叙述",
  ...........
  ]);

  其中景物叙述可以是字串或是一个 function ,所以你可以利用这个功能加以变化,当玩家 look 一个景物时,可能看到叙述,也可能发生一些特殊的事件,而你就可以在被呼叫的函式中写下这些事件。

  4. objects 可以让这个房间在每次 reset 时载入某些生物或某些物品:

  set("objects", ([
  "物品或生物的档名" : 数量,
  ...........
  ]);

  如同前面所提到的,建议采用 __DIR__来编写你的路径,而数量则要用整数。

  5. 要为这个房间添上门户时,记得前面必须先 #include 。而格式为:

  create_door("出口方向", "门的名称", "进入方向", 预设状态);

  比如说,这里明显的出口有 west、east 和 up。 而你要让西边有一个关上的红木门,你可以这样写:

  create_door("west", "红木门", "east", DOOR_CLOSED);

  当玩家进入这个房间时,他会看到:这里明显的出口有 east 和 up。

  而当他 look west 时,会看到:这个红木门是关上的。

  其他的一些属性,你可以参考 /doc/build/room_prop 或是读一下标准物件的 room.c。也建议你可以多用 more here来观看一间特殊的 room。

  二、进阶篇

  要让你的区域中富有变化,生动有趣,除了文字叙述的丰富度以外,你更可以利用 init() 这个函式为你的房间增加一些「机关」或「秘密」。

  这里,先让我们了解一下 init() 的用途为何,和为什麽要用到它。每一个房间的 create() 只有当 reset 时才会被呼叫到,而 init() 则是在 B 物件进入到 A 物件时都会呼叫到 A物件的 init() 。看到这,你应该可以看出差别了,我们希望当一个物件(此处较多是玩家)进到一个房间时,能够经由某个动作启动这个房间的机关的话,自然是利用 init() 来编写。

  一般的使用方式,是在 init() 中利用 add_action() 来呼叫你写的函式,其格式为:

  add_action("function type", "action");

  function type 即是被呼叫的函式名 action 是启动的动作

  而你就可以将被 action 启动后要发生的事,都写在被呼叫的函式里面。理论上来说,利用这个方式我们可以做到任何事,当然,能不能达成就看写程式的功力了。下面举个简单的例子:

  void init()
  {
  add_action("do_pick", "pick");
  }

  int do_pick(string arg)
  {
  object me;

  me = this_player();
  if ( !arg || ( arg != "flower" ) ) return notify_fail("你要摘什麽?\n");

  else if ( random((int)me->query("kar")) < 7 )
  message_vision("$N将花摘了下来,但一不小心被刺了一下。\n", me);
  else message_vision("$N摘下一朵美丽的血红色鲜花。\n", me);

  return 1;
  }

  当玩家利用 pick 这个指令时就会呼叫到 do_pick() 这个 function,而启动了这个房间的机关。

  这里特别提到一点,一个简单的 room 我们为了使记忆体的使用量降到最低,会在 create() 最后加上一行 replace_program(ROOM); 。这是因为在房间的标准物件中有定义了如 init() 等其他的函式,而一个简单的房间根本没有用到,所以我们用 replace_program() 来将原本的被继承的标准物件「重置」(或说取代)掉,但是一旦房间中用到了 init() 来编写时,就绝对不可以用 replace_program(),因为系统届时找不到 init() 便会随便呼叫一个记忆体中的位址而随便传进一些乱七八糟的东西,情况严重时,甚至可以让整个 mud crash。但是,我们自不可因噎废食,该用的时候还是要用,这些应该是一个好的程式写作人员自己必须留意的,发生状况要自己负责。

  三、建议

  如果你玩过 mud 的话,应该对 mud 组成一个世界的方式相当熟悉,没错,我们就是用一个个的房间(room)来构成这个虚拟的世界,这里我们称「房间」只是传统的 mud 的称呼,因为早期的 mud 全名是 Multi-User Dungeon,Dungeon 就是「地牢」的意思,因此用房间来称呼地牢的最小单位而沿用至今。

  当然,我们现在的 mud 早已脱离地牢的时代,而是一个没有限制的创作空间,如何将你想像中的人、事、地规划成以房间为单位的舞台,就看你的经验和功力了, 通常 mud 并不硬性规定一个房间跟另一个房间的距离、位置等关系,而是根据实际需要而决定房间的连结方式。不可否认的,大多数巫师在从事区域的创作时都会或多或少加上距离跟位置的考量,但是在此仍然要提醒一下,为了位置跟距离的关系而制作的房间是不具意义的。

  建造房间,首先你必须先自己规划一个「区域」的构想,我们通常把一个村庄、洞穴、城镇等地理上能够明确区隔其范围的单位称为一个区域(area),理想的区域设计,是将所有该区域用到的程式放在同一个目录,并且和其绝对路径无关,可以随时挂上或搬移到其他的目录下,因为区域是一个独立的地理单位,具有一致的风格跟设定,对于大多数 mud 的管理者而言都希望万一因为区域的扩展而有需要移动或整理现有区域时,能不必一个个地去修改档案,能够配合管理者要求的巫师,自然就会受到欢迎。

  当你有了构想之后,相信很多巫师会用「画地图」当成第二步,根据我的观察,一个用这种方法写出来的区域通常会有太多不必要的房间,因为画地图时往往会不自觉地将房间想像成「具有相同面积的方块」,因而大量增加了房间的个数,你如果不信,可以试著比较接下来我所建议的方法,看看哪一种方法会有比较多的房间。

  我所建议的方法是「身历其境」的创作方式,当你构想好一个区域大致的内容之后,可以先写出这个区域的入口,想像你是第一个「发现」这个地方的探险者,然后跟著你的想像力所至,开一个出口到下一个房间,继续探险,千万要注意的是:

  不要画地图,甚至想像中也不要用「空中俯瞰」区域的方式去设计你的区域,因为一个探险者是很难有机会俯瞰他发现的区域的,mud 在空间概念上较倾向于冒险游戏而非角色扮演/模拟游戏。

  写完一个房间的叙述再写下一个,不要用 roommaker造出空房间之后就急著连接出口到下一个房间,因为这样到最后往往你会需要苦思半天才能想出一些无聊的叙述填满你用 roommaker 造出来的一堆多余房间,当你发现不知道要在一个房间的叙述里写什么的时候,就表示这个房间其实是多余的。

  让你的想像力引导你的创造力,不要因为觉得一座城堡「应该」有四座塔楼,而写出你的故事中根本不必出现的场景,或者是因为一条长廊「应该」比国王的大厅长很多而用五、六个房间来「堆砌」这样的场景,要记得每间房间的存在都需要耗费电脑的一些资源去储存,浪费太多的资源在无意义的场景上将使你的区域在难以过关。

  适当地使用「动作」连接你的场景,例如有一棵树可以爬上去,你可能开一个 up 的出口直接连到树上的房间,这时候如果花点心思,让使用者必须从环境的叙述中发现提示,如树旁消失的脚印,树皮新近剥落的痕迹等引导玩家发现一个 climb 的动作,不是能使你的区域更有内容吗?

  不过要提醒一些懒惰的新巫师,就是像这样 code 片段不要直接从一些范例中「拷贝」下来,修改一下文字字串就到处适用,如何设计一个有趣的「动作」将是你成为有实力的巫师最佳的锻练方式。