iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 12
1

https://ithelp.ithome.com.tw/upload/images/20190926/20115823ggYOgVwSBc.png

指令裡面有一個我還算蠻常用的:/fill
這個指令可以讓你用特定的方塊填充指定的範圍,也可以填充指定範圍的外框但內部是空的。什麼意思?
以下這個指令可以讓你建造一個老舊的岩石屋:
/fill ~-3 ~ ~-4 ~3 ~4 ~4 minecraft:mossy_cobblestone 2 hollow

看起來就像這樣
https://ithelp.ithome.com.tw/upload/images/20190926/20115823eYWGXJ4VoJ.png
那個洞是我挖的,因為我有幽閉恐懼症...

你以為我們今天只是要做一個自己寫的"填充方塊"模組嗎?沒這麼簡單!

標題其實有給些提示了,我想做羅馬競技場。
這樣感覺比較有趣。

感謝許多的Minecraft前輩,提供了很多很多想法與點子,讓我們這些後輩們可以有效仿與學習的對象。

定義模組類別

  1. 先在主程式定義我們的事件類別註冊:
    @EventHandler
    public void registerCommands(FMLServerStartingEvent event) {
        event.registerServerCommand(new ColosseumFillCommand());
    }
    
    @EventHandler
    public void init(FMLInitializationEvent event) {
        MinecraftForge.EVENT_BUS.register(new Colosseum());
    }
    
  2. 接下來,這邊我們會需要兩個類別:
    • Colosseum : 繪畫競技場的邏輯與定義用的類別
    • ColosseumFillCommand : 指令使用的類別
  3. 首先先看Colosseum類別,我們會需要讓使用者定義競技場的中心點,這邊我們控制滑鼠右鍵的事件:
    public class Colosseum {
    
        public static BlockPos centerPos = BlockPos.ORIGIN;
    
        @SubscribeEvent
        public void chooseCenter(PlayerInteractEvent event) {
            if (event.entityPlayer.getHeldItem() == null ||
                    event.entityPlayer.getHeldItem().getItem() != Items.wooden_axe ||
                    !event.entityPlayer.capabilities.isCreativeMode) {
                return;
            }
    
            if (event.action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) {
                centerPos = event.pos;
    
                event.entityPlayer.addChatComponentMessage(new ChatComponentText(
                        EnumChatFormatting.GREEN +
                                "Colosseum center position set to " + event.pos.toString()
                ));
    
                event.setCanceled(true);
            }
        }
    }
    
    這裡我們判斷使用者是否手拿木斧頭、在創造模式下、並且按下右鍵才會將指定的方塊位置作為中心點。這裡注意:我們之後會使用這個方塊作為中心點,所以方塊的位置最好是與你的腳在同一個平面上。成功獲取中心點後,會在訊息視窗中顯示設定的中心點。
  4. ColosseumFillCommand類別,我們一樣繼承CommandBase,設定指令的名稱,以及填入必須實作的方法:
    public class ColosseumFillCommand extends CommandBase {
    
        private List aliases = new ArrayList();
    
        public ColosseumFillCommand() {
            aliases.add("colosseum");
            // 純粹致敬神鬼戰士
            aliases.add("gladiator");
        }
    
        @Override
        public String getName() {
            return "Fill Colosseum";
        }
    
        @Override
        public List getAliases() {
            return aliases;
        }
    
        @Override
        public String getCommandUsage(ICommandSender sender) {
            return "colosseum";
        }
    
        @Override
        public void execute(ICommandSender sender, String[] args) throws CommandException {
        }
    }
    
  5. 接下來就是寫主邏輯execute方法了。因為競技場需要一定的空間才能建造,我們可以先做一些判斷來避免到時候建造產生不必要的結果 (比如說:你好不容易自己蓋好的房子結果被覆蓋了)。
    @Override
    public void execute(ICommandSender sender, String[] args) throws CommandException {
        // 我們競技場是橢圓形,短軸為17方格,長軸為22方格,高先預留20方格
        int widthHalf = 17;
        int lengthHalf = 22;
        int height = 20;
    
        EntityPlayer player = (EntityPlayer) sender;
        BlockPos pos = player.getPosition();
    
        for (int x = pos.getX() - widthHalf; x <= pos.getX() + widthHalf; x++) {
            for (int y = pos.getY(); y <= pos.getY() + height; y++) {
                for (int z = pos.getZ() - lengthHalf; z <= pos.getZ() + lengthHalf; z++) {
                    BlockPos blockPos = new BlockPos(x, y, z);
                    // 若這個立方體區域內有任何不是空氣方塊且不是我們中心點的方塊,跳出錯誤
                    if (!blockPos.equals(Colosseum.centerPos) &&
                            !(player.worldObj.getBlockState(blockPos).getBlock() instanceof BlockAir)) {
                        player.addChatComponentMessage(new ChatComponentText(
                                EnumChatFormatting.RED +
                                        "The Colosseum could not build in current area because the block : " + blockPos.toString()
                        ));
                        return;
                    }
                }
            }
        }
    
        System.out.println("centerPos: " + Colosseum.centerPos.toString());
    }
    

存檔後進入遊戲,選創造模式,先清出一塊空地 (可以用/fill指令幫助你)。
https://ithelp.ithome.com.tw/upload/images/20190926/20115823KViiu0Rg8w.png

在地上放一個方塊當作我們的中心點。
https://ithelp.ithome.com.tw/upload/images/20190926/20115823K6gZRrfRGS.png

裝備木斧頭 (或者你在模組內指定的物品),再按下滑鼠右鍵設定中心點。
https://ithelp.ithome.com.tw/upload/images/20190926/20115823wU9Ltuo2iE.png

輸入/colosseum確認我們可以在這塊空地上蓋競技場 (成功後會在IDE中出現訊息)。
https://ithelp.ithome.com.tw/upload/images/20190926/201158232GMM22myTX.png


上一篇
[Day11] 用指令玩遊戲
下一篇
[Day13] 羅馬競技場是一鍵造成的 (下)
系列文
[Minecraft - 當個創世神] 從玩遊戲到設計遊戲30

尚未有邦友留言

立即登入留言