
好的,哈伯社区。
许多年前,我遇到了一个帖子
(1) 。 然后,我为有机会为roguelike
(2)创建有趣的游戏元素而感到困惑。 假设对手可能在墙后,直到我们在视线内遇到他,我们才看到他。 但是我更喜欢这样一种情况,当我们沿着地牢的走廊旅行时,会根据可见区域逐渐揭示物体位置的特征。
在后面的文章
(3) ,
(4)和
(5)中 ,考虑了2D游戏中的阴影投射问题。 正如作者自己和评论中所指出的那样,对于计算器和设计而言,阴影的计算非常繁琐,而且并非易事。
不知何故,我有一些自由的日子,所以我决定回到阴影更美好的问题。 显然,视频卡可以成功且快速地处理阴影,但是在这种情况下,我想为2D游戏处理阴影,因此将计算转移到视频卡似乎是多余的。 是的,近年来处理器能力整体上有所增长,实际上是一篇有关最终情况的文章。
该程序是用Pascal编写的,因为我很了解Lazarus,它是一个开放的IDE,具有许多组件。
最初的想法是绘制从观察者到瓷砖各个角的线,然后使所得图形变暗。

然而,当视角改变时,这种阴影看起来有些不自然。 阴影现在更宽,现在更窄。

圆形物体的阴影看起来要好得多。 为了构建这样的阴影,您需要从观察点到圆以及到屏幕的边界绘制两个切线。 圆的直径将对应于瓷砖的尺寸。
在我的程序中,我使用了以下功能:
其中(x1,y1)是观察点,(x2,y2)是圆的中心,®是其半径,(x3,y3)和(x4,y4)是直线和圆的交点。 仅当观察者在圆外时,该函数才返回true。
由于处理器对三角函数不是很友好,因此我尝试将其最小化。 实际上会依靠一个简单的规则(粗略模型),专家会告诉您原因。
(错误)SIN,COS ..>'/',SQRT>'DIV','MOD'>'SHR','SHL'>'*'>':=','+','-','AND ','XOR'..(好)很高兴在画布上实现图元的图形部分,有很多库和引擎可以简化工作。 在Delphi上进行开发时,我不得不使用Agg2D库,在Lazarus上有端口
(6) ,因此我决定实现这一想法。 实际上,从库中获得的好处是将alpha通道添加到RGB颜色,并且平滑了基元,并且由于直接访问像素和各种技巧,处理比画布快得多。
当绘制图块的阴影时,我本来打算用阴影填充该扇区,但随后图块内部的图像很难分辨(图3中所讨论的扇区用绿色填充)。 在尝试了各种选项之后,我停止从阴影区域中选择一个扇区。
要绘制扇形,我们需要以弧度为单位的角度,但是三角学仍然无法做到。 (arctan2-数学模块库函数)
实际上,一切都准备好进行图像组装。 我们绘制一张瓷砖地图,并在单独的图层上依次逐一应用阴影。 对于树木,阴影更暗,对于其他物体,阴影更透明。

将完成的图像应用于图块的主层。 进行一些背景设计,并选择更加通用的tileset。 实际上,我花了两天的时间来寻找合适的磁贴集,这些磁贴集属于公共领域,或者质量很低或成本很高。 结果,他亲自绘制了树木,并从用户Joe Williamson
(7) (出色的风格)中借用了其他元素。

到此为止,但是关于性能的一些沉淀。 随着对象数量的增加,大约有五百次缩编开始。 考虑了各种优化方法,将其拆分为多个内核并将绘图区域限制为一定的半径,更改阴影的形状(比弧线便宜),我什至想到了将计算转移到视频。
结果,我得出的结论是,最好的选择是减少用作荫罩的图像的采样。 由于计算数量显着减少,以及阴影轮廓的像素化的意外影响,因此具有一定的传统魅力。

我非常喜欢这种效果,以至于我不得不通过给定的多重性参数来缩放动态过程。

剩下的就是创建不透明的墙并将结果呈现给社区。

我期待使用这种效果或其发展的新游戏。
谢谢你
演示可以触摸手柄的位置(Windows的exe)。
第2 部分 ,
第3部分参考文献:1)habr.com/post/16927/
2)en.wikipedia.org/wiki/Roguelike
3)habr.com/post/204782/
4)habr.com/post/305252/
5)habr.com/post/319530/
6)wiki.freepascal.org/BGRABitmap
7)twitter.com/joecreates