教學:開發模組API/構建系統與監聽事件

出自Minecraft基岩版开发Wiki

< 編輯、除錯、打包與作品上傳 | 在事件下使用元件 >

導讀[編輯]

在建立了基本的環境之後,便可以著手開始構建系統了。

本章將會介紹模組API引擎最基本的用法。

註冊系統[編輯]

系統需要一個名為 modMain.py 的檔案進行註冊。該檔案應在腳本資料夾的第一層,且不可缺少。modMain 是 Python 邏輯的入口檔案,需要包含 mod 初始化與退出時的處理函式。

下面是一個 modMain 實例,對該檔案的結構進行解釋。

Mod 屬於 SDK 的內部類,用於繫結

from mod.common.mod import Mod

# 分别导入服务端与客户端的API进行绑定

import mod.server.extraServerApi as serverApi

import mod.client.extraClientApi as clientApi

# 将引擎的方法绑定到类上用于识别

@Mod.Binding(name = "testMod", version = "0.0.1")

class testMod(object):

    def __init__(self):

        pass

    # 服务端脚本初始化的入口函数
    #当然,如果您不需要服务端,您可以直接pass掉它

    @Mod.InitServer()

    def testServerInit(self):

        serverApi.RegisterSystem("testMod", "testModServer", "Scripts.ServerSystem.ServerSystem")
    #RegisterSystem的三个参数分别是[Mod名称][System名称][System类路径](路径从行为包根目录开始计算,中间以“.”隔开而不是“/”。下面客户端注册同理)

    # 服务端脚本在退出时执行的析构函数

    @Mod.DestroyServer()

    def testServerDestroy(self):

        pass

    # 客户端脚本初始化的入口函数

    @Mod.InitClient()

    def testClientInit(self):

        clientApi.RegisterSystem("testMod", "testModClient", "Scripts.ClientSystem.ClientSystem")

    # 客户端脚本在退出时执行的析构函数

    @Mod.DestroyClient():

    def testClientDestroy(self):

        pass

#备注:建议将Mod名称、版本号等需要在多处地方使用的量保存在一个单独的模块文件里,以便将来维护修改。

構建系統[編輯]

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

構建系統時必須確保該系統在ModMain中被正確註冊,否則會導致報錯或未被啟用。

匯入庫[編輯]

與目前的最新版本不同,網易使用的是 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 #客户端为 client.extraClientApi
import modConfig as config
#获取System类以继承创建自己的类
ServerSystem = serverApi.GetServerSystemCls()

class ServerSystem(ServerSystem):

      #类的init函数,会在类初始化时自动执行。
    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()

用戶端系統的構建同理。

結語[編輯]

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

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

因為官方的腳本模板並非完全空白,刪去多餘功能很浪費時間,所以這裏附贈一個完全空白的腳本資料夾模板。

下載位址:https://pan.baidu.com/s/1XjOTj116IDNFs-abM5Tjdg (提取碼:ogms)

你知道嗎[編輯]

  • 腳本資料夾名稱的重複會導致嚴重錯誤,所以請儘量使用更加獨特的名稱(如 工作室名+Mod名+"Scripts")
  • 上面範例中的Config模組其實是一個自訂檔案,透過Python匯入,其中可以存放任何你想要存放的變數(如系統名稱和路徑),方便統一修改。

< 編輯、除錯、打包與作品上傳 | 在事件下使用元件 >