Minecraft基岩版开发Wiki:技術週報/21m02w04a

出自Minecraft基岩版开发Wiki
assignment 21m02w04a | event 2021/2/28 | confirmation_number 第三期

edit history refresh

navigate_before 21m02w03a | 21m02w04a | 21m03w01a navigate_next

技術更新[編輯]

官方Beta[編輯]

本週官方發布了Beta 1.16.210.61更新,其中並無技術更新。

技術茶館[編輯]

本週主題:《中國版 Mod API 引擎系統構建》

文案:月光獨奏

在上週的週報中,我們介紹了網易ModAPI引擎的基本結構以及如何初始化引擎,這次我們來講如何構建一個系統。

系統是整個 Mod API 的核心基礎,所有操作都必須基於系統之上進行。

匯入庫[編輯]

與目前的最新版本不同,網易使用的是 python2 。在整個腳本檔案的開頭,我們需要一行特殊的注釋以保證檔案能夠在含中文的情況下正常執行。

# -*- coding: utf-8 -*-

接下來,使用 python 的 import 方法匯入網易的 mod 庫,以及任何你想使用的庫(例如存放變數的檔案)。

需要注意的一點是,伺服器端系統與用戶端系統使用的是兩套不同的庫,匯入時需要注意。若是在一端的系統內使用了另一端的 API ,很可能會導致嚴重的錯誤。

下為伺服器端的匯入範例:

import mod.server.extraServerApi as serverApi
...

用戶端:

import mod.client.extraClientApi as clientApi
...

構建 System 類[編輯]

在匯入了所有需要的庫之後,就可以開始構建系統類了。同樣的,用戶端和伺服器端的構建操作有著一些細微的差異。下面給出程式碼範例。

伺服器端:

ServerSystem = serverApi.GetServerSystemCls()
class ServerSystem(ServerSystem):
    def __init__(self, namespace, systemName):
        super(ServerSystem, self).__init__(namespace, systemName)

用戶端:

ClientSystem = clientApi.GetClientSystemCls()
class ClientSystem(ClientSystem):
    def __init__(self, namespace, systemName):
        super(ClientSystem, self).__init__(namespace, systemName)

注意:此處類的名稱(即class後面的字元)一定要與在Modmain中註冊的類名稱一致!否則會導致引擎無法找到類造成構建失敗(以及一大堆積紅色字元!)(笑)

對遊戲進行修改[編輯]

到此為止,我們的系統其實已經構建完成了。但是若想讓它真正發揮作用,還必須透過監聽事件以對遊戲進行修改。下面給出一個完整伺服器端系統的程式碼範例進行解析。

# -*- coding: utf-8 -*-

import server.extraServerApi as serverApi
import modConfig as config
#获取System类以继承创建自己的类
ServerSystem = serverApi.GetServerSystemCls()

class ServerSystem(ServerSystem):

    def __init__(self, namespace, systemName):
        super(ServerSystem, self).__init__(namespace, systemName)
        #建议将监听事件和反监听事件单独写成函数,并将两个函数放在一起,这样方便增删事件。
        self.ListenEvent()

    def ListenEvent(self):
        #监听事件用函数ListenForEvent,参数分别为[事件来源Mod名][事件来源System][事件名称][回调函数所在类][回调函数]。
        #前两个参数处的函数是API中提供的快速获取Mod名和System名的函数,可以在监听内置事件时使用。
        self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "OnCarriedNewItemChangedServerEvent", self, self.book)
        #下面是监听自定义事件的一个示例,参数类型和上面相同,使用了config模块快速导入变量。
        self.ListenForEvent(config.modName, config.ClientSystemName, "GetName", self, self.GetName)

    def UnListenEvent(self):
        #反监听事件函数,内容基本和上面相同,除了多了几个字母以外(雾)
        self.UnListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "OnCarriedNewItemChangedServerEvent", self, self.book)
        self.UnListenForEvent(config.modName, config.ClientSystemName, "GetName", self, self.GetName)

    def book(self, args):
        #OnCarriedNewItemChangedServerEvent的回调函数,args为事件传递过来的字典,详细内容请见官方文档。
        #创建name组件,以达到获取或修改当前游戏内容的效果。详细内容请见官方文档。
        name = serverApi.CreateComponent(args["playerId"],"Minecraft","name")
        playerName = name.GetName()
        data = {"playerId": args["playerId"], "playerName": playerName}
        if args["newItemName"] == config.guideUiItem:
            self.NotifyToClient(args["playerId"], "bookRender", data)
        if args["oldItemName"] == config.guideUiItem:
            self.NotifyToClient(args["playerId"], "bookRenderDestroy", args["playerId"])

    def GetName(self, args):
        #自定义事件GetName的回调函数。
        name = serverApi.CreateComponent(args["playerId"],"Minecraft","name")
        playerName = name.GetName()
        data = {"playerId": args["playerId"], "playerName": playerName}
        #向指定客户端发送名为initRender的自定义事件,传入的值为data。
        self.NotifyToClient(args["playerId"], "initRender", data)

    def Destroy(self):
        #Destroy是系统内置方法,在引擎被摧毁时会自动调用,此时可以反监听事件。
        # 清楚system的时候调用取消监听事件
        self.UnListenEvent()

用戶端系統的構建同理。

結語[編輯]

到此為止,Mod API 引擎的基本構建已經徹底完成了,接下來的步驟就是根據自己的想法,選擇事件進行監聽、修改來定義你心目中的那個 Minecraft 了。

內建事件和其傳入值、內建元件可以檢視官方文件取得。

當然,這些東西並不是腳本的全部————在腳本中,還有一個非常特殊的存在,那就是自訂 UI 。不過對於初學者來說,自訂 UI 是一項大挑戰。如果要進行 UI 開發,建議在熟悉系統的工作方式之後解析官方範例進行學習。

最後,送給大家一個僅註冊了一個空伺服器端和一個空用戶端的腳本資料夾範例,以幫助大家更快地收拾這些極其麻煩的步驟【其實官方範例也不是完全空白,而是帶有一些邏輯的,還要修改不少地方才能用。我在這裡準備的是完全沒有任何附加邏輯的空資料夾,解壓到行為包裡,修改註冊名稱之後就可以開始製作了】

下載位址:https://xmariohux.lanzous.com/inOOjlyiaud

編輯的時候記得先改資料夾名字啊!(笑)

別問我為什麼,問就是把兩個包打一起用的時候總是註冊失敗,然後折騰了幾個小時才發現是因為資料夾名字重了,我先在這說一下,避免大家被坑到(

有緣再見!

你知道嗎[編輯]

  • 這週 Mojang 的更新記錄只有三個條目。
  • 這週 Mojang 依然沒有更新任何腳本引擎相關的內容。