zh
切换语言
  1. PowerNukkitX
  2. 快速入门
  3. 服务器配置

    expand_more
    1. server.properties
    2. nukkit.yml
    3. pnx-cli-config.ini
    4. 反矿透
    5. 资源包加密
    6. 硬件加速压缩
    7. 使用WaterDogPE
    8. 超平坦世界
  4. FAQ

    expand_more
    1. 新人必看
    2. PNX-CLI教程
    3. 常见问题
    4. Terra问题
    5. 重生点问题
    6. 转换地图
  5. 开发者文档

    expand_more
    1. Java

      expand_more
      1. 跳转到JavaDoc
      2. Mod API

        expand_more
        1. 自定义方块
        2. 自定义物品
        3. 自定义实体
        4. 自定义附魔
      3. 生物AI

        expand_more
        1. 行为
        2. 记忆
        3. 传感器
        4. 运动控制器
        5. 寻路器
        6. 行为组
        7. 工作周期
    2. JavaScript

      expand_more
      1. 配置开发环境
      2. 基于LLSELib开发
      3. Hello World
      4. 基本知识
      5. 事件监听
      6. 常见开发问题
    3. API

      expand_more
      1. 简介
      2. 通用API
      3. Git-API
      4. 下载API
      5. 延迟返回API
      6. 插件API
    4. 实用资源

      expand_more
      1. 事件对照表
      2. 物品方块ID

第二章 记忆 - 实体的海马体

author: daoge_cmd

1.0 记忆类型和记忆存储器

对于一个生物来说,不仅存在行为逻辑,在其生命周期中也具有一些实时数据。举个例子,对于羊来说,若其发现附近有手中拿着小麦的玩家并尝试移动过去,其“脑海”中就应该存储着对应此玩家的“记忆”。再比如说对于僵尸,其如果想要攻击最近的玩家,首先需要向“脑海”写入对应此玩家的记忆。这样子寻路器,攻击执行器,控制器等组件才能根据数据正常工作并实现目标行为

我们称上述的每个“数据”为一个记忆类型MemoryType。其中羊对应的记忆就是NEAREST_FEEDING_PLAYER(最近喂食玩家),僵尸对应的就是ATTACK_TARGET(仇恨目标)

"脑海"即记忆存储器MemoryStorage,其的概念比较好理解,每个实例化实体都拥有一个独立的记忆存储器,实体的所有记忆都保存在记忆存储器里面

1.0.1 创建一个新的记忆类型

MemoryType的可用构造函数如下:

想要新建一个记忆,我们需要提供一个命名空间标识符Identifier以及记忆默认值(当尝试从存储器获取不存在的记忆的值时会返回默认值,可以是常量,也可以通过提供Supplier<Data>动态生成)

命名空间标识符是每个记忆类型的“身份证”。PNX核心内部使用的命名空间是minecraft:,若你想在插件中增加新的记忆类型,请使用不同于minecraft:的命名空间避免重复

核心使用到的所有记忆类型保存在接口cn.nukkit.entity.ai.memory.CoreMemoryTypes

1.1.0 通用性

对于不同实体使用到的含义相同的属性(例如仇恨目标),我们应尽量让他们使用相同的记忆类型。这样子,如果我们想让僵尸去攻击苦力怕,我们就可以将他们的”仇恨目标“分别设置为对方。

1.1.1 连接不同组件

事实上,记忆存储器不仅为行为提供信息,它还在组件间发挥了桥梁作用。例如默认的几个运动控制器就通过读取MOVE_DIRECTION_STARTMOVE_DIRECTION_END等记忆移动实体,寻路器通过读取MOVE_TARGET计算路径。

通过记忆存储器,不同的简单组件被无缝衔接到了一起,实现了实体的复杂行为

1.2.0 作为属性保存还是作为记忆保存?

对于实体的数据(生命值,攻击伤害,仇恨目标,愤怒状态等),你可以选择将其作为属性直接保存在实体类上,并用接口抽象它的getter/setter。你也可以选择将其作为memory保存在实体记忆中。那是不是应该将所有数据都保存进memory呢?

看完上述内容,你也许会认为应该都存入到memory中,然而这样并不一定好。

对于实体基础属性,例如血量,生命值,攻击伤害等,我们规定应将其保存为实体类的属性并使用接口抽象

对于实体运行时属性,例如warden的愤怒值,实体寻路目标,仇恨目标等,我们规定应将其保存进memory

若你依然无法正确区分,我们还有个简单的判断方法,即观察属性是否应在实体生命周期结束(简单说就是close()掉了)后被保存。若应被保存,你就应该将其保存为实体类的属性而不是memory


© PowerNukkitX 开发组