龙空技术网

为何RPG是游戏中的王者?Roguelike游戏的视野算法

哎哟嘿小游戏 89

前言:

而今兄弟们对“bresenham直线算法vc60”大体比较注重,大家都需要了解一些“bresenham直线算法vc60”的相关内容。那么小编同时在网摘上网罗了一些有关“bresenham直线算法vc60””的相关知识,希望朋友们能喜欢,兄弟们一起来学习一下吧!

大家好,欢迎来到上地十三少的游戏知识瞎科普!

昨天我们介绍了经典游戏系列《上古卷轴》,在文章中我曾提到RPG这一类别游戏是游戏中的王者。

但不少读者对此表示不以为然,在他们看来,吃鸡、农药才是当下最火的游戏,RPG早已日薄西山,穷途末路了。

我承认,他们说的也有道理,尤其是在手游如此风靡的今天,RPG游戏似乎确实没有那么大的市场和受众了。

但是,一款游戏的好坏,并不能单纯的按照游戏玩家数量以及市场营收来看。就如同获得奥斯卡奖的电影未必票房一定大卖一样。我敢说,目前这些火热的手游,绝大多数也不会进入到经典游戏的行列中去。

首先,我今天并不是来跟各位打嘴炮的,也并不想试图证明RPG就是比其他类型的游戏好。只是想起某些经典的RPG游戏伴随着我和一批老玩家的成长,所以今天就想盘一盘那些经典的RPG,权当给以后留个念想。

上世纪90年代,电子游戏逐渐进入到中国的千家万户。那是一个游戏史上的黄金时代。无数经典的游戏系列都在这个时候发行了第一代作品。而无数日后伟大的游戏公司,也在这个时候崭露头角。驶向他们的星辰大海。

千禧年来临的时候,年幼的我与同龄人一起接触到了电子游戏。这种神奇的,新鲜的娱乐方式一下子捕获了我们年幼而稚嫩的心灵。在那台只有256M内存/80G硬盘的台式机上,我和我的小伙伴们第一次发现,原来世界上竟然还有这么好玩的东西。

那是一个百花齐放的时代,也是国产单机的黄金时代。那是一个几乎没有网游,没有手游的时代。但好玩的游戏却有那么多那么多,学校门口的盗版碟摊上有花里胡哨、琳琅满目的各种游戏,只要花上3块钱或者5块钱就能享受到那时候最圆满的快乐。(当然长大后我们才明白,盗版是不对的,可能正是我们当年买盗版才导致了国产单机行业的衰亡)

那时候的很多RPG游戏给我留下了对游戏最美好的印象。就比如这款《天龙八部》(2002年智冠科技出品的单机游戏)

这款游戏的名气或许并不如国产三剑以及《金庸群侠传》,但它却是我心目中武侠RPG的No.1

首先,这款游戏的画面虽然做的不是那么好,但在那个800×600分辨率的时代,依然非常吸引我。因为开头CG的伪3D效果,也因为它分外鲜艳明亮的游戏色调。

然后,我一进入游戏就听到了制作非常精良的背景音乐,这款游戏的背景音乐可以说是国产武侠游戏中的标杆了。当然,同时期其他国产游戏的背景音乐也做的非常好。

这种背景音乐的美妙,与今天的游戏背景音乐已经不可同日而语了。《天龙八部》的背景音乐除了饱含感情,悠扬婉转之外,它和游戏场景及事件的契合度其实是非常高的。

在游戏中玩家会诞生在桂州,而在桂州城里的那段背景音乐,至今还时常萦绕在我的耳畔,偶尔我还会用口哨吹一吹这支小曲。虽然我至今都并不晓得这支曲子叫什么。但是它欢快又悠闲的旋律,伴随着当时懵懂无知的我,一直在桂州城里寻找宝藏。

而这支曲子也恰恰饱含着我那时单纯的快乐。而这种由游戏所带来的简单快乐,我却已经很多年都没有再体会过了。

这支曲子的链接在这里:桂州小调,有同感的朋友可以去怀旧一下。

当我终于从田猛和王六两位师父那里学会了通臂拳和蟠龙棍法之后,我志得意满地出城了。

本以为可以仗棍走天下,不想却在野猪林就被强盗打劫。但初生牛犊不怕虎,我上去就是一顿操作,然后,就出现了佛祖为我祈福的画面,那个画面的中间有一个大大的悔字。

