与平铺贴图负坐标

Negative coordiates with Tile maps

本文关键字:坐标      更新时间:2023-10-16

如何在基于2D平铺的游戏中映射负地图坐标?例如(-18100)或(10,-8)

我需要用O(1)访问它们。我不想创建一个巨大的二维矢量,并将(500500)视为(0,0),只是为了调用负坐标。

这个问题有点愚蠢,但我真的不知道。

谢谢。

我假设你有一个无限的、程序生成的世界,因为如果这个世界不是无限的,那么只需将X和Y坐标的下限设置为零,然后在你的瓦片映射数组周围包装一个函数,如果有人要求一个越界的瓦片,这个函数就会自动返回零。

在无限世界的情况下,你将无法在O(1)时间内访问你的瓦片——你要做的最好的事情是O(logn)。以下是我的做法:

  • 将你的瓷砖地图分成你认为合理大小的正方形块(我们称之为S大小)
  • 创建一个向量的哈希映射,每个向量都是映射的一块
  • 当玩家靠近一个新的区块时,在后台线程中生成它,并将其放入哈希中。散列应该基于区块的x,y坐标(x/S,y/S)
  • 如果要访问特定位置的贴图平铺,请获取适当块的向量,然后访问该向量中的平铺(x%S,y%S)
  • 如果你把它封装在一个类中,你可以为它添加一些功能,比如将块加载并保存到磁盘上,这样你就不必把整个映射保存在内存中。您还可以编写一个getTile函数,该函数可以获取任意坐标,并负责为您选择正确的块uan和块内的位置

您的向量在O(1)时间内总是可访问的,并且散列应该在O(logn)时间内可访问。此外,只要你选择了一个合理的区块大小,哈希的大小就不会失控,所以对性能的影响基本上是零。

如果数据密集(使用了已知2D范围内的所有或大部分点),则没有什么能胜过2D数组(O(1))。接受坐标偏移。

如果你的数据是稀疏的,那么在坐标对上创建一个哈希表怎么样。接近O(1)。

std::map或hash_map似乎不适合我的需求。它们过于复杂,不够灵活。我决定选择std::vector并接受高内存使用率的

我会把我的做法留在这里,以供将来参考

const uint Xlimit = 500;
const uint Ylimit = 500;
class Tile
{
public:
Tile(){someGameData=NULL;}
void *someGameData;
};
class Game
{
public:
Game()
{
    tiles.resize(Xlimit, std::vector<Tile>(Ylimit, Tile()));
}
inline Tile* GetTileAtCoord(int x, int y)
{
    return &tiles[x+Xlimit][y+Ylimit];
}
protected:
std::vector<std::vector<Tile>> tiles;
};