Particle.java

net.minecraft.client.particle.Particle

信息

  • 全限定名:net.minecraft.client.particle.Particle
  • 类型:public abstract class
  • 包:net.minecraft.client.particle
  • 源码路径:src/main/java/net/minecraft/client/particle/Particle.java
  • 起始行号:L18
  • 职责:

    TODO

字段/常量

  • INITIAL_AABB

    • 类型: AABB
    • 修饰符: private static final
    • 源码定位: L19
    • 说明:

      TODO

  • MAXIMUM_COLLISION_VELOCITY_SQUARED

    • 类型: double
    • 修饰符: private static final
    • 源码定位: L20
    • 说明:

      TODO

  • level

    • 类型: ClientLevel
    • 修饰符: protected final
    • 源码定位: L21
    • 说明:

      TODO

  • xo

    • 类型: double
    • 修饰符: protected
    • 源码定位: L22
    • 说明:

      TODO

  • yo

    • 类型: double
    • 修饰符: protected
    • 源码定位: L23
    • 说明:

      TODO

  • zo

    • 类型: double
    • 修饰符: protected
    • 源码定位: L24
    • 说明:

      TODO

  • x

    • 类型: double
    • 修饰符: protected
    • 源码定位: L25
    • 说明:

      TODO

  • y

    • 类型: double
    • 修饰符: protected
    • 源码定位: L26
    • 说明:

      TODO

  • z

    • 类型: double
    • 修饰符: protected
    • 源码定位: L27
    • 说明:

      TODO

  • xd

    • 类型: double
    • 修饰符: protected
    • 源码定位: L28
    • 说明:

      TODO

  • yd

    • 类型: double
    • 修饰符: protected
    • 源码定位: L29
    • 说明:

      TODO

  • zd

    • 类型: double
    • 修饰符: protected
    • 源码定位: L30
    • 说明:

      TODO

  • bb

    • 类型: AABB
    • 修饰符: private
    • 源码定位: L31
    • 说明:

      TODO

  • onGround

    • 类型: boolean
    • 修饰符: protected
    • 源码定位: L32
    • 说明:

      TODO

  • hasPhysics

    • 类型: boolean
    • 修饰符: protected
    • 源码定位: L33
    • 说明:

      TODO

  • stoppedByCollision

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L34
    • 说明:

      TODO

  • removed

    • 类型: boolean
    • 修饰符: protected
    • 源码定位: L35
    • 说明:

      TODO

  • bbWidth

    • 类型: float
    • 修饰符: protected
    • 源码定位: L36
    • 说明:

      TODO

  • bbHeight

    • 类型: float
    • 修饰符: protected
    • 源码定位: L37
    • 说明:

      TODO

  • random

    • 类型: RandomSource
    • 修饰符: protected final
    • 源码定位: L38
    • 说明:

      TODO

  • age

    • 类型: int
    • 修饰符: protected
    • 源码定位: L39
    • 说明:

      TODO

  • lifetime

    • 类型: int
    • 修饰符: protected
    • 源码定位: L40
    • 说明:

      TODO

  • gravity

    • 类型: float
    • 修饰符: protected
    • 源码定位: L41
    • 说明:

      TODO

  • friction

    • 类型: float
    • 修饰符: protected
    • 源码定位: L42
    • 说明:

      TODO

  • speedUpWhenYMotionIsBlocked

    • 类型: boolean
    • 修饰符: protected
    • 源码定位: L43
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.particle.Particle.LifetimeAlpha
    • 类型: record
    • 修饰符: public
    • 源码定位: L209
    • 说明:

      TODO

构造器

protected Particle(ClientLevel level, double x, double y, double z) @ L45

  • 构造器名:Particle
  • 源码定位:L45
  • 修饰符:protected

参数:

  • level: ClientLevel
  • x: double
  • y: double
  • z: double

说明:

TODO

public Particle(ClientLevel level, double x, double y, double z, double xa, double ya, double za) @ L55

  • 构造器名:Particle
  • 源码定位:L55
  • 修饰符:public

