为 2D 游戏分配图块地图'tiles'和数值

Assign tilemap 'tiles' and numerical value for 2d game

本文关键字:tiles 地图 游戏 2D 分配      更新时间:2023-10-16

我目前使用的系统根据瓷砖集读取瓷砖图的x和y,并显示相对图像。这是可行的,但我发现手工创建地图非常困难,所以决定使用一个名为"平铺"的程序,但这是读取图像,在我的情况下,每32px读取一次,并将其设置为一个数字,让我试着解释一下,想象下面的每个数字都是32x32px的正方形,数字表示Tiled如何将图像存储为数字,直到它达到图像的宽度(例如,图像为160px或5个瓦片宽),然后在新行上继续计数。。

[1] [2][3][4][5]

[6] [7][8][9]

这会抛出我的脚本,因为没有使用x和y。我尝试了搜索和尽可能多的事情来调整我的代码以读取新格式,但完全失败了,下面是我当前加载地图的功能。

void LoadMap(const char*filename)
{
std::ifstream openfile(filename);
std::vector<sf::Vector2i> tempMap;
map.clear();
if(openfile.is_open())
{
std::string tileLocation;
openfile >> tileLocation;
tileTexture.loadFromFile(tileLocation);
tiles.setTexture(tileTexture);
while(!openfile.eof())
{
std::string str, value;
std::getline(openfile, str);
std::stringstream stream(str);
while(std::getline(stream, value, ' '))
{
if(value.length() > 0)
{
std::string xx = value.substr(0, value.find(','));
std::string yy = value.substr(value.find(',') + 1);
int x, y, i, j;
for(i = 0; i < xx.length(); i++)
{
if(!isdigit(xx[i]))
break;
}
for(j = 0; j < yy.length(); j++)
{
if(!isdigit(yy[j]))
break;
}
x = (i == xx.length()) ? atoi(xx.c_str()) : -1;
y = (j == yy.length()) ? atoi(yy.c_str()) : -1;
tempMap.push_back(sf::Vector2i(x, y));
}
}
if(tempMap.size() > 0)
{
map.push_back(tempMap);
tempMap.clear();
}
}
}
}

我所需要的只是脚本为每个32x32平方分配一个数字,然后开始一行新行,直到它到达tilemap.png 的末尾

如果这是一个愚蠢的请求,我很抱歉,我对c++很陌生,所以如果有任何关于让我的代码阅读新格式的建议,我将不胜感激,如果你需要任何其他信息,请告诉我。

如果我理解正确,您有这个对应关系,并且您希望将N转换为{x,y}和/或反之亦然。

X = 1    2    3    4    5
[ 1] [ 2] [ 3] [ 4] [ 5] y = 0
[ 6] [ 7] [ 8] [ 9] [10] y = 1
[ N]

因此,以下内容可能有助于

void NToXY(unsigned int N, unsigned int& x, unsigned int& y)
{
x = (N - 1) % 5 + 1;
y = (N - 1) / 5 + 1;
}
void XYToN(unsigned int x, unsigned int y, unsigned int& N)
{
N = (y - 1) * 5 + x;
}

这是一篇文章,介绍了tiled如何理解地图数据背后的逻辑。在您自己的游戏引擎中解析和渲染平铺的TMX格式地图

它讨论了如何将(x,y)坐标转换为Tiled使用的"gid"。

其要点是,他们使用1d数组来存储游戏中地图的所有平铺数据(此外,他们还使用1d数组索引到平铺的纹理图中)。这里的想法是,在一个紧凑的1d数字数组中,您可能能够利用缓存加载带来的性能提高。

这里还有另一个问题,它更详细地涵盖了这项技术:将2D阵列映射到1D阵列C 上

看起来Jarod42的答案具有进行数学/转换所需的函数。这将有助于暂时转换您的系统。我建议您重写引擎,以便更直接地利用GID属性,因为这将为您节省一些痛苦。您可以将转换函数保留为辅助函数,以备以后使用。