123 lines
4.6 KiB
Markdown
123 lines
4.6 KiB
Markdown
---
|
||
front: https://nie.res.netease.com/r/pic/20211104/69055361-2e7a-452f-8b1a-f23e1262a03a.jpg
|
||
hard: 进阶
|
||
time: 20分钟
|
||
---
|
||
|
||
# 监听事件并创建组件逻辑
|
||
|
||
现在我们已经创建好了一个服务端系统,我们来尝试向这个系统中添加逻辑。
|
||
|
||
在添加逻辑之前,我们需要手动将系统在主模组文件中注册。我们仿照之前看到的示例,将额外API的`RegisterSystem`函数写在`@Mod.InitServer()`装饰器下的方法中。
|
||
|
||
```python
|
||
@Mod.InitServer()
|
||
def DemoTutorialModServerInit(self):
|
||
serverApi.RegisterSystem("DemoTutorialMod", "Server", "Script_DemoTutorialMod.DemoTutorialServerSystem.DemoTutorialServerSystem")
|
||
|
||
```
|
||
|
||
## 监听实体受伤事件
|
||
|
||
我们回到服务端系统文件`DemoTutorialServerSystem.py`中。我们一起尝试做一个简单的事件监听,比如,监听实体(活动对象)收到伤害的事件。
|
||
|
||
通过查阅API文档,我们得到了控制实体受到伤害的事件`ActorHurtServerEvent`,其字面意思为“活动对象受伤服务端事件”。我们通过该系统本身的`ListenForEvent`方法来注册这个事件监听。我们在`__init__`方法的末尾加入我们的监听注册函数,同时在该类中定义一个新的方法,比如名为`OnActorHurtServer`,将该方法作为回调函数绑定到事件上。
|
||
|
||
```python
|
||
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`中写入如下内容。
|
||
|
||
```python
|
||
def OnActorHurtServer(self, args):
|
||
comp = serverApi.GetEngineCompFactory().CreateAction(args["entityId"])
|
||
comp.SetMobKnockback(0.1, 0.1, 10.0, 1.0, 1.0)
|
||
|
||
```
|
||
|
||

|
||
|
||
这样,我们便成功更改了击退的威力。我们将完整的修改过的代码展示在此处。首先是`modMain.py`:
|
||
|
||
```python
|
||
# -*- 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`:
|
||
|
||
```python
|
||
# -*- 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`更改击退属性“诚不我欺”。
|
||
|