我试图从Tiled实用程序的地图格式文档中找出这段代码的目的.
const int gid = data[i] |
data[i + 1] << 8 |
data[i + 2] << 16 |
data[i + 3] << 24;
Run Code Online (Sandbox Code Playgroud)
看起来有一些"or-ing"和位移,但我不知道这是什么目的,在使用平铺程序的数据的情况下.
Tiled将其"Global Tile ID"(GID)数据层存储在32位整数数组中,在XML文件中进行base64编码和(可选)压缩.
根据文档,这些32位整数以小端格式存储 - 也就是说,整数的第一个字节包含数字的最低有效字节.作为类比,在十进制中,在little-endian中写入数字"1234"看起来像是4321- 4数字中最不重要的数字(表示仅为4的值),3是下一个最不重要的数字(表示30),等等.这个例子和Tiled正在做的唯一区别是我们使用十进制数字,而Tiled使用的是字节,这些字节实际上是数字,每个数字可以容纳256个不同的值而不是10个.
但是,如果我们用十进制数来考虑代码,实际上很容易理解它在做什么.它基本上通过这样做来重建数字中的整数值:
int digit[4] = { 4, 3, 2, 1 }; // our decimal digits in little-endian order
int gid = digit[0] +
digit[1] * 10 +
digit[2] * 100 +
digit[3] * 1000;
Run Code Online (Sandbox Code Playgroud)
它只是将每个数字移动到位以创建完整的整数值.(在二进制中,以8的倍数进行位移,就像乘以十进制的10的幂;它将值移入下一个"有效数字"槽中)
关于big-endian和little-endian的更多信息以及为什么差异很重要可以在On Holy Wars和A Plea For Peace中找到,这是1980年的重要(并且有趣的书面)文件,其中Danny Cohen认为需要标准化网络协议的单字节排序.(剧透:big-endian最终赢得了这场战斗,因此整数的大端表示现在是表示文件和网络传输中整数的标准方式 - 并且已经持续了数十年.Tiled使用小端整数文件格式有点不寻常.导致需要像您引用的代码一样的代码,以便可靠地将数据文件中的小端整数转换为计算机的本机格式.如果他们将数据存储为标准的大端格式每个操作系统都提供标准的实用程序函数,用于从big-endian到native进行来回转换,你可以简单地调用ntohl()汇编本机格式的整数,而不需要手动编写和理解这种字节操作代码.