修改一个实体
确实,在世界上生成一个常规的实体已经足够了,不过,有没有什么更有趣的东西呢?这时候就需要 DataManipulator 大显身手了。一个 Entity 同时也是一个 DataHolder ,也就是说一个实体可以存储数据。关于 DataHolder
的更多信息请参见 这里 。
常见的适用于实体的 DataManipulator
有 FoodData 以及 HealthData 等。我们可以在 org.spongepowered.api.data.manipulator.mutable 和 org.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) {
if (entity.getType().equals(EntityTypes.CREEPER)) {
return true;
}
return false;
}
操作实体数据
现在我们清楚这么一个 Entity
是一个爬行者了,那么我们就可以使用适用于爬行者的特殊 DataManipulator
,比如 ExplosionRadiusData 。爬行者拥有这一数据,而并非每个实体都拥有。把一个实体的爆炸半径设置成五十的示例如下:
import org.spongepowered.api.data.manipulator.mutable.entity.ExplosiveRadiusData;
public void explosionRadius50(Entity creeper) {
ExplosiveRadiusData radiusData = creeper.get(ExplosiveRadiusData.class).get();
creeper.offer(radiusData.explosiveRadius().set(50));
}
这样我们就获取到了这一 Entity
的 ExplosiveRadiusData
。我们就可以使用这一数据设置爬行者的爆炸半径为五十。然后我们需要把这一数据设置回爬行者身上,因为我们获取到的只是一个数据的副本。
也许我们想要给我们的实体设置一个自定义名称! DisplayNameData 就是用来完成这件事的。下面是一个示例:
import org.spongepowered.api.data.manipulator.mutable.DisplayNameData;
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.format.TextColors;
public void setDisplayName(Entity creeper) {
DisplayNameData displayData = creeper.get(DisplayNameData.class).get();
creeper.offer(displayData.displayName().set(Text.of(TextColors.DARK_AQUA,
"Inscrutable")));
}
此外,还有一种比较简短的方式来解决问题:通过使用 Keys 而不是 DataManipulator
。就像这样:
import org.spongepowered.api.data.key.Keys;
public void explosionRadius50(Entity creeper) {
creeper.offer(Keys.EXPLOSIVE_RADIUS, 50);
creeper.offer(Keys.DISPLAY_NAME, Text.of(TextColors.DARK_AQUA, "Inscrutable"));
}
代码变得更加整洁了,并且执行也变得更加容易了。参见 data documentation 以比较 DataManipulator
和 Keys
的优缺点。