# 监听事件并创建组件逻辑

现在我们已经创建好了一个服务端系统,我们来尝试向这个系统中添加逻辑。

在添加逻辑之前,我们需要手动将系统在主模组文件中注册。我们仿照之前看到的示例,将额外API的RegisterSystem函数写在@Mod.InitServer()装饰器下的方法中。

@Mod.InitServer()
def DemoTutorialModServerInit(self):
    serverApi.RegisterSystem("DemoTutorialMod", "Server", "Script_DemoTutorialMod.DemoTutorialServerSystem.DemoTutorialServerSystem")

# 监听实体受伤事件

我们回到服务端系统文件DemoTutorialServerSystem.py中。我们一起尝试做一个简单的事件监听,比如,监听实体(活动对象)收到伤害的事件。

通过查阅API文档,我们得到了控制实体受到伤害的事件ActorHurtServerEvent,其字面意思为“活动对象受伤服务端事件”。我们通过该系统本身的ListenForEvent方法来注册这个事件监听。我们在__init__方法的末尾加入我们的监听注册函数,同时在该类中定义一个新的方法,比如名为OnActorHurtServer,将该方法作为回调函数绑定到事件上。

def __init__(self, namespace, systemName):
    ServerSystem.__init__(self, namespace, systemName)
    self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ActorHurtServerEvent", self, self.OnActorHurtServer)

这样,我们便完成了实体受伤的监听。当实体受到伤害时,DemoTutorialServerSystem实例的OnActorHurtServer方法将会运行。

# 在事件内触发击退逻辑

我们希望不仅仅是监听该事件,更要在事件发生时执行一些逻辑,比如更改受击实体的击退属性。

我们通过查阅API文档得知,action组件(mod.server.component.actionCompServer)具备更改击退逻辑的方法SetMobKnockback。所以我们使用引擎组件工厂创建一个action引擎组件,然后调用它的设置击退的方法做到一些逻辑,比如我们想增加击退的威力。我们在OnActorHurtServer中写入如下内容。

    def OnActorHurtServer(self, args):
        comp = serverApi.GetEngineCompFactory().CreateAction(args["entityId"])
        comp.SetMobKnockback(0.1, 0.1, 10.0, 1.0, 1.0)

这样,我们便成功更改了击退的威力。我们将完整的修改过的代码展示在此处。首先是modMain.py

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

from mod.common.mod import Mod
import mod.server.extraServerApi as serverApi
import mod.client.extraClientApi as clientApi

@Mod.Binding(name="DemoTutorialMod", version="0.0.1")
class DemoTutorialMod(object):

    def __init__(self):

    @Mod.InitServer()
    def DemoTutorialModServerInit(self):
        serverApi.RegisterSystem("DemoTutorialMod", "Server", "Script_DemoTutorialMod.DemoTutorialServerSystem.DemoTutorialServerSystem")

    @Mod.DestroyServer()
    def DemoTutorialModServerDestroy(self):
        pass

    @Mod.InitClient()
    def DemoTutorialModClientInit(self):
        pass

    @Mod.DestroyClient()
    def DemoTutorialModClientDestroy(self):
        pass

然后是DemoTutorialServerSystem.py

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

import mod.server.extraServerApi as serverApi
ServerSystem = serverApi.GetServerSystemCls()


class DemoTutorialServerSystem(ServerSystem):
    def __init__(self, namespace, systemName):
        ServerSystem.__init__(self, namespace, systemName)
        self.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ActorHurtServerEvent", self, self.OnActorHurtServer)

    def OnActorHurtServer(self, args):
        comp = serverApi.GetEngineCompFactory().CreateAction(args["entityId"])
        comp.SetMobKnockback(0.1, 0.1, 10.0, 1.0, 1.0)

    # ScriptTickServerEvent的回调函数,会在引擎tick的时候调用,1秒30帧(被调用30次)
    def OnTickServer(self):
        """
        Driven by event, One tick way
        """
        pass

    # 这个Update函数是基类的方法,同样会在引擎tick的时候被调用,1秒30帧(被调用30次)
    def Update(self):
        """
        Driven by system manager, Two tick way
        """
        pass

    def Destroy(self):
        self.UnListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ActorHurtServerEvent", self, self.OnActorHurtServer)

进入游戏测试,便可以发现SetMobKnockback更改击退属性“诚不我欺”。

https://nie.res.netease.com/r/pic/20211104/69055361-2e7a-452f-8b1a-f23e1262a03a.jpg

进阶

20分钟

监听实体受伤事件

在事件内触发击退逻辑