mud 板


LINE

看板 mud  RSS
※ 引述《laechan (小太保)》之铭言: : 首先来一张简单的 m x n 的地图(底下是 7x7) : x-x-x-x-x-x-x : | | | | | | | : x-x-x-x-x-x-x : | | | | | | | : x-x-x-x-x-x-x : | | | | | | | : x-x-x-x-x-x-x : | | | | | | | : x-x-x-x-x-x-x : | | | | | | | : x-x-x-x-x-x-x : | | | | | | | : x-x-x-x-x-x-x string str,*tmps=([]); int i,n,n1,n2; sscanf(str,"%d-%d",n1,n2); n=(n1*2-1)*(n2*2-1); // 计算需产生的数量 tmps=allocate(n); // 事先配置 for(i=0;i<n;i++) { if( (i/n1)%2==0 ) // x-x-x- 行 { if( i%2 == 0) tmps[i]="x"; else tmps[i]="-"; } else // | | | 行 { if( i%2 == 0 ) tmps[i]="|"; else tmps[i]=" "; } } str=""; for(i=0;i<n;i++) { str+=tmps[i]; if( (i+2)%n1 == 0) // 换行 str=str+"\n"; } write(str+"\n"); // 秀出来确认产生的图是不是对的 : 先随机戳几个洞,就变如下.. : x-x-x-x x-x-x : | | | | : x-x x-x-x : | | | : x-x x-x-x : | : x-x x-x-x : | | | | : x-x-x-x-x x : | | | | | : x-x-x-x-x-x : | | | : x x-x-x-x 随机戳几个洞的写法很多,底下展示一种 n=n1*n2; h=random(n); // 先跑出要把第几个 x 挖掉 // 第几排 排尾 在哪一排的第几个位置 h= (1+(h+1)/n2) * (n1*2-1) + ((h+1)%n1)*2-2; /* 假设是 3x3, n=25, 假设跑出的 h 是 4(代表中间的 x) 则新的 h = (1+(4+1)/3) x (3x2-1) + ((4+1)%3)x2 -2) = 2 x 5 + 2 = 12 (tmps[12] 刚好就是中间) */ tmps[h]=" "; // 挖洞 当然你也可以指定 tmps[12] = " ", 看是要随机还是手 动挖都可以, 手动的好处是不局限 "x", 你也可以把 "|" 或 "-" 挖掉。 : 然後把地图编号一下 : 001-002-003-004 005-006-007 : | | | | : 008-009 010-011-012 : | | | : 013-014 015-016-017 : | : 018-019 020-021-022 : | | | | : 023-024-025-026-027 028 : | | | | | : 029-030-031-032-033-034 : | | | : 035 036-037-038-039 int r=1; n=sizeof(tmps); // 第一步: 先处理 x for(i=0;i<n;i++) { if(tmps[i]=="x") { if(r<10) tmps[i]="00"+r; else if(r<100) tmps[i]="0"+r; else tmps[i]=""+r; r=r+1; } } // 第二步: 再处理 | (-不需处理) for(i=0;i<n;i++) if(tmps[i]=="|") tmps[i]=" | "; // 第三步: 再处理 " " for(i=0;i<n;i++) if(tmps[i]==" ") tmps[i]=" "; : 接着依这个地图产生出区域房间.. : > ls : 1 001.c 1 007.c 1 013.c 1 019.c 1 025.c 1 031.c 1 037.c : 1 002.c 1 008.c 1 014.c 1 020.c 1 026.c 1 032.c 1 038.c : 1 003.c 1 009.c 1 015.c 1 021.c 1 027.c 1 033.c 1 039.c : 1 004.c 1 010.c 1 016.c 1 022.c 1 028.c 1 034.c : 1 005.c 1 011.c 1 017.c 1 023.c 1 029.c 1 035.c : 1 006.c 1 012.c 1 018.c 1 024.c 1 030.c 1 036.c r=r-1; for(i=1;i<=r;i++) // 看最後产生几个房间 { if(i<10) files=__DIR__+"00"+i+".c"; else if(i<100) files=__DIR__+"0"+i+".c"; else files=__DIR__+i+".c"; // 产生要写的档案 file_text=FILE_TEXT; // 读入事先编好的房间档 exits=get_exits(i); // 依据 i 去读出这个房间有设哪些出口, 连接哪个房间 foreach(tmp in keys(exits)) file_text+="\""+tmp+"\":\""+exits[tmp]+"\",\n"; // "east":"/d/xxx", file_text+="}\n"; write_file(files,file_text); } FILE_TEXT 的定法类似底下 #define FILE_TEXT "#include <mudlib.h>\ninherit ROOM;\n\nvoid create...." get_exits 则看各家的写法,基本上就是做座标判读,判断 第 n 个房间的上下左右有没有连结,以左右的判断为例 // 假设 tmps[n] 是房间 if(n>0 && tmps[n-1]=="-") // 代表左边有连结房间 if(n<(n1*2-1)*(n2*2-1)-1 && tmps[n+1]=="-") // 代表右边有连结房间 if(n>n1+2 && tmps[n-(n1+2)]=="|") // 代表上面有连结房间 if(n<(n1*2-1)*(n2*2-1)-n1 && tmps[n+(n1+2)]=="|") // 代表下面有连结房间 重点就是要做边界判定。 上面是大致的概念,用「移动磁头」的概念,当我们想要对 第 n 个 x 做操作时,第一步就是计算出相对的座标出来.. 经过计算 由n ───→ 得出相对的 tmps[m] 所以建议将部份计算函数化.. 1. 由 n 得到 m 的函数 2. 判定边界的函数 3. get_exits 4. 秀图程式(随时确认修改後的 tmps 是否正确) 以上一点心得。 LAechan --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 111.253.169.46
1F:→ Searle:对这种有兴趣的可以去看RW的code 11/06 16:51
2F:→ laechan:我记得以前 doom 也有 imm 讨论过相关的设定, 另一个设定 11/06 18:49
3F:→ laechan:是「如何在 mud 呈现一个 100x100 格的区域」 11/06 18:49
4F:推 pssjim:FS狂想空间有个殭屍洞是类似的区域,有空可以去问一下喔 11/07 14:10
5F:推 jaykill:pss不上线还在这边喇赛 11/07 21:24
6F:→ laechan:呵这应该是在各 mud 均列为机密的东西吧 11/07 21:56
7F:推 Picoro:以前有写过类似的程式 ... 不过我是反过来的作法 ... 11/09 02:33
8F:→ Picoro:我是先随机决定好两个点或多个点为出口 11/09 02:33
9F:→ Picoro:之後随机放置障碍物 , 开始乱摆 11/09 02:34
10F:→ Picoro:摆完後我是使用EDA用的routing演算法"flooding algorithm" 11/09 02:35
11F:→ Picoro:从终点开始一直跑 , 直到它可以连结到起点 11/09 02:35
12F:→ Picoro:之後再用随机方式 , 看要它继续淹几次 11/09 02:36
13F:→ Picoro:若一直没有找到起点 , 但所有结点淹不下去 , 11/09 02:37
14F:→ Picoro:那就重新摆障碍物 , 再淹一次 , 一直到有路连通起终点 11/09 02:37
15F:→ Picoro:由於淹的过程已经建立好连结的指标 , 因此写档也很快 11/09 02:38
16F:→ Picoro:但我最大的问题还是在叙述很难写 ... 所以就不鸟鸟之 Orz 11/09 02:39
17F:→ belion:应该也能将叙述用此类作法.? 11/09 09:40
18F:→ laechan:做法有很多种可行 11/09 12:54
19F:推 kyoe:叙述真是大家心中的一个痛阿!! 11/09 15:47
20F:推 Picoro:毕竟MUD是文字叙述的东西 , 如果是图型 , 或许会简单许多 11/09 16:18
21F:推 neoyori:图形更困难吧,就算像RPGMaker那样有素材给你贴也要贴超久 11/10 00:32
22F:推 Picoro:不过如果每一格都可以用像FC时代的贴图 , 看起来还ok的感觉 11/10 01:53
23F:→ Picoro:毕竟以自动化设定区域来说 , 随机选素材来贴应该比叙述好用 11/10 01:54
24F:→ Picoro:不过没有实际接触那种东西 , 有些可能是我没看到的东西 11/10 01:55
随机叙述还有一种做法,适用於发展已久的 mud,它的做法 同样是建立资料库,但是建立的标的是「选定的房间」,例 如说底下三个房间.... /area/room/snake/009.c 毒蛇地穴 - 你看到在洞穴内长着一些从没在其他地方见过的蕈类, 这些蕈类 的上头有着一点一点暗红色的圆形斑点, 据说这些蕈类都含有剧 毒, 吃了马上灵魂出窍. /area/room/spipder/008.c 千蛛洞 洞穴内一片黑暗, 而且你感觉到你脸上与身体上都黏上了蜘蛛丝 , 感觉怪讨厌的. /area/room/scorpion/003.c 天蠍洞 里头屍骨遍布满地, 残破的衣服上还沾满着血迹, 可能是在与毒 物战斗时死去的冒险者吧! 因为在衣服上还有奇特的黑色液体残 留着. 假设这类的房间搜集了约一两百个,建成的资料录如下.. string *room_files=([]); room_files=({ "/area/room/snake/009.c", "/area/room/spipder/008.c", "/area/room/scorpion/003.c", . . . }); 那基本做法有两种.. 一、进入一个房间时,该房间的叙述「随机取上述房间的其中一   个」 string query_long() { string files=room_files[random(sizeof(room_files))]; object room; if(room=find_object_or_load(files)) return room->query("long"); } 二、搭配三段叙述法 string get_msg(object r1,object r2,object r3); string query_long() { int s; object room1,room2,room3; room1=find_object_or_load(room_files[random(s)]); room2=find_object_or_load(room_files[random(s)]); room3=find_object_or_load(room_files[random(s)]); return get_msg(room1,room2,room3); } string get_msg(object r1,object r2,object r3) { string *m1,*m2,*m3,tmp,msg; int i,j; m1=explode(r1->query("long"),", "); m2=explode(r2->query("long"),", "); m3=explode(r3->query("long"),", "); tmp=sprintf("%s, %s, %s.",m1[0],m2[1],m3[2]); msg=""; j=strlen(tmp); // 每 28 个中文字一行 for(i=0;i<j;i=i+56) msg+=tmp[i..i+55]+"\n"; return msg+tmp[i..j-1]+"\n"; } 其中第二种做法只要做好资料前处理其实就是三段叙述法, 以这种方式形成的房间叙述有时会像底下这样... xxx.c 某房间 你看到在洞穴内长着一些从没在其他地方见过的蕈类, 而且你感 觉到你脸上与身体上都黏上了蜘蛛丝, 可能是在与毒物战斗时死 去的冒险者吧! 问题:像这样完全不知所云的叙述真的可以吗? 我只能说,嘛,圣殿是可以的。圣殿有好几千个房间的叙述 都是许多巫师认真撰写下的产物,从里面取样产生新的叙述 并不困难,圣殿的[新区域]以这样的方式产生叙述完全没有 问题,因为根本没啥玩家在看房间叙述,这才是让我兴起想 写随机地图、随机叙述、甚至随机怪物分配等工具或继承用 物件的原因,这样就不需要再徵新巫师、也不需要再向玩家 徵求相关的东西,更不需要忍受绞尽脑汁写的叙述被蹧蹋的 不爽感。 (当然实际上我还是会要求产生的叙述要够正常) 後 mud 时代,我觉得 coding 人员的时间应该花在重点上, 而不是花在这类纯资料的构思上,我计划让圣殿明年至少增 加30个以「随机」为主架构的区域,大部份是区域的附属子 区域(如OX洞窟、OX塔)。 ※ 编辑: laechan 来自: 122.117.11.103 (11/10 05:45)
25F:推 dannielz:推没啥玩家在看叙述 尤其是这种随机生成的地图 11/10 15:02
26F:→ dannielz:除非带有解谜提示性质 否则没什麽必要在叙述上钻牛角尖吧 11/10 15:03
27F:→ kruz:diablo刚出来的时候就有人写过类似的,後来有发过paper的样子 11/11 03:43
28F:→ kruz:99年左右的mud研讨会的时候也有发表过. 11/11 03:43
29F:→ kruz:翻了一下,应该是第一届研讨会就发表了,所以是96 or 97的样子 11/11 03:48
30F:→ kruz:实作应该是在ES2上有跑过 11/11 03:49







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP