我的世界forge模组开发(9)——自定义投掷物实体
mc中的物理
我们都知道现实生活中的物理现象,mc中也不例外,像掉落的沙子,掉落的投掷物,这些都属于物理现象。
在 Minecraft 1.20.1 中,一些常见的物理现象包括重力、水流、火的燃烧、植物生长等。这些物理现象通常在游戏中能够看到,并且对玩家的行为和环境造成影响。
在 Minecraft 的源代码中,相关的物理实现通常可以在不同的包中找到,具体取决于物理现象的类型。例如,重力相关的代码可能会在 net.minecraft.world.phys 包中,水流和火的燃烧可能会在 net.minecraft.world.level.block 包中。在代码中通常会有专门的类来处理特定的物理现象。
Minecraft 是通过一系列的游戏规则和算法来实现物理效果的。例如,重力会影响方块的掉落行为,水流会根据周围方块的情况进行流动,火会传播并燃烧可燃物体等。这些效果都是通过代码中的逻辑判断和状态更新来实现的,以模拟真实世界中的物理现象。
mc中的重力加速度
在Minecraft中,重力加速度是每tick 0.08个方块。
重力在Minecraft游戏中的代码通常在游戏引擎的源代码中。玩家通常无法直接修改重力加速度的数值,除非使用MOD或插件进行修改。玩家可以在游戏中通过观察物体下落的速度,以及玩家下落的速度来感受游戏中的重力效果。详情请看Wiki。不同的生物和实体有不同的重力加速度,研究重力加速度对于弹射物的弹道计算具有非常重要的意义。
mc的投掷物
在Minecraft中,原版投掷物种类丰富,开发Forge模组时可以通过继承和重写关键方法来自定义投掷物的物理属性和击中效果。以下是详细指南:
一、Minecraft原版投掷物类型
以下为常见的原版投掷物及其实现类:
二、自定义投掷物物理属性
1. 基础物理属性控制
继承`ThrowableItemProjectile`并重写以下方法:
public class CustomProjectile extends ThrowableItemProjectile {
// 构造函数省略...
@Override
protected float getGravity() {
return 0.05F; // 重力加速度(默认雪球为0.03F)
}
@Override
protected float getDrag() {
return 0.99F; // 空气阻力(值越小阻力越大,默认0.99)
}
@Override
public void tick() {
super.tick();
// 自定义运动逻辑(如抛物线轨迹)
if (!this.isNoGravity()) {
Vec3 vec3 = this.getDeltaMovement();
this.setDeltaMovement(vec3.x, vec3.y - this.getGravity(), vec3.z);
}
}
}
2. 投掷初速度与方向
在物品的`use`方法中控制投掷力度和角度:
public class CustomThrowableItem extends Item {
@Override
public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
ItemStack itemStack = player.getItemInHand(hand);
if (!level.isClientSide) {
CustomProjectile projectile = new CustomProjectile(level, player);
projectile.shootFromRotation(
player,
player.getXRot(), // 俯仰角
player.getYRot(), // 偏航角
0.0F, // 偏移角度
1.5F, // 速度
0.5F // 精度偏移(值越小越准)
);
level.addFreshEntity(projectile);
}
return InteractionResultHolder.sidedSuccess(itemStack, level.isClientSide());
}
}
三、自定义击中效果
1. 基础击中逻辑
重写`onHit`方法实现基础效果:
@Override
protected void onHit(HitResult result) {
super.onHit(result);
if (!this.level.isClientSide) {
if (result.getType() == HitResult.Type.ENTITY) {
// 对实体造成伤害
Entity target = ((EntityHitResult) result).getEntity();
target.hurt(this.damageSources().thrown(this, this.getOwner()), 5.0F);
}
// 生成爆炸效果
this.level.explode(null,
this.getX(), this.getY(), this.getZ(),
2.0F, Level.ExplosionInteraction.NONE
);
this.discard(); // 销毁投掷物
}
}
2. 高级效果:状态效果与粒子
结合事件监听器实现复杂逻辑:
@SubscribeEvent
public static void onProjectileImpact(ProjectileImpactEvent event) {
if (event.getProjectile() instanceof CustomProjectile) {
HitResult result = event.getRayTraceResult();
Level level = event.getProjectile().level;
// 生成紫色粒子
level.addParticle(
ParticleTypes.ENTITY_EFFECT,
result.getLocation().x,
result.getLocation().y,
result.getLocation().z,
0.5, 0.5, 0.5 // RGB颜色参数
);
// 给附近实体添加中毒效果
AABB area = new AABB(result.getLocation()).inflate(3.0);
List<LivingEntity> entities = level.getEntitiesOfClass(
LivingEntity.class, area
);
for (LivingEntity entity : entities) {
entity.addEffect(new MobEffectInstance(
MobEffects.POISON, 200, 1
));
}
}
}
四、完整开发流程
1. 注册实体与物品
// 实体注册
public static final RegistryObject<EntityType<CustomProjectile>> CUSTOM_PROJECTILE =
ENTITIES.register("custom_projectile",
() -> EntityType.Builder.of(CustomProjectile::new, MobCategory.MISC)
.sized(0.25F, 0.25F)
.build("custom_projectile")
);
// 物品注册
public static final RegistryObject<Item> CUSTOM_THROWABLE = ITEMS.register(
"custom_throwable",
() -> new CustomThrowableItem(new Item.Properties())
);
2. 客户端渲染绑定
@SubscribeEvent
public static void onClientSetup(FMLClientSetupEvent event) {
EntityRenderers.register(
ModEntities.CUSTOM_PROJECTILE.get(),
manager -> new ThrownItemRenderer<>(manager, 1.0F, false)
);
}
五、进阶技巧
• 穿透效果:在`tick()`中检测碰撞,通过`ProjectileImpactEvent.Result.DENY`取消默认销毁行为
• 跟踪目标:在`tick()`中使用`setDeltaMovement`调整方向,实现追踪导弹
• 多阶段爆炸:通过`Age`值判断存活时间,分阶段触发不同效果
通过结合物理计算与事件系统,开发者可以实现高度定制的投掷物行为,例如:
• 燃烧箭矢(持续点燃地面)
• 引力炸弹(吸引附近实体)
• 治疗弹(范围内恢复生命值)
建议参考`ThrowableItemProjectile`和`AbstractArrow`的源码,深入理解Minecraft的投射物系统。
ThrowableProjectile类
这段代码是 Minecraft 中 ThrowableProjectile 类的实现,用于定义可抛射物(如雪球、末影珍珠等)的通用行为。以下是对代码的逐部分解析