跌跌撞撞,懵懵懂懂,充满好奇,啥都不会。

那时候,我还是个快乐的小学生,而那时候小学生也还不是个贬义词。

但当时只要放学回家进入这款游戏,我就可以一瞬间进入那个迷人的武侠世界,成为一个敢作敢当的大侠!我头戴地藏顶,手握蟠龙棍。走遍江湖,却被毒蛇、老虎打的满地找牙。但我依然快乐。

这大概就是我对RPG游戏最美好,最纯真的回忆了。

后来,我又化身成独孤剑、杨影枫、南宫飞云、变成小虾米、变成江暇、江云(新绝代双骄三)、化身为李逍遥、王小虎、陈靖仇(轩辕剑天之痕)等等英雄人物。穿梭在各种各样光怪离奇异彩纷呈的世界中。体会过兄弟情义、感受过国仇家恨,也历经血海深仇、阴谋诡计。

在那时候,好像每个RPG游戏都那么好玩,无论画面是否精良,操作是否顺畅。这些都不重要。重要的就是我能在这些游戏中成为一大侠,成为英雄,成为自己所敬仰的人,从而获得前所未有的满足感。

可能也是从这个时候,电子游戏开始被称为电子海洛因,但不得不说,那时候的我,真的中毒很深。

时至今日,再回想起那个青涩懵懂的童年,除了在操场边吃着小浣熊,拍着水浒卡之外,最深刻的记忆全部都是这些最经典的游戏了。

某天夜里,我猛一蹬腿,从睡梦中惊醒,竟然是梦到的是我杨影枫被卓非凡从悬崖边上推下去的那一幕。无语良久,却又开始深深怀念那个时代。

有时候,我就在想,要是当年少买盗版碟,用压岁钱买正版支持国产单机。是不是到如今国内也会有可以比肩《巫师三》跟《荒野大镖客2》的武侠RPG大作呢?

但世间唯独就没有卖后悔药的,我也不是李白,也不能重来。

多想无用,人终归还是要往前看。况且去年的《天命奇御》《太吾绘卷》《河洛群侠传》《古剑奇谭三》也都证明了国产单机还未死,还是大有前途的。

好不容易从回忆中艰难的撤出来,我想在文章的最后再BB几句,也算是我对文章标题的回答。

为何RPG是游戏中的王者?

那是因为,我们每个人的人生经历都很有限,想做的很多,能做的却不多。而RPG这种代入感MAX的游戏却可以帮助我们在有限的人生中,体验到更多人的人生。

就问问大家,谁还没有个英雄梦嘛?

作者:上地十三少

来源:简书

原地址:

【最近对这方面有兴趣,康了些资料顺便翻译了,出处:

Roguelike Vision Algorithms

里面还有很多资料,这没贴出来,主要是implementations和对比】

简介

实现Roguelike的一项任务是弄清楚如何计算玩家或怪物的可见区域。现有的算法很多,但是都存在缺陷,因此我着手开发一种新的算法,该算法对我来说是快速,准确和美观的。尽管我没有创建理想的算法,但我仍然认为我的算法是对其他算法的改进。

可见区域(视野/ field of view / FOV),判断单位是否可以看到地形的某个部分。这里假设地牢是很常见的基于tiles的类型。玩家是否可以“看到tile”(视线/ line of sight / LOS)有时与玩家是否可以“看到tile中的怪物”有所不同,也不同于他是否可以使用远程武器或咒语”瞄准该怪物“(瞄准线/ line of targeting / LOT)。

理想的算法属性

接下来首先描述视野算法一些常见而有用的特征,然后说明为什么大多数现有算法缺少这些特征中的一个或多个。

