这个按位表达式我哪里错了?

Where am I wrong about this bitwise expression?

Game Maker Studio 2 有一个可下载的地牢自上而下游戏演示。其中有一个碰撞检查脚本。左走部分如下:

x += -4;
var tx = (x-16)>>5; /* check right edge (my note: this gets the tile x-index
for the wall on the left, as each tile is 32 pixels wide. I think they 
copied the part for walking right and didn't fix the comment)*/
var ty1 = ((y+16)>>5);
var ty2 = ((y-16)>>5);

// collision data never has flips etc...
var tile1 = tilemap_get(WallMap, tx,ty1 )& tile_index_mask;
var tile2 = tilemap_get(WallMap, tx,ty2 )& tile_index_mask;
if(( tile1!=0 ) || (tile2!=0))
{ x = (x&~31)+16; }

(我用它们的值替换了一些变量和宏。+16部分用于精灵调整。玩家的精灵原点(x,y)设置为距其边缘16个像素)。

最后一行让我很困扰。

31 位是 00000000000000000000000000011111。

~31 位则为 11111111111111111111111111100000.

所以 x&~31 实际上应该只是将 x 位的最后 5 位数字设置为 0。

但是x=0,y=0是房间的左上角。 x越小越靠左

所以我从中收集到的是,当 x 在向左行走时与其左侧的墙壁发生碰撞时,此函数将其原点设置为更靠近左侧,进入墙壁。这没有意义。

根据我的理解,最后一行应该是 { x = (x&~31)+32+16; }, 要将玩家原点捕捉到墙砖的左侧,将其移动到墙的右侧 32 像素,然后再移动 16 像素以适应精灵宽度。

然而 运行 游戏,它按预期运行。试图向左走到墙上会让你原地踏步。我哪里弄错了?

我不认为这个问题真的是关于它的按位方面的。我解释这段代码的方式是 x 代表精灵的 "origin" 和 x - 16 它的左边缘。然后 tx = (x-16)>>5 计算 左边缘 所在的图块的 x 坐标,这是碰撞测试等等。

然而,同一时刻,精灵的原点仍在你所站立的方块中(移动偏移小于精灵宽度的一半,因此试探性移动不会将原点移动到一个步骤中的不同瓷砖),那就是 (x&~31)+16 中使用的 x。因此,x&~31 向下舍入到您站立的瓷砖的左边界,而不是墙砖的左边界。