如何绘制不规则地图



  • 随机地图根据游戏方式不同,绘制原理也不同。

    现在需要强调的是如何绘制如世界地图一样的不规则图形。

    本人想到一个方法,首先创建一个N*N(方格)大小的地图,通过选取方格添加到数组,再选取方格四周随机方格(不能重复)添加到数组,以此重复选取的办法,来得到一个随机的方格数组(随机地形),最终得到一个随机划分的地图。

    此种方法简单,但不能获得复杂地形,而且每一个方格就是一个精灵,对于巨大地图势必会消耗大量资源。

    所以在此请教大佬,有无在唤镜中更好的办法绘制此种随机地图。



  • 可以把精灵换成tilemap,用动作来设置某一编号图块的样式,可以解决消耗大量资源的问题。当然用起来肯定没有直接创建精灵那么简单直观,这个你就自己去多试试吧。 aba5d457-4c54-4b73-8f85-7689b65aaee8-image.png 4459c7fa-17f6-4681-b6b5-2dd51692ad1a-image.png

    另外关于绘制不规则地图的方法,网上有挺多的。 有兴趣的可以看一下【元胞自动机】的使用。我的理解是每一个地图块自己去根据周围地图块的状态(规则可以自定义,比如自身周围有多少个墙壁时),来改变自身的状态。每一个周期所有的地图块都会演变一次,在多次演变后,最终形成一个新的地图。(我讲的可能不清楚,这个你去网上搜索一下就有很多了。)

    这个是最开始完全随机生成的地图(绿色灰色2选一,没有其他规则。) 21d3ce55-cd9a-4818-9dfa-064a92467727-image.png 这个是进行了一次演变的地图(规则是我之前在其他代码的教程里看的,我只是把代码的东西搬过来转换成事件表来使用) 当前为墙壁时:如果周围有4个以上墙壁,则保持墙壁,否则变为道路 当前为道路时:周围墙壁有5个以上时,变为墙,否则保持道路 51757d6c-c284-44b7-8ec8-49da0a331363-image.png

    第三次优化 28be8014-98d4-4d4c-832d-bd049909f616-image.png

    创建地图就循环创建就好了,优化的动作组是这个。 【获取周围墙壁数量】就比较一下坐标就好了,这个自己去解决,获取到之后,先记录要转换的类型,但不要转换。 等所有地图块都计算完后,在去转换,不然会有问题。 6a32aa25-cb84-44f7-b8ba-b38d39595ec1-image.png

    ps:这个是比较早的时候试验的时候做的,没有做过什么优化。 如果地图块都用精灵的话,在优化时会卡顿一秒左右,因为计算量比较多。所以你如果要试验这种方法,可以把精灵转换成tilemap,就像我最开始说的那样。



  • @DionysusF5 谢谢大佬给出的一种解决思维,能不能在加点料,这样生成的地图太随机,有点凌乱。能不能再多一点规则,我现在并不想生成地牢式地图,而是像生成地面地图,元素有河,路,山,城。这些元素需要的规则是什么。

    还有个问题,我怎么检验电脑生成了我需要的地图。

    最后我还是要感谢,你对随机地图的建议,让地图自己根据周围情况来改变确实是好注意,就是复杂的地图,规则越多,现在最搞不清这些规则了。



  • @猫人队长 昨天说的只是其中一种思路。 要生成城的话,要看你的城是可以占多个格子的还是只占一个格子。 还有一种思路,你可以把整个地图先划分成多个小区域,然后你做一些预设的城市道路的组合,每个区域去随机这些组合来生成。 当然如果预设少的话,可能看起来就不是那么的随机了。 但其实这种思路也是可以继续拓展的,比如说,第一遍,你先随机划分区域的大小(这个你自己算坐标避免区域重叠就好)。 第二遍去遍历每个区域,根据这个区域的大小,去随机可以出现在这个大小的区域里的物件(也是你可以自定义的,比如说 城镇A可以出现在区域类型为A的区域内)。 这样生成下来,就有了一个差不多的地图, 然后可以在用各种思路去优化地图。 比如说,如果两个城市离得太近,随机选择一个城市变成空白区域,这个区域用【元胞自动机】或者其他方式去随机山和水。 水路和道路的连接,也可以尝试用这个思路,如果一个空白区域,他的左边和右边两格以内有水,那么他就变成水,道路也是一样。

    总结一下整体思路就是先按照组合的方式随机生成一个大的地图,再去优化小的细节部分。不过说了这些其实也只能给你提供一个思路,具体的算法实现还是要你自己去做。 毕竟我也不是啥大佬,之前做小游戏有涉及到这部分所以看了一下简单的算法,但是也没做过太完整的随机地图,还是要你自己去试了。。 如果你总结出来一套生成规则,也可以拿出来分享一下。



  • @DionysusF5 这个思路我也想过,还是谢谢你了。



  • @DionysusF5 那么大佬该如何绘制碰撞呢



  • @唤境用户11704324 墙的位置放置刚体



  • @DionysusF5 大佬能不能把生成的事件表截图下?不会写...另外想问下跨场景的时候怎么保存?每个位置的坐标.图块类型都要单独存2个数组,然后回来时生成?感觉这样好麻烦



  • @疑似陆飞 这个规则我是看的这位博主的想法然后在唤境上重现的,有兴趣可以去看一下他说的思路。 https://indienova.com/indie-game-development/procedural-content-generation-tile-based-random-cave-map/

    这个是生成,每个格子都生成一个地图块,地图块的类型随机选择 40082748-8e22-46d4-a820-7d5a558eba06-image.png

    这个是优化地图,每个地图块都循环一次。先获取当前地图块周围的类型为【墙壁】的地图块的数量。然后根据这个数量,决定当前地图块转变为什么类型(道路或墙壁)。 决定好后不要立刻修改,否则会影响后面的地图块的运算,先用实例变量记录自己要转变成什么类型的地图块。

    所有地图块都计算过后,再去循环一遍,去转变地图块的类型。 13543adf-1f82-4c13-b105-f4de1a0c8aea-image.png 获取周围墙壁数量就直接比较坐标就好了,这个没什么好说的。 9dda6077-110d-43da-93b9-e3977b0ff1be-image.png



  • @疑似陆飞 另外跨场景保存这个你肯定要记录坐标这些到数组的。 如果你不想记录,那就不要跨场景。 用一个图层来做大地图之类的。 但其实记录没那么麻烦。 你不需要每次跳转场景都重新记录大地图的样式,在第一次生成的时候顺便去记录就好了。 后面重新回到大地图就直接用数组里的坐标去重新生成一遍。



  • @DionysusF5 感谢,确实时有我没熟练掌握的知识点.



  • @DionysusF5 !59BC4Y11A)8N3XB}NVZJQOW.png 再问下这里为什么会选择用*10的方法?跟直接用1-400的for循环1样的吧,还是说有什么独到之处?



  • @疑似陆飞 我这里一个格子的宽高就是10。 每个格子的间距也是10,这里是为了计算生成位置。直接用一个1-400的循环不方便计算XY坐标。



  • @DionysusF5 我忽略了每个格子的高宽,以为直接是按地图的XY来的..现在明白了,这样挺方便的


登录后回复