对称性(Symmetry): 如果站在tile A上可以看到tile B,那么站在tile B上就应该能够看到tile A。而且视野不对称通常会导致战术性和公平性变差(当LOS与LOT相同)。当然如果游戏是刻意造成不对称的话是例外。墙壁扩展(Expansive Walls):站在没有凹陷的大房间时,你可以看到房间里所有的墙;而站在长走廊时,您可以看到走廊两侧所有的墙。尽管它很少影响游戏玩法,但如果算法不具有此属性,看起来就会很丑,并且会使探索变得乏味。扩大柱子阴影: 当视线被柱子遮挡时,柱子应以扇形投射阴影。这通常可以提供更具战术性的玩法:更容易隐藏,伏击和逃脱。但是许多roguelike根本没有柱子,这个属性就跟他们没啥关系了。没有盲角: 在拐角处可以在看到至少两个tile。因此,如果沿拐角对角移动,你就不会发现自己旁边突然出现之前看不见的怪物。这也意味着可以在进入大厅之前看到两侧至少两个tile。大多数情况下这都是可取的,如果玩家走过每个角落都必须小心翼翼就有些乏味了。一些算法允许拐角处可以看到无限远,也算保护玩家免受远程武器的伤害。没有伪影(Artifacts): 尽管对于视野算法而言什么是“正确”有讨论空间,但是算法至少应该做到本份。意思是算法应该定义如同现实世界的几何图形并准确地模拟光传播。伪影的意思是有些算法根本不符合现实世界的几何体,是使用近似而非精确的数学来实现的,并且存在bug。效率: 算法不应该花费很长时间,并且最好避免重复测试同一个tile。

现有算法

不算详尽,涵盖了最常用的算法。

光线投射(Ray casting)

优点: 简单。相当快。扩大柱子阴影。良好的光影平衡。没有盲角。

缺点: 不对称。没有墙壁扩展。间隙很多(可见性不连续)。

