iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 7
1

https://ithelp.ithome.com.tw/upload/images/20190922/20115823sMt7iYoSAk.png

延續前一篇的話題,關於最後的"俄羅斯娃娃"程式碼至少包含以下的幾個問題:

  1. 目前只能丟一次蛋,再丟第二次就沒有效果了?
    • 這個問題也有邦友 (@Capillary J)發現到;因為我們用的是全域變數,在累加超過5之後我們的邏輯就不會再執行了。一個簡單的解法,就是在
      if (integer.getAndIncrement() > 5)內使用
      integer.compareAndSet(6, 0);
      
      就可以多次產生豬了,至於為什麼,有興趣的邦友可以想看看。
  2. 豬產生的位置好像有點"投射"的感覺,不是站在地上?
    • 主要原因是我們將豬的縮小行為綁定在"渲染"效果上,但"實體"在Minecraft內的判斷方式是透過BoundingBox,這個部分我們並沒有一起更改。簡單的方式確認BoundingBox,可以透過在遊戲內按下F3 + B來查看。
      下圖就是開啟後的畫面,透明的立方體就是每一個物件在世界內的BoundingBox,你可以看到我們的豬並沒有在自己的Box內。
      https://ithelp.ithome.com.tw/upload/images/20190922/20115823ptIfUSiK7m.png
  3. 產生的第一隻豬好像會跑來跑去?
    • 這個邏輯我們並沒有處理 (將第一隻觸發事件的豬也拔掉AI),這個就給各位自行去實做看看。
  4. 地上的陰影好像對不上?
    • 一樣,這個是只有處理渲染沒有處理真實的實體。

其他還有豬的位置會跟我們移動的時候一起移動、可能會打不到縮小比例的豬...等等

既然問題這麼多,為什麼還要這樣寫呢?
因為,我們現在這種開發模組的方式,比較適合直覺型的功能開發。換句話說,當你今天要做的邏輯牽涉到"不是當前事件提供的功能就可以完成的",你就會需要處理其他事件發生時可能會有的情況。

還記得我們在[Day3] 讓打方塊動作有敲有回應提到的事件巴士 (EVENT_BUS)嗎?

Minecraft Forge是透過監聽不同的事件(Event)發生來進行的,而每一個事件需要透過事件巴士(EventBus)在事件處理器(Event Handler)內進行註冊(register)才可以使用。

我們到目前為止的開發方式都是以下的流程:
建立事件處理類別 -> 處理特定事件 -> 註冊類別到主程式內

有沒有注意到一件事情:我們並不是在建立"可以照順序處理"的功能,而是建立"等待被觸發"的功能!
因為事件是會被所有有在主程式內註冊的類別都可以看的到,我們在為了確保事件是依照我們想要的情況才被觸發,就會免不得用很多IF的判斷式來避開不想要處理的狀況:

  • 如果是客戶端則不處理...
  • 如果實體是豬才處理...
  • 如果XXX不存在則不處理...
  • 如果執行次數超過XXX則不處理...

等等,有勾起你在前幾天一起開發的回憶了嗎?

如果還沒有感覺的話,我們用一個模擬情況來說好了:

今天有一個事件,它透過事件巴士要完成以下的事情

  • 到市場的時候要先賣斗笠,然後獲得錢
  • 到米店的時候要用錢買米

想一想,如果上面的處理順序互換,整個事件就無法正常運行了。
因此這裡還是要再次強調:Minecraft Forge的事件處理是透過

事件發生 - 事件處理類別訂閱 - 訂閱者監聽事件並做出處理

來完成各個功能的,這個很重要,很重要,很重要。


今天花了一點時間再一次說明事件註冊的一些觀念,希望可以幫助各位在未來要開發自己的模組時,能夠"利其器,善其事",用最簡單的方式完成想要的功能。

今日額外課題:在一開始的截圖裡,我們將殭屍裝上全套的鑽石裝備。請試著自行做出一樣的模組出來吧!

提示:

  • 在實體類別Entity內,有一個setCurrentItemOrArmor的方法,其中第一個參數從0-5分別代表手持、胸甲、護腿、鞋子、頭盔。
  • ItemStack的構造式new ItemStack()接受Item類別,你可以直接透過Items找到你想要的物品。

上一篇
[Day6] Minecraft版的俄羅斯娃娃(上)
下一篇
[Day8] Minecraft版的俄羅斯娃娃(中)
系列文
[Minecraft - 當個創世神] 從玩遊戲到設計遊戲30

尚未有邦友留言

立即登入留言