伤害数字粒子

基本信息

属性 值
实现类 net.torocraft.torohealthmod.client.particle.DamageParticles(extends EntityFX)
触发点 LivingEvent.LivingUpdateEvent,EventPriority.LOW,仅 isRemote(ToroHealthEventHandler.java:14-17)
触发条件 实体血量(floor 后)发生变化,且上一帧血量不是 -1(未初始化),且上一帧最大血量 == 当前最大血量(ToroHealthEventHandler.java:35)
图层 getFXLayer() 返回 3(DamageParticles.java:140-142)

数值

参数 值 源码
GRAVITY 0.1F DamageParticles.java:17
LIFESPAN(particleMaxAge) 12 tick DamageParticles.java:18、35
初始 particleScale ConfigurationHandler.size(默认 3.0) DamageParticles.java:33
水平初速 rand.nextGaussian() * 0.02 DamageParticles.java:42、44
垂直初速 0.5f DamageParticles.java:43
生成高度 entity.posY + entity.height DamageParticles.java:49
放大阶段每 tick 倍率 * 1.1664F,直到 particleScale > size * 3.0 DamageParticles.java:130-134
缩小阶段每 tick 倍率 * 0.8573F DamageParticles.java:136

粒子先放大到配置 size 的 3 倍(默认 9.0),再开始缩小,LIFESPAN = 12 tick 后消失。 放大/缩小的分界点由 size 配置决定,不是固定常数。

颜色语义

DamageParticles.java:37:

this.color = damage < 0 ? ConfigurationHandler.healColor : ConfigurationHandler.damageColor;
  • damage < 0(回血)→ healColor(配置默认 GREEN → 0x00FF00)
  • damage >= 0(受伤)→ damageColor(配置默认 RED → 0xFF0000)

显示文本是 Integer.toString(Math.abs(damage))(DamageParticles.java:36), 即永远是正数,不带正负号,方向只能靠颜色区分。渲染时偏移量取 fontRenderer.getStringWidth(text) / 2 做居中(DamageParticles.java:114)。

可见性过滤

isEntityNotVisible(DamageParticles.java:57-83)依次判定,返回 true 则不生成:

条件 源码
entity.isInvisibleToPlayer(player) DamageParticles.java:59-61
distSq > 64D * 64D(距离超过 64 格) DamageParticles.java:62-66
距离 > 25D(5 格)且实体在玩家背后(点乘 < 0,第三人称反向视角用 -1D 修正) DamageParticles.java:71-78
showThroughWalls == false 且玩家到实体的射线被方块挡住 DamageParticles.java:79-80

⚠️ 距离阈值写法不一致:64D * 64D 与 25D 都是距离平方,所以实际生效的是 64 格与 5 格。第二条(5 格内不判定"在背后")在 distSq > 25D 才进入,等于 5 格内无视朝向。源码未给这两处常量任何命名或注释。

渲染

renderParticle(DamageParticles.java:85-124)关闭光照与深度测试, 用 SRC_ALPHA / ONE_MINUS_SRC_ALPHA 混合,drawStringWithShadow 画字, 结束后逐项恢复 GL 状态。整体按玩家视角旋转(第一人称用玩家 yaw/pitch, 第三人称反向 thirdPersonView == 2 时 yaw +180F、pitch 取负,DamageParticles.java:96-102)。 缩放时 x/y 取 -f1、z 取 f1,即镜像翻转(DamageParticles.java:110)。

血量快照来源

prevHealth / prevMaxHealth 不是原版字段,而是由本 mod 自己维护的两个 @Unique 字段, 通过 early mixin 注入 EntityLivingBase(mixins/early/MixinEntityLivingBase.java:12-16, 接口 mixins/interfaces/EntityLivingBaseExt.java)。初值为 -1,用作"刚生成"的哨兵值 (ToroHealthEventHandler.java:32)。该 mixin 仅在客户端加载 (MixinLoadingPlugin.java:47-49)。