这算法会将光线从玩家投射到地图边缘上的每个点(或视野半径边缘的每个点)。光线用简单的画线算法投射(如Bresenham'的算法[0]),一碰到墙就会停止。光线投射是最简单而且速度很快的算法,但是有许多问题。

不对称。 Bresenham的算法是不对称的,但是即使你用对称的画线算法,结果还是不对称,因为在替换位置时线条的端点不会简单地反转。在可见点和阴影上也都存在间隙,并且很古怪。后期处理可以修复间隙,可以消除难看的伪影,但会减慢速度,并且无法解决其他问题。会多次重复测试tile,效率有些低下,但是由于简单性,最终还是非常快,尤其是在较小的视线范围。

光线投射以最快的算法闻名,但是这主要是由于较复杂的算法普遍实现的较差。实现良好的阴影投射算法永远比光线投射更胜一筹。但如果撇开间隙和不对称,仅考虑光线和阴影的形状,我认为光线投射比阴影投射和菱形墙等更复杂的算法产生更好的结果。而且,随着视线半径的减小,大多数问题都变得没那么严重了;如果圆形视线半径为4或更小,它其实可以很好地工作,不需要进行后期处理(尽管还是有些一些伪影)。

代码:

阴影投射(点对tile或点对点)( Shadow casting)

优点:快。扩大柱子阴影。墙壁扩展。连续的可见性。

缺点:对角线视野比平常窄得多。盲角。光束通过门扩展得太多。不对称。消除伪影的方法复杂(nontrivial)。

阴影投射是从玩家向外投射扇形光线的技术。当一个扇区碰到墙时,该扇区可能会减小角度或分成两个扇区,然后分别进行处理。实现方式各不相同,但是好的实现只会访问每个tile一次或接近一次,并且每个tile仅进行少量且大致恒定的工作。如果实现得当,阴影投射会成为最快的算法之一;但在实现不佳的情况下,它在走廊拐角和具有许多小障碍物的开放区域中的速度可能较慢。 “阴影投射”有点用词不当,因为实际投射的是光,但我还是会用这词,因为“Light casting”跟“Ray casting”有些像。在我见过的所有case,阴影投射都使用正方形的tile,但是其他形状也是可能的。

在通常的实现中,如果从玩家的tile中心到目标tile的任何部分之间都存在一条畅通的线条,则tile为可见。这是一个示例,说明阴影投射如何针对单个八分圆扇形进行工作。 (并非所有实现都可以在八分圆中工作)


↑一个45度的扇形投影到了45度八分圆处,绿线为顶部,蓝线为底部。显示的分数是直线的斜率,数值永远是0到1之间,带有圆圈的象限被视为可见。然后,算法从发射点向外工作,对于每一列,它从扇区内的tile从上倒下扫。如果找到从透明到不透明的分界,则调整扇区至不包含该不透明。


↑已经扫描了前三列,并且在第四列中发现了分界(不透明>>透明),因此向下调整了顶部。


↑找到分界(透明>>不透明),因此向上调整了底部。


↑在第五列中找到了两种分界,因此将扇区一分为二,每个扇区独立继续。当算法达到最大视距或所有扇区变空(底部斜率>顶部斜率),算法将停止。


阴影投射的一些功能和问题(使用普通的正方形tile)。

上面就是不对称性会减弱战术性的一个原因。如果可以瞄准看到的东西(LOS==LOT),那么走廊中间会比拐角具有优势,尽管拐角看上去更隐蔽。拐角的单位可以在不见攻击者的情况下被射杀。像这样的不对等就是对称性是一种理想特性的原因。但是,如果上述不对称性被逆转,则实际上它可能是优于对称算法:可以使拐角真的更加隐蔽,使游戏更具战术性(更佳的可能是LOS对称,而LOT不对称)。有一种称为“反向阴影投射”的算法可以逆转不对称性,但通常看起来更差并且运行更慢。

不过,对阴影投射代码进行小的修改就足以使其对称。这是通过更改算法来实现的,因此只有在从玩家的tile中心到目标tile中心(而不是目标tile的任何部分)有一条畅通无阻的线条时,它才判定tile可见。如下所示,这可以解决一些问题但会导致其他问题。


代码:

【key point is the strategy of how to determine a tile is visible: just need the sector cover the tile? or need to cover the center point? or cover a certain percentage of area? 发射点固定了在格子中央,但是被观察的一方则是视线稍为蹭到格子都算看见,因此不对称】

菱形墙(Diamond walls)(点对tile或点对点)

优点:相当快。扩大支柱阴影。墙壁扩展。没有盲角。可见性基本连续。

缺点:光束通过门会扩展太多。不对称;小更改即可解决,但相对会丢失墙壁扩展并导致不连续

就像阴影投射一样,如果从玩家tile的中心到目标tile的任何部分都存在一条畅通无阻的线条,则tile为可见,但是它会将墙视为菱形。这比标准阴影投射有更大的拐角可视距离空间,更好地窥视各个角落。但它本身会带来一些问题,主要是有点过于宽容,使太多的tile可见,尽管如此,这似乎也是对标准阴影投射的一种改进。 (我稍为修改阴影投射代码来实现)至于效率,它比普通阴影投射要慢一些,因为它需要为每个tile做更多的工作,但是仍然相当快。

将墙视为菱形实际上在roguelikes中很有用。原因是大多数roguelikes允许单位在对角相邻的墙之间移动,如果墙是正方形的,它们的角就会碰触,没有空间。如下图所示。使游戏的物理学更加一致【指可移动范围与可视范围有一致性? 】。菱形墙还可以使拐角处的视野更好,通常是好事。




不幸的是,菱形墙存在理论上的问题。与菱形成切线视之为不相交;零宽度的光束仍然能照亮tile。这样可以在拐角处提供更好的视野,但在以下情况下使单位可以透视墙壁。应该要在特殊情况下禁止透视墙壁,但会造成游戏物理在某些情况下不一致。



菱墙的一些功能和问题


简单更改足以将菱墙算法转换为对称算法,但有与标准阴影投射相同的优缺点

代码:

半宽墙(Half-width walls)

优缺点: 与菱形墙相同,但更宽容,但速度稍慢。

另一个类似于菱形墙的想法,分别是它使用的墙是通常宽度的一半。它也解决了在对角tile之间的视野问题,但在我看来过于宽容,感觉比菱形墙更差。由于并非每个墙都是相同形状,因此实施速度也稍慢。 (形状取决于是否有相邻的墙要连接。)我姑且实现了这算法,但实在不值得花这气力。

宽容的FOV(Permissive field of view)(tile to tile)

优点: 对称。没有盲角。墙壁扩展。连续可见性。

缺点: 慢。没有扩大的支柱阴影。拐角处的可见性可能过多。

如果从玩家tile的任何部分到目标tile的任何部分之间都存在一条畅通无阻的线条,则视tile为可见。此方法的大多数实现都是估算,例如仅对对角进行相互测试【并不是任何部分,而是只有目标和自己的四个边角点】,在某些情况下会失败。精准的实现可以适应所有情况,但是慢。我提供了一个精确的实现(改编自Jonathon Duerig[1])。该算法的主要特征是对称,并且在拐角可以看很远,但对我而言有些太宽容了,所以我没有很努力优化这算法。可以说如果所有生物的视线半径都较短,那这算法感觉上和实际上都会更好。

有一个这算法的版本,可以在运行时更改宽容度(permissivity)。我玩了一下,把通常宽容度减半看上去很不错,但就不再对称了,而且我想有个更快的算法anyway。


代码:

Digital FOV(菱到菱)

优点和缺点: 与宽容FOV算法相同。

Digital FOV将每个tile都视为菱形,并且如果从玩家菱形的任何部分到目标菱形的任何部分都存在一条畅通的线条,则认为该tile可见。结果,它甚至比允宽容FOV稍微宽容一些(因为墙壁的障碍性更小) 。在其他方面所有相同的特征和缺点一样,但更慢。这个想法是基于的相当笨拙的digital straight line segments概念,我没有费心实现这个。 One interesting feature of the algorithm is that the knowledge of the digital line segment from a line-of-sight calculation allows easy tracing of a projectile path through space without hitting any walls, even down somewhat twisted tunnels (such as the Kuo corridor above) 。但是复杂性似乎超过了收益。

我的算法

以上没有一个令我满意。首先除了ray casting之外,要么太宽容,要么太过局限,有时两者都有。而且ray casting有太多伪影,用不来。下面我打算修复的问题和我想要的功能。

没大多数其他算法那么宽松比其他算法对称能够做到对称(至少跟不能穿墙的怪物相对)而不会损失墙壁扩展良好的拐角视野,但不能太好良好的狭窄的空间视野,而不会损失墙壁扩展比其他算法更少阴影间隙与菱形墙相当的效率没有死角没有伪影一致的物理

为此,我会将地牢的几何结构像下图一样表示。 (注意:图2中的两个角应该是斜角的。我画错了。不过,这图说明了内部正方形的用途。)



如果一个墙tile的两个相邻都不是墙,则将该角切成斜角。如果光束与墙的形状相交,则墙tile可见;如果光束与中心正方形(size最大为tile的1/2)相交,则空白tile可见。与图形成切线不算相交,并且零宽度的扇形无法照亮。

带有斜角的实心墙允许在拐角处窥视并可以看到对角空间,同时避免了钻石墙的理论问题。除非光线在中心附近通过,否则不要看见空白tile,这应该会没那么宽容,减少阴影间隙,减少不对称性并搞定光线通过窄空间的行为。

图2说明了光线穿过狭窄空间的问题。不管沿着隧道走多远,扇形都会在离开走廊时打开,而其他算法会立即照亮出口上下方的tile。支柱也是同理,就像走廊的墙壁一样,扇形在穿过支柱之间后打开。不照亮光线照射的比较少的tile就可以避免这种情况,还能让柱子有效的阻挡光线。因为能防止小束光线照亮tile,应该还能减少阴影间隙。

可以通过调整斜角的角度和内部正方形的大小来调整宽容度。可以使用正方形以外的其他形状,但是起码要可以放在tile中的最大菱形区域(就是不应该比柱子大)。用正方形的话,最大值为tile长宽的1/2,测试表明这样的结果最好。使用3/8的宽度,可以在长走廊内和拐角的单位之间对称的互望,很不错,但在其他情况感觉有些局限(尤其是在有许多柱子的环境下),所以我会用1 /2。实际的实现使用了修改的阴影投射算法,只要我能避免在每个tile上做太多工作就能有不错的性能。


不对称版本的例子【1/2大小】

我的算法有两个对称版本:一个是完全对称的版本,另一个是基本对称的版本(就是单位之间是对称但穿墙单位另算)。


基本对称的版本。对称时,它不会遇到其他算法的相同问题。最重要的是不会失去墙壁扩展。这是两个对称版本中较好的,除非你需要与穿墙单位也对称


完全对称版本。它与所有穿墙单位都有对称性,但没了了墙壁扩展;虽然扩展程度比大多数算法更好(宽容FOV除外)。与对称的菱形墙非常相似但不相同

代码:

[0] Bresenham's algorithm:

[1]Jonathon Duerig:

作者:淮山

专栏地址:

标签: #bresenham直线算法vc60