炮弹挖坑流程

  • 炮弹打在地图上,产生一定形状的弹坑。
  • 地图和弹坑形状都为二进制数据,一个byte共8位,每一位表示一个像素点,代表改像素点是否为空点。
  • 整个地图的数据为一个byte数组,xy坐标系下x0,y0 点的数据,保存在byte数组的第 y0 * wight + x / 8 个byte中,具体为该byte的第 x % 8 位。其中wight为整个地图一横排的所有点的byte的数量。
  • 炮弹打在地图上,在击中点生成一个弹坑数据,弹坑数据与地图数据在地图坐标系下求交集,再在地图数据中,减去交集中的实心点,就可以得到挖坑后的地图数据。

地图数据减去弹坑数据流程

  • 按行移除

    • 按y 遍历所有行,每一行取出地图数据与弹坑数据,每一行计算交集矩形宽度范围内的像素点。
    • 根据地图数据起始点的x值,计算该byte需要计算的位数。
    • 根据弹坑数据起始点的x值,计算该byte拥有的位数,对两个byte进行左右移动,使起始位的偏移值相同。
    • 如果弹坑数据该byte拥有的位数不够,则取下一个byte的前几位,使弹坑的位数等于需要计算的位数。
    • 然后将弹坑byte取反,并与上地图byte求出该地图byte计算后的byte值
  • 按像素移除

    • 按x,按y,遍历所有xy像素点,如果地图可挖,弹坑为实心,则把改地图像素置为空

问题

  • 偶尔会出现弹坑左边边界处有多挖的情况。也就是说取弹坑byte的时候,会出现多余的1。

解决

  • 断点跟踪后发现,-32 右移 7位后变成了-1,-32的二进制表示为:11100000, -1二进制表示为11111111。
  • 查找资料后发现>> 右移操作为有符号右移,即右移时会保持符号不变,所以左边会补1。而>>>为 无符号右移。
  • 尝试使用>>> 发现和原来结果一样
  • 继续查资料 发现>>> 虽然是无符号的右移,但是byte类型的进行右移会默认转为32位int类型,然后进行无符号右移,再转换为byte。
  • 因为会转换为int类型,所以我们可以将原byte & 0xff 把int的前24位置0,再进行右移,然后转为byte。完美解决