参数:

  • level: ClientLevel
  • x: double
  • y: double
  • z: double
  • xa: double
  • ya: double
  • za: double

说明:

TODO

方法

下面的方法块按源码顺序生成。

public Particle setPower(float power) @ L67

  • 方法名:setPower
  • 源码定位:L67
  • 返回类型:Particle
  • 修饰符:public

参数:

  • power: float

说明:

TODO

public void setParticleSpeed(double xd, double yd, double zd) @ L74

  • 方法名:setParticleSpeed
  • 源码定位:L74
  • 返回类型:void
  • 修饰符:public

参数:

  • xd: double
  • yd: double
  • zd: double

说明:

TODO

public Particle scale(float scale) @ L80

  • 方法名:scale
  • 源码定位:L80
  • 返回类型:Particle
  • 修饰符:public

参数:

  • scale: float

说明:

TODO

public void setLifetime(int lifetime) @ L85

  • 方法名:setLifetime
  • 源码定位:L85
  • 返回类型:void
  • 修饰符:public

参数:

  • lifetime: int

说明:

TODO

public int getLifetime() @ L89

  • 方法名:getLifetime
  • 源码定位:L89
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void tick() @ L93

  • 方法名:tick
  • 源码定位:L93
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public abstract ParticleRenderType getGroup() @ L117

  • 方法名:getGroup
  • 源码定位:L117
  • 返回类型:ParticleRenderType
  • 修饰符:public abstract

参数:

说明:

TODO

public String toString() @ L119

  • 方法名:toString
  • 源码定位:L119
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public void remove() @ L124

  • 方法名:remove
  • 源码定位:L124
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

protected void setSize(float w, float h) @ L128

  • 方法名:setSize
  • 源码定位:L128
  • 返回类型:void
  • 修饰符:protected

参数:

  • w: float
  • h: float

说明:

TODO

public void setPos(double x, double y, double z) @ L139

  • 方法名:setPos
  • 源码定位:L139
  • 返回类型:void
  • 修饰符:public

参数:

  • x: double
  • y: double
  • z: double

说明:

TODO

public void move(double xa, double ya, double za) @ L148

  • 方法名:move
  • 源码定位:L148
  • 返回类型:void
  • 修饰符:public

参数:

  • xa: double
  • ya: double
  • za: double

说明:

TODO

protected void setLocationFromBoundingbox() @ L180

  • 方法名:setLocationFromBoundingbox
  • 源码定位:L180
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected int getLightCoords(float a) @ L187

  • 方法名:getLightCoords
  • 源码定位:L187
  • 返回类型:int
  • 修饰符:protected

参数:

  • a: float

说明:

TODO

public boolean isAlive() @ L192

  • 方法名:isAlive
  • 源码定位:L192
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public AABB getBoundingBox() @ L196

  • 方法名:getBoundingBox
  • 源码定位:L196
  • 返回类型:AABB
  • 修饰符:public

参数:

说明:

TODO

public void setBoundingBox(AABB bb) @ L200

  • 方法名:setBoundingBox
  • 源码定位:L200
  • 返回类型:void
  • 修饰符:public

参数:

  • bb: AABB

说明:

TODO

