2015-04-12 13 views
2

我正在開發一個適用於Minecraft的mod,它允許用戶創建與RedPower類似的大型移動結構。源可用here 我正在使用僞造1.8-11.14.1.1357,我試圖檢查一個塊是否通過另一個塊或直接連接到控制器塊。然而,我的當前方法由於遞歸深入而引發了StackOverflow錯誤。我怎樣才能簡化代碼,以便儘可能避免遞歸。 如何檢查一個塊是否間接連接到Minecraft中的另一個特定塊

public boolean isAttachedToController(BlockPos pos, World world) { 
     IBlockState state; 
     boolean up; 
     state = world.getBlockState(pos.up()); 
     if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
      up = true; 
     } else { 
      if (Arrays.asList(Stuff.getConfig().get("allowed_blocks", "Blocks", new String[]{}).getStringList()).contains(state.getBlock().getClass().getCanonicalName())) { 
       up = isAttachedToController(pos.up(), world); 
      } else { 
       up = false; 
      } 
     } 
     boolean down; 
     state = world.getBlockState(pos.down()); 
     if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
      down = true; 
     } else { 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       down = isAttachedToController(pos.down(), world); 
      } else { 
       down = false; 
      } 
     } 
     boolean north; 
     state = world.getBlockState(pos.north()); 
     if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
      north = true; 
     } else { 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       north = isAttachedToController(pos.north(), world); 
      } else { 
       north = false; 
      } 
     } 
     boolean south; 
     state = world.getBlockState(pos.south()); 
     if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
      south = true; 
     } else { 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       south = isAttachedToController(pos.south(), world); 
      } else { 
       south = false; 
      } 
     } 
     boolean east; 
     state = world.getBlockState(pos.east()); 
     if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
      east = true; 
     } else { 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       east = isAttachedToController(pos.up(), world); 
      } else { 
       east = false; 
      } 
     } 
     boolean west; 
     state = world.getBlockState(pos.west()); 
     if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
      west = true; 
     } else { 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       west = isAttachedToController(pos.west(), world); 
      } else { 
       west = false; 
      } 
     } 
     return up || down || north || south || east || west; 
    }

堆棧跟蹤可作爲GitHub的要點here BlockMovingController.java源here

+0

請向我們展示異常堆棧跟蹤。 – Unihedron

回答

0

你的問題是,你的方法不是終止。

up = isAttachedToController(pos.up(), world); 

此行是你的問題:它會basicly上去infinitly,因爲第一個塊不具有CONTROLER到它,然後要求上塊。這個控制器在頂部都沒有,但不是終止,而是再次詢問上面的塊。

看看下面的代碼。使用參數checkNextBlock = true調用它可以解決問題。

public boolean isAttachedToController(BlockPos pos, World world, boolean checkNextBlock) { 
    IBlockState state; 
    // check the block above 
    state = world.getBlockState(pos.up()); 
    if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
     return true; 
    } else { 
     if(checkNextBlock) 
      if (Arrays.asList(Stuff.getConfig().get("allowed_blocks", "Blocks", new String[]{}).getStringList()).contains(state.getBlock().getClass().getCanonicalName())) { 
       if(isAttachedToController(pos.up(), world, false)) 
        return true; 
      } 
    } 
    // check the block below 
    state = world.getBlockState(pos.down()); 
    if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
     return true; 
    } else { 
     if(checkNextBlock) 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       if(isAttachedToController(pos.down(), world, false)) 
        return true; 
      } 
    } 
    // check the nothen block 
    state = world.getBlockState(pos.north()); 
    if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
     return true; 
    } else { 
     if(checkNextBlock) 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       if(isAttachedToController(pos.north(), world, false)) 
        return true; 
      } 
    } 
    // check the southen block 
    state = world.getBlockState(pos.south()); 
    if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
     return true; 
    } else { 
     if(checkNextBlock) 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       if(isAttachedToController(pos.south(), world, false)) 
        return true; 
      } 
    } 
    // check the eastern block 
    state = world.getBlockState(pos.east()); 
    if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
     return true; 
    } else { 
     if(checkNextBlock) 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       if(isAttachedToController(pos.up(), world, false)) 
        return true; 
      } 
    } 
    // Check the western block 
    state = world.getBlockState(pos.west()); 
    if (state.getBlock().getClass().getCanonicalName().equals("cethric.stuff.block.BlockMovingController")) { 
     return true; 
    } else { 
     if(checkNextBlock) 
      if (! state.getBlock().getClass().getCanonicalName().equals("net.minecraft.block.BlockAir")) { 
       if(isAttachedToController(pos.west(), world, false)) 
        return true; 
      } 
    } 
    return false; 
} 
+0

謝謝你的迴應,但是,這不僅僅是在呼叫者周圍搜索1塊。例如,如果控制器塊距離20個街區,但仍然通過一個塊「連接」,那麼它仍然會被發現?這是我最終與[這裏](https://gist.github.com/Cethric/86ed1d4639cc422b29c8)和[這裏](https://gist.github.com/Cethric/8376c29cd5d2f06f12ad) – Cethric

+0

你可以取代boolen與一個int並減少它的每一次迭代。你的問題是你無法掃描每個塊。 –

+0

這種方法多久調用一次,因爲我認爲這會非常緩慢。 Specaly,因爲我猜它只會掃描上面的程序段,並在執行此操作時獲得一個計算器。 –

相關問題