rendering - 程序生成世界中的 Godot 2D 自上而下平铺渲染
问题描述
我知道这个问题被问了很多。但是对于我的一生,我无法在互联网上找到答案。
到目前为止,我已经创建了一个带有 Player 节点(附加相机)和 TileMap 的场景。
TileMap 使用 OpenSimplexNoise 在玩家周围生成一个 32x32 的瓷砖网格,一个“块”。
我已经创建了一个脚本来不断地在 _process(Delta) 中生成新的图块,但是如果“块”太大并且当我必须同时更新位掩码时,这会破坏帧速率。
通过我的研究,我了解到,与其每 0.1 秒更新一次图块,不如在玩家通过“块”时将它们绘制成 9 个“块”会更快。
我模糊地理解使用“块”作为实例并复制它的概念,但似乎这仅在 3D 场景中是必需的。
我的问题是:我是否需要实例化 TileMap 块,或者我可以将 TileMap 保留在场景中并根据玩家块的位置绘制大块的图块。
我的最终游戏是创建一个程序生成的大型有限地图,但是当我使用位掩码和自动拼贴时,我无法超越绘制大量单元格以填充屏幕的阶段。
任何资源、链接、教程都会很有帮助,因为互联网上有太多的知识,我在试图找到正确的答案时迷失了方向。
这是我的代码:
func _ready():
randomize()
noise = OpenSimplexNoise.new() # Makes the noise OpenSimplexNoise
noise.seed = 123456#randi()
print("seed: " + str(noise.seed))
noise.octaves = 1.0
noise.period = 12
noise.persistence = 0.7
screensize = get_viewport().get_visible_rect().size
addChunk()
func addChunk():
var chunkWidth = 32
var chunkHeight = 32
var player_pos = Vector2(0,0)
var chunkCenter = ($Grid.world_to_map($Player.position)/32)*32
var PlayerChunkPos = ($Grid.world_to_map($Player.position)/16)
var columnStart: float = (chunkCenter.x/16 - (chunkWidth/2)+16)
var columnEnd: float = (chunkCenter.x/16 + (chunkWidth/2)+16)
var rowStart: float = (chunkCenter.y/16 - (chunkHeight/2)+16)
var rowEnd: float = (chunkCenter.y/16 + (chunkHeight/2)+16)
for x in range(columnStart,columnEnd):
for y in range(rowStart,rowEnd):
var a = noise.get_noise_2d(x,y)
if a < grass_cap:
$Grass.set_cell(x,y,0)
#$Grass.update_bitmask_region(Vector2(0.0, 0.0), Vector2(x,y))
func _process(delta):
addChunk()
print($Grid.world_to_map($Player.position))
print(($Grid.world_to_map($Player.position)/32).floor())
解决方案
首先,TileMap
已经处理了用于内部渲染的大块瓷砖。您可以通过设置来配置这些块的大小cell_quadrant_size
。所以,是的,一个单一的TileMap
应该适用于相当大尺寸的有限地图。
为了生成块中的内容……好吧,一旦生成了块,您就不必再次生成它,对吗?因此,请跟踪您已经生成了哪些块(我建议使用字典的键作为集合)。
您将使用相机的位置来计算附近块的坐标。对于每一个,您检查它们是否在生成的块集中。对于那些没有生成的块,你调用一个函数来生成块给定的坐标,然后将它们放到生成的块的集合中。
进一步优化的可能路径:您只能在相机从一个块移动到另一个块时生成块。此外,您只能考虑与相机移动的相机方向相同的块(假设相机没有跳过太多块)。
对于其他问题,我建议使用姐妹网站gamedev.stackexchange.com。那里有很多关于块和世界生成的现有问题可能会对您有所帮助。
推荐阅读
- ios - 点击其他单元格时如何在 TableViewController 中隐藏键盘?
- css - 如何使用 Css 在地图中创建“模糊区域”?
- php - 为什么协议 gs 上的 file_get_contents() 错误(开发本地 GAE)
- javascript - 如何在 chrome 扩展中使用 AJAX 向“我的 XAMPP 服务器”发送 GET 请求
- javascript - div上的点击事件并过滤vuex数据--vue.js
- android - 应用在生产中时,如何使用测试用户的帐户进行实际购买以购买相同的产品?
- django - Django Microservices - 跳过所有用户为非用户服务创建的表
- r - 有没有办法在反应数据上使用来自 shinyWidget 的 pickerGroup(或 selectizeGroup)模块?
- r - 如何将列表保存为 R 中的文件以便在 Python 中读取它?
- java - 为什么 Java 不能用泛型类型参数推断 lambda 表达式的类型?