public Optional<ParticleLimit> getParticleLimit() @ L204

  • 方法名:getParticleLimit
  • 源码定位:L204
  • 返回类型:Optional
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public abstract class Particle {
    private static final AABB INITIAL_AABB = new AABB(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
    private static final double MAXIMUM_COLLISION_VELOCITY_SQUARED = Mth.square(100.0);
    protected final ClientLevel level;
    protected double xo;
    protected double yo;
    protected double zo;
    protected double x;
    protected double y;
    protected double z;
    protected double xd;
    protected double yd;
    protected double zd;
    private AABB bb = INITIAL_AABB;
    protected boolean onGround;
    protected boolean hasPhysics = true;
    private boolean stoppedByCollision;
    protected boolean removed;
    protected float bbWidth = 0.6F;
    protected float bbHeight = 1.8F;
    protected final RandomSource random = RandomSource.create();
    protected int age;
    protected int lifetime;
    protected float gravity;
    protected float friction = 0.98F;
    protected boolean speedUpWhenYMotionIsBlocked = false;
 
    protected Particle(ClientLevel level, double x, double y, double z) {
        this.level = level;
        this.setSize(0.2F, 0.2F);
        this.setPos(x, y, z);
        this.xo = x;
        this.yo = y;
        this.zo = z;
        this.lifetime = (int)(4.0F / (this.random.nextFloat() * 0.9F + 0.1F));
    }
 
    public Particle(ClientLevel level, double x, double y, double z, double xa, double ya, double za) {
        this(level, x, y, z);
        this.xd = xa + (this.random.nextFloat() * 2.0F - 1.0F) * 0.4F;
        this.yd = ya + (this.random.nextFloat() * 2.0F - 1.0F) * 0.4F;
        this.zd = za + (this.random.nextFloat() * 2.0F - 1.0F) * 0.4F;
        double speed = (this.random.nextFloat() + this.random.nextFloat() + 1.0F) * 0.15F;
        double dd = Math.sqrt(this.xd * this.xd + this.yd * this.yd + this.zd * this.zd);
        this.xd = this.xd / dd * speed * 0.4F;
        this.yd = this.yd / dd * speed * 0.4F + 0.1F;
        this.zd = this.zd / dd * speed * 0.4F;
    }
 
    public Particle setPower(float power) {
        this.xd *= power;
        this.yd = (this.yd - 0.1F) * power + 0.1F;
        this.zd *= power;
        return this;
    }
 
    public void setParticleSpeed(double xd, double yd, double zd) {
        this.xd = xd;
        this.yd = yd;
        this.zd = zd;
    }
 
    public Particle scale(float scale) {
        this.setSize(0.2F * scale, 0.2F * scale);
        return this;
    }
 
    public void setLifetime(int lifetime) {
        this.lifetime = lifetime;
    }
 
    public int getLifetime() {
        return this.lifetime;
    }
 
    public void tick() {
        this.xo = this.x;
        this.yo = this.y;
        this.zo = this.z;
        if (this.age++ >= this.lifetime) {
            this.remove();
        } else {
            this.yd = this.yd - 0.04 * this.gravity;
            this.move(this.xd, this.yd, this.zd);
            if (this.speedUpWhenYMotionIsBlocked && this.y == this.yo) {
                this.xd *= 1.1;
                this.zd *= 1.1;
            }
 
            this.xd = this.xd * this.friction;
            this.yd = this.yd * this.friction;
            this.zd = this.zd * this.friction;
            if (this.onGround) {
                this.xd *= 0.7F;
                this.zd *= 0.7F;
            }
        }
    }
 
    public abstract ParticleRenderType getGroup();
 
    @Override
    public String toString() {
        return this.getClass().getSimpleName() + ", Pos (" + this.x + "," + this.y + "," + this.z + "), Age " + this.age;
    }
 
    public void remove() {
        this.removed = true;
    }
 
    protected void setSize(float w, float h) {
        if (w != this.bbWidth || h != this.bbHeight) {
            this.bbWidth = w;
            this.bbHeight = h;
            AABB aabb = this.getBoundingBox();
            double newMinX = (aabb.minX + aabb.maxX - w) / 2.0;
            double newMinZ = (aabb.minZ + aabb.maxZ - w) / 2.0;
            this.setBoundingBox(new AABB(newMinX, aabb.minY, newMinZ, newMinX + this.bbWidth, aabb.minY + this.bbHeight, newMinZ + this.bbWidth));
        }
    }
 
    public void setPos(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
        float w = this.bbWidth / 2.0F;
        float h = this.bbHeight;
        this.setBoundingBox(new AABB(x - w, y, z - w, x + w, y + h, z + w));
    }
 
    public void move(double xa, double ya, double za) {
        if (!this.stoppedByCollision) {
            double originalXa = xa;
            double originalYa = ya;
            double originalZa = za;
            if (this.hasPhysics && (xa != 0.0 || ya != 0.0 || za != 0.0) && xa * xa + ya * ya + za * za < MAXIMUM_COLLISION_VELOCITY_SQUARED) {
                Vec3 movement = Entity.collideBoundingBox(null, new Vec3(xa, ya, za), this.getBoundingBox(), this.level, List.of());
                xa = movement.x;
                ya = movement.y;
                za = movement.z;
            }
 
            if (xa != 0.0 || ya != 0.0 || za != 0.0) {
                this.setBoundingBox(this.getBoundingBox().move(xa, ya, za));
                this.setLocationFromBoundingbox();
            }
 
            if (Math.abs(originalYa) >= 1.0E-5F && Math.abs(ya) < 1.0E-5F) {
                this.stoppedByCollision = true;
            }
 
            this.onGround = originalYa != ya && originalYa < 0.0;
            if (originalXa != xa) {
                this.xd = 0.0;
            }
 
            if (originalZa != za) {
                this.zd = 0.0;
            }
        }
    }
 
    protected void setLocationFromBoundingbox() {
        AABB aabb = this.getBoundingBox();
        this.x = (aabb.minX + aabb.maxX) / 2.0;
        this.y = aabb.minY;
        this.z = (aabb.minZ + aabb.maxZ) / 2.0;
    }
 
    protected int getLightCoords(float a) {
        BlockPos pos = BlockPos.containing(this.x, this.y, this.z);
        return this.level.hasChunkAt(pos) ? LevelRenderer.getLightCoords(this.level, pos) : 15728640;
    }
 
    public boolean isAlive() {
        return !this.removed;
    }
 
    public AABB getBoundingBox() {
        return this.bb;
    }
 
    public void setBoundingBox(AABB bb) {
        this.bb = bb;
    }
 
    public Optional<ParticleLimit> getParticleLimit() {
        return Optional.empty();
    }
 
    @OnlyIn(Dist.CLIENT)
    public record LifetimeAlpha(float startAlpha, float endAlpha, float startAtNormalizedAge, float endAtNormalizedAge) {
        public static final Particle.LifetimeAlpha ALWAYS_OPAQUE = new Particle.LifetimeAlpha(1.0F, 1.0F, 0.0F, 1.0F);
 
        public boolean isOpaque() {
            return this.startAlpha >= 1.0F && this.endAlpha >= 1.0F;
        }
 
        public float currentAlphaForAge(int age, int lifetime, float partialTickTime) {
            if (Mth.equal(this.startAlpha, this.endAlpha)) {
                return this.startAlpha;
            } else {
                float timeNormalized = Mth.inverseLerp((age + partialTickTime) / lifetime, this.startAtNormalizedAge, this.endAtNormalizedAge);
                return Mth.clampedLerp(timeNormalized, this.startAlpha, this.endAlpha);
            }
        }
    }
}

引用的其他类

  • ClientLevel

    • 引用位置: 参数/字段
  • ParticleRenderType

    • 引用位置: 返回值
  • LevelRenderer

    • 引用位置: 方法调用
    • 关联成员: LevelRenderer.getLightCoords()
  • BlockPos

    • 引用位置: 方法调用
    • 关联成员: BlockPos.containing()
  • ParticleLimit

    • 引用位置: 返回值
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.clampedLerp(), Mth.equal(), Mth.inverseLerp(), Mth.square()
  • RandomSource

    • 引用位置: 字段/方法调用
    • 关联成员: RandomSource.create()
  • Entity

    • 引用位置: 方法调用
    • 关联成员: Entity.collideBoundingBox()
  • AABB

    • 引用位置: 参数/字段/构造调用/返回值
    • 关联成员: AABB()
  • Vec3

    • 引用位置: 构造调用
    • 关联成员: Vec3()