研究RPGMaker中地面纹理的拼接方式

话题

RPGMaker是我小时候很喜欢玩的游戏制作工具,其中最让我感到神奇的是绘制地图时地面纹理的拼接:
在这里插入图片描述
看起来不管我怎么画,图中【水】和【地面】边缘的衔接都是自然的。
不过,RPGMaker本身是一个轻量级的二维游戏制作工具,达成这个效果的方式一定只是简单的贴图拼接。我现在想要研究一下这个拼接的方式是什么。

研究

我在项目目录的\img\tilesets\发现了所有地图tile的贴图,这种能自动拼接的贴图资源都是一个格式:
在这里插入图片描述
就称它为【模板】吧,它的尺寸以tile为单位的话是2X3。
那么tile就是拼接的元素吗?为了解决这个疑问我对【模板】做了标记:
在这里插入图片描述
然后发现游戏中的情况就变成这样了:
在这里插入图片描述
从图中可以看出来:
1.圆圈颜色不一致。这表示拼接的元素并不是一个tile,而是一个1/4的tile。
2.圆圈线条是连接的。这表示“左上”的元素在【模板】的tile中也一定是“左上”。右上、左下、右下同理。

之后,我以数字为标记,标记出了【模板】里所有的拼接元素:
在这里插入图片描述
然后看游戏中的情况:
在这里插入图片描述
从图中可以看出,1~4其实没有被使用。1 、2 、3 、4 其实就是 9 、12 、21 、24。而 5 ~ 24这20个元素都被使用了。在之前已经确定了一个tile的四个部分不会混用(即“左上”部分不会使用【模板】中某个tile的“右下”部分),因此每个部分应该有 5种情况。
继续观察能发现,一个部分的元素选择实际上和它最相邻的三个tile有关,意思是:“左上”元素的选择只和 左上 三个相邻的tile有关。这样实际上是 2^3=8种情况,而他们实际上有5种表现,以“左上”部分为例:

在这里插入图片描述
从上至下的五种表现分别为:
1. 左上 都有同样式的tile,取值19。
2. 有同类型tile,但是左上 没有,取值5。
3. 都没有,则不管左上有没有,都取值9。
4.有且没有,则不管左上有没有,都取值17。
5.有且没有,则不管左上有没有,都取值11。

实践算法

完整的Unity工程见链接
工程的结构比较简单,在元素选取时的代码是这样的(以左上为例):

if(part==TilePart.LU)
{
    bool up = NeighbourFilled(new Vector2Int(0, 1));
    bool left = NeighbourFilled(new Vector2Int(-1, 0));
    bool up_left = NeighbourFilled(new Vector2Int(-1, 1));
    if (up && left)//上和左都有
    {
        if (up_left) //左上也有
            return 19;
        else                                        //左上没有
            return 5;
    }
    else if (!(up || left))//上和左都没有
        return 9;
    else    //左和上有一者有
    {
        if (up)         //上
            return 17;
        else            //左
            return 11;
    }
}

算法上,我相信有更简洁的表示方法,不过那样的可读性可能会变差。
最终效果和原版一样:
在这里插入图片描述

资源制作流程

虽然拼接的算法搞明白了,但还有个重要的问题没有讨论:
【模板】怎么制作?
我的意思是,虽然我们能知道一个元素它潜在的邻居,例如:【5】上会接【13】,左会接【10】,右可能接【18】或【6】或【20】等等。。。但是这并不能成为美术的制作规则,你不能对美术说:“嗨,我需要一个有20个元素的贴图资源,其中【5】号元素上半部分需要和谁谁谁无缝衔接,而【6】号元素需要和谁谁谁衔接”。
因此,一套流程是必要,美术应该按一套步骤尽量简单,规则尽量简单的流程制作资源,同时流程能保证制作出的资源一定是满足我们算法的要求的。

关于RPGMaker官方是如何生产这些资源的,我没有找到资料,他们很可能创造了一些工具来配合流程。
这里,我猜测了一种流程:

1.首先制作一个tile尺寸的无缝衔接的贴图:

重点是保证上下左右都可以无缝衔接(即tiling)
在这里插入图片描述
他将会作为模板中的14 、15 、18 、19:
在这里插入图片描述

2.制作边缘:

延展上一步得到的贴图一个元素的长度(为tile尺寸的一半),例如“上”边缘:
重点是保证左右可以无缝衔接(即tiling)
在这里插入图片描述
以同样的方法制作出:
左边缘(保证上下可tilling)、下边缘(保证左右可tilling)、右边缘(保证上下可tilling)。
此时模板:
在这里插入图片描述

3.制作边缘角

以左上为例,在已有10,13,14的情况下画出左上边缘角,注意要保证无缝:
在这里插入图片描述
以同样的方式画出左下、右上、右下边缘角。
此时模板:(1 、2 、3 、4也已填充,因为他们实际就是9 、12 、21 、24)
在这里插入图片描述

4.制作拐角

以右下拐角为例,在已有10,13的情况下画出右下拐角,注意要保证无缝:
在这里插入图片描述
以同样方式画出剩下三个拐角。
至此模板完成:
在这里插入图片描述

尝试制作

我用上面的流程尝试制作了一个模板:
在这里插入图片描述
这是他的效果:在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

YakSue

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值