修改一个实体

警告

这些文档是为 SpongeAPI 7 编写的,可能已经过时。 如果你觉得你可以帮助更新它们,请提交一个 PR!

确实,在世界上生成一个常规的实体已经足够了,不过,有没有什么更有趣的东西呢?这时候就需要 DataManipulator 大显身手了。一个 Entity 同时也是一个 DataHolder ,也就是说一个实体可以存储数据。关于 DataHolder 的更多信息请参见 这里

常见的适用于实体的 DataManipulatorFoodData 以及 HealthData 等。我们可以在 org.spongepowered.api.data.manipulator.mutableorg.spongepowered.api.data.manipulator.mutable.entity 中找到适用于实体的 DataManipulator 。注意并非所有的 DataManipulator 都适用于所有的实体。

实体类型

在我们进一步操纵实体之前,我们首先应检查这个 Entity 是什么类型的,因为一些实体并不是我们自己生成的,所以我们可能并不清楚它的具体类型。一个很简单的检查就可以完成这一点,下面是一个检查一个 Entity 是否是一个爬行者的示例:

import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.EntityTypes;

public boolean isCreeper(Entity entity) {
    return entity.getType().equals(EntityTypes.CREEPER);
}

操作实体数据

现在我们清楚这么一个 Entity 是一个爬行者了,那么我们就可以使用适用于爬行者的特殊 DataManipulator ,比如 ExplosionRadiusData 。爬行者拥有这一数据,而并非每个实体都拥有。把一个实体的爆炸半径设置成五十的示例如下:

import org.spongepowered.api.data.manipulator.mutable.entity.ExplosiveRadiusData;

public void explosionRadius50(Entity creeper) {
    ExplosionRadiusData radiusData = creeper.get(ExplosionRadiusData.class).get();
    creeper.offer(radiusData.explosionRadius().setTo(50));
}

这样我们就获取到了这一 EntityExplosiveRadiusData 。我们就可以使用这一数据设置爬行者的爆炸半径为五十。然后我们需要把这一数据设置回爬行者身上,因为我们获取到的只是一个数据的副本。

也许我们想要给我们的实体设置一个自定义名称! DisplayNameData 就是用来完成这件事的。下面是一个示例:

import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.spongepowered.api.data.manipulator.mutable.DisplayNameData;

public void setDisplayName(Entity creeper) {
    DisplayNameData displayData = creeper.get(DisplayNameData.class).get();
    creeper.offer(displayData.displayName()
        .set(Component.text("Inscrutable", NamedTextColor.DARK_AQUA)));
}

此外,还有一种比较简短的方式来解决问题:通过使用 Keys 而不是 DataManipulator 。就像这样:

import org.spongepowered.api.data.key.Keys;

public void explosionRadius50(Entity creeper) {
    creeper.offer(Keys.EXPLOSION_RADIUS, Optional.of(50));
    creeper.offer(Keys.DISPLAY_NAME, Component.text("Inscrutable", NamedTextColor.DARK_AQUA));
}

This would neaten our code and is easier to perform. See the data documentation on the specific benefits of using either DataManipulators or just Keys.