Files
2025-08-25 18:36:29 +08:00

175 lines
4.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 模拟原版袭击事件
> 本篇教程获得第一期知识库必看教程奖。
>
> 获奖作者:艾诺德。
今天的教程将教各位开发者实现类似于原版劫掠的袭击事件。这项技术可为RPG类模组提供更高的可玩性。
**教程概述:**
主要功能:实现类似于原版的袭击事件。
实现步骤:
1. 以触发点为原点在距该点**[8, 16]**格的某一位置生成参与袭击事件的生物并增加袭击事件进度条。
2. 参与袭击的生物死亡时更新进度条并在少于3个袭击者时显示剩余生物的数量。
3. 所有参与袭击生物死亡时判定事件结束。
**学习本教程的前置技术:**
- 基本熟悉Python语法及modApi接口。
- 了解如何进行服务端、客户端互传事件。
- 会使用MCS制作UI。
**目标效果:**
![img](./images/0_0.png)
![img](./images/0_1.png)
## 实现步骤
首先我们使用MCS的编辑器制作出一个进度条并制作一个文本框作为进度条的子组件为了模仿原版我们默认文本框在进度条的上方开发者也可自行布局之后我们保存编辑。
![img](./images/0_2.png)
完成上述步骤后,我们在客户端初始化(即`__init__`)事件下定义`self.UiNode = None`用于在加载UI后储存节点。
![img](./images/0_3.png)
完成后我们在初始化事件下增加对`UiInitFinished`事件的监听。
![img](./images/0_4.png)
并定义回调函数。我们在回调函数中调用`clientApi.RegisterUI`进行UI的注册在这里不作过多赘述完成后我们使用`clientApi.CreateUI/clientApi.GetUI`获取刚刚注册的UI并赋值给`self.UiNode`
![img](./images/0_5.png)
为了防止因ui未成功注册而导致初始化发生错误我们需要定义如下判定
![img](./images/0_6.png)
初始化操作中我们需要隐藏进度条由于进度条是文本框的父组件在进度条被隐藏后文本框也会自动被隐藏path为进度条的路径开发者请根据实际情况调整当然如果开发者写了储存袭击的算法可自行添加判定决定是否隐藏
![img](./images/0_7.png)
我们在客户端初始化事件下定义如下变量以保存袭击进度。
![img](./images/0_8.png)
第一个变量用于储存参与袭击的生物,第二个变量用于判定是否处于袭击事件中(注意,该做、储存方式为缓存,在退出游戏后失效,若想不受退出的影响可自行在服务端中通过`SetExtraData`设置储存于全局的变量实现),后续变量用于控制袭击进度条的变化。
接下来我们编写好服务端,增加如下自定义事件并在客户端中监听:
服务端代码:
![img](./images/0_9.png)
客户端代码注意ServerSystem和modName需要开发者根据实际情况进行调整
![img](./images/0_10.png)
接下来我们编写触发袭击事件。
我们先制作生成袭击生物的函数。为实现随机距离我们需要导入random库。
![img](./images/0_11.png)
我们通过`GetTopBlockHeight`得到最高的非空气方块的高度,并+1获取生成袭击者的y坐标以保证实体不会卡进地下。
我们通过`SetMoveSetting`组件使袭击者自动寻路前往目标点位,该组件具体用法请自行参考官网(同时为了保护版权,寻路回调函数已略去)。
完成生成后我们返回袭击者的id以进行进一步操作。
![img](./images/0_12.png)
为了像原版一样随机生成袭击者,我们需要编写一个根据权重随机选择实体的函数:
![img](./images/0_13.png)
完成该函数的编写后我们可以传人如下形式的字典参数来获得筛选出的实体id键名为实体id对应的值为权重
![img](./images/0_14.png)
应用上述函数,我们进行开启袭击事件的函数编写:
![img](./images/0_15.png)
在进行客户端回调函数的编写前,我们需要在客户端制作如下前置函数:
![img](./images/0_16.png)
![img](./images/0_17.png)
完成后我们编写回调函数:
![img](./images/0_18.png)
我们增加对OnScriptTickClient事件的监听并编写如下逻辑
![img](./images/0_19.png)
我们通过第一个if下的操作实时进行袭击状态的更新通过第二个实时进行进度条的更新通过第三个if-else实现少于3个袭击者时显示剩余生物的数量的逻辑。
最后我们进行胜利条件的判定:
我们在客户端增加自定义函数并在服务端监听回调(这里略去具体细节) 。
![img](./images/0_20.png)
我们在刚才的OnScriptTickClient事件下写如下逻辑
![img](./images/0_21.png)
完成后就可以实现一个类似于原版的袭击事件了!
**感谢大家的阅读。**