这个按位表达我错在哪里?

时间:2018-01-10 03:54:18

标签: bit-manipulation bitwise-operators bitwise-and

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 in bit则为11111111111111111111111111100000。

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

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

所以我从中得到的结果是,当左边的x与左边的墙碰撞时,这个函数将它的原点设置得更靠近左边,进入墙壁。这没有意义。

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

然而,运行游戏,它按预期工作。试图左转进入墙壁让你保持原位。我错在哪里?

1 个答案:

答案 0 :(得分:0)

我不认为这个问题实际上与它有关。我解释这段代码的方式是x代表"起源"精灵和x - 16左边缘。然后tx = (x-16)>>5计算左边缘所在的图块的x坐标,进行碰撞测试,等等。

然而,在同一时刻,精灵的原点仍然在你所站立的瓷砖上(运动偏移小于精灵宽度的一半,因此暂定运动不会将原点移动到一步中使用不同的图块),这是x中使用的(x&~31)+16。因此,x&~31向下舍入到您所站立的图块的左边框,而不是墙砖的左边框。