FireworkParticles.java
net.minecraft.client.particle.FireworkParticles
信息
- 全限定名:net.minecraft.client.particle.FireworkParticles
- 类型:public class
- 包:net.minecraft.client.particle
- 源码路径:src/main/java/net/minecraft/client/particle/FireworkParticles.java
- 起始行号:L25
- 职责:
TODO
字段/常量
- 无
内部类/嵌套类型
-
net.minecraft.client.particle.FireworkParticles.FlashProvider- 类型:
class - 修饰符:
public static - 源码定位:
L27 - 说明:
TODO
- 类型:
-
net.minecraft.client.particle.FireworkParticles.OverlayParticle- 类型:
class - 修饰符:
public static - 源码定位:
L45 - 说明:
TODO
- 类型:
-
net.minecraft.client.particle.FireworkParticles.SparkParticle- 类型:
class - 修饰符:
private static - 源码定位:
L69 - 说明:
TODO
- 类型:
-
net.minecraft.client.particle.FireworkParticles.SparkProvider- 类型:
class - 修饰符:
public static - 源码定位:
L128 - 说明:
TODO
- 类型:
-
net.minecraft.client.particle.FireworkParticles.Starter- 类型:
class - 修饰符:
public static - 源码定位:
L147 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
- 无
代码
@OnlyIn(Dist.CLIENT)
public class FireworkParticles {
@OnlyIn(Dist.CLIENT)
public static class FlashProvider implements ParticleProvider<ColorParticleOption> {
private final SpriteSet sprite;
public FlashProvider(SpriteSet sprite) {
this.sprite = sprite;
}
public Particle createParticle(
ColorParticleOption options, ClientLevel level, double x, double y, double z, double xAux, double yAux, double zAux, RandomSource random
) {
FireworkParticles.OverlayParticle particle = new FireworkParticles.OverlayParticle(level, x, y, z, this.sprite.get(random));
particle.setColor(options.getRed(), options.getGreen(), options.getBlue());
particle.setAlpha(options.getAlpha());
return particle;
}
}
@OnlyIn(Dist.CLIENT)
public static class OverlayParticle extends SingleQuadParticle {
private OverlayParticle(ClientLevel level, double x, double y, double z, TextureAtlasSprite sprite) {
super(level, x, y, z, sprite);
this.lifetime = 4;
}
@Override
public SingleQuadParticle.Layer getLayer() {
return SingleQuadParticle.Layer.TRANSLUCENT;
}
@Override
public void extract(QuadParticleRenderState particleTypeRenderState, Camera camera, float partialTickTime) {
this.setAlpha(0.6F - (this.age + partialTickTime - 1.0F) * 0.25F * 0.5F);
super.extract(particleTypeRenderState, camera, partialTickTime);
}
@Override
public float getQuadSize(float a) {
return 7.1F * Mth.sin((this.age + a - 1.0F) * 0.25F * (float) Math.PI);
}
}
@OnlyIn(Dist.CLIENT)
private static class SparkParticle extends SimpleAnimatedParticle {
private boolean trail;
private boolean twinkle;
private final ParticleEngine engine;
private float fadeR;
private float fadeG;
private float fadeB;
private boolean hasFade;
private SparkParticle(ClientLevel level, double x, double y, double z, double xa, double ya, double za, ParticleEngine engine, SpriteSet sprites) {
super(level, x, y, z, sprites, 0.1F);
this.xd = xa;
this.yd = ya;
this.zd = za;
this.engine = engine;
this.quadSize *= 0.75F;
this.lifetime = 48 + this.random.nextInt(12);
this.setSpriteFromAge(sprites);
}
public void setTrail(boolean trail) {
this.trail = trail;
}
public void setTwinkle(boolean twinkle) {
this.twinkle = twinkle;
}
@Override
public void extract(QuadParticleRenderState particleTypeRenderState, Camera camera, float partialTickTime) {
if (!this.twinkle || this.age < this.lifetime / 3 || (this.age + this.lifetime) / 3 % 2 == 0) {
super.extract(particleTypeRenderState, camera, partialTickTime);
}
}
@Override
public void tick() {
super.tick();
if (this.trail && this.age < this.lifetime / 2 && (this.age + this.lifetime) % 2 == 0) {
FireworkParticles.SparkParticle sparkParticle = new FireworkParticles.SparkParticle(
this.level, this.x, this.y, this.z, 0.0, 0.0, 0.0, this.engine, this.sprites
);
sparkParticle.setAlpha(0.99F);
sparkParticle.setColor(this.rCol, this.gCol, this.bCol);
sparkParticle.age = sparkParticle.lifetime / 2;
if (this.hasFade) {
sparkParticle.hasFade = true;
sparkParticle.fadeR = this.fadeR;
sparkParticle.fadeG = this.fadeG;
sparkParticle.fadeB = this.fadeB;
}
sparkParticle.twinkle = this.twinkle;
this.engine.add(sparkParticle);
}
}
}
@OnlyIn(Dist.CLIENT)
public static class SparkProvider implements ParticleProvider<SimpleParticleType> {
private final SpriteSet sprites;
public SparkProvider(SpriteSet sprites) {
this.sprites = sprites;
}
public Particle createParticle(
SimpleParticleType options, ClientLevel level, double x, double y, double z, double xAux, double yAux, double zAux, RandomSource random
) {
FireworkParticles.SparkParticle particle = new FireworkParticles.SparkParticle(
level, x, y, z, xAux, yAux, zAux, Minecraft.getInstance().particleEngine, this.sprites
);
particle.setAlpha(0.99F);
return particle;
}
}
@OnlyIn(Dist.CLIENT)
public static class Starter extends NoRenderParticle {
private static final double[][] CREEPER_PARTICLE_COORDS = new double[][]{
{0.0, 0.2}, {0.2, 0.2}, {0.2, 0.6}, {0.6, 0.6}, {0.6, 0.2}, {0.2, 0.2}, {0.2, 0.0}, {0.4, 0.0}, {0.4, -0.6}, {0.2, -0.6}, {0.2, -0.4}, {0.0, -0.4}
};
private static final double[][] STAR_PARTICLE_COORDS = new double[][]{
{0.0, 1.0},
{0.3455, 0.309},
{0.9511, 0.309},
{0.3795918367346939, -0.12653061224489795},
{0.6122448979591837, -0.8040816326530612},
{0.0, -0.35918367346938773}
};
private int life;
private final ParticleEngine engine;
private final List<FireworkExplosion> explosions;
private boolean twinkleDelay;
public Starter(
ClientLevel level, double x, double y, double z, double xd, double yd, double zd, ParticleEngine engine, List<FireworkExplosion> explosions
) {
super(level, x, y, z);
this.xd = xd;
this.yd = yd;
this.zd = zd;
this.engine = engine;
if (explosions.isEmpty()) {
throw new IllegalArgumentException("Cannot create firework starter with no explosions");
} else {
this.explosions = explosions;
this.lifetime = explosions.size() * 2 - 1;
for (FireworkExplosion explosion : explosions) {
if (explosion.hasTwinkle()) {
this.twinkleDelay = true;
this.lifetime += 15;
break;
}
}
}
}
@Override
public void tick() {
if (this.life == 0) {
boolean farEffect = this.isFarAwayFromCamera();
boolean largeExplosion = false;
if (this.explosions.size() >= 3) {
largeExplosion = true;
} else {
for (FireworkExplosion explosion : this.explosions) {
if (explosion.shape() == FireworkExplosion.Shape.LARGE_BALL) {
largeExplosion = true;
break;
}
}
}
SoundEvent sound;
if (largeExplosion) {
sound = farEffect ? SoundEvents.FIREWORK_ROCKET_LARGE_BLAST_FAR : SoundEvents.FIREWORK_ROCKET_LARGE_BLAST;
} else {
sound = farEffect ? SoundEvents.FIREWORK_ROCKET_BLAST_FAR : SoundEvents.FIREWORK_ROCKET_BLAST;
}
this.level.playLocalSound(this.x, this.y, this.z, sound, SoundSource.AMBIENT, 20.0F, 0.95F + this.random.nextFloat() * 0.1F, true);
}
if (this.life % 2 == 0 && this.life / 2 < this.explosions.size()) {
int eIndex = this.life / 2;
FireworkExplosion explosionx = this.explosions.get(eIndex);
boolean trail = explosionx.hasTrail();
boolean twinkle = explosionx.hasTwinkle();
IntList colors = explosionx.colors();
IntList fadeColors = explosionx.fadeColors();
if (colors.isEmpty()) {
colors = IntList.of(DyeColor.BLACK.getFireworkColor());
}
switch (explosionx.shape()) {
case SMALL_BALL:
this.createParticleBall(0.25, 2, colors, fadeColors, trail, twinkle);
break;
case LARGE_BALL:
this.createParticleBall(0.5, 4, colors, fadeColors, trail, twinkle);
break;
case STAR:
this.createParticleShape(0.5, STAR_PARTICLE_COORDS, colors, fadeColors, trail, twinkle, false);
break;
case CREEPER:
this.createParticleShape(0.5, CREEPER_PARTICLE_COORDS, colors, fadeColors, trail, twinkle, true);
break;
case BURST:
this.createParticleBurst(colors, fadeColors, trail, twinkle);
}
int color = colors.getInt(0);
this.engine.createParticle(ColorParticleOption.create(ParticleTypes.FLASH, color), this.x, this.y, this.z, 0.0, 0.0, 0.0);
}
this.life++;
if (this.life > this.lifetime) {
if (this.twinkleDelay) {
boolean farEffectx = this.isFarAwayFromCamera();
SoundEvent sound = farEffectx ? SoundEvents.FIREWORK_ROCKET_TWINKLE_FAR : SoundEvents.FIREWORK_ROCKET_TWINKLE;
this.level.playLocalSound(this.x, this.y, this.z, sound, SoundSource.AMBIENT, 20.0F, 0.9F + this.random.nextFloat() * 0.15F, true);
}
this.remove();
}
}
private boolean isFarAwayFromCamera() {
Minecraft instance = Minecraft.getInstance();
return instance.gameRenderer.getMainCamera().position().distanceToSqr(this.x, this.y, this.z) >= 256.0;
}
private void createParticle(
double x, double y, double z, double xa, double ya, double za, IntList rgbColors, IntList fadeColors, boolean trail, boolean twinkle
) {
FireworkParticles.SparkParticle sparkParticle = (FireworkParticles.SparkParticle)this.engine
.createParticle(ParticleTypes.FIREWORK, x, y, z, xa, ya, za);
sparkParticle.setTrail(trail);
sparkParticle.setTwinkle(twinkle);
sparkParticle.setAlpha(0.99F);
sparkParticle.setColor(Util.getRandom(rgbColors, this.random));
if (!fadeColors.isEmpty()) {
sparkParticle.setFadeColor(Util.getRandom(fadeColors, this.random));
}
}
private void createParticleBall(double baseSpeed, int steps, IntList rgbColors, IntList fadeColors, boolean trail, boolean twinkle) {
double xx = this.x;
double yy = this.y;
double zz = this.z;
for (int yStep = -steps; yStep <= steps; yStep++) {
for (int xStep = -steps; xStep <= steps; xStep++) {
for (int zStep = -steps; zStep <= steps; zStep++) {
double xa = xStep + (this.random.nextDouble() - this.random.nextDouble()) * 0.5;
double ya = yStep + (this.random.nextDouble() - this.random.nextDouble()) * 0.5;
double za = zStep + (this.random.nextDouble() - this.random.nextDouble()) * 0.5;
double len = Math.sqrt(xa * xa + ya * ya + za * za) / baseSpeed + this.random.nextGaussian() * 0.05;
this.createParticle(xx, yy, zz, xa / len, ya / len, za / len, rgbColors, fadeColors, trail, twinkle);
if (yStep != -steps && yStep != steps && xStep != -steps && xStep != steps) {
zStep += steps * 2 - 1;
}
}
}
}
}
private void createParticleShape(
double baseSpeed, double[][] coords, IntList rgbColors, IntList fadeColors, boolean trail, boolean twinkle, boolean flat
) {
double sx = coords[0][0];
double sy = coords[0][1];
this.createParticle(this.x, this.y, this.z, sx * baseSpeed, sy * baseSpeed, 0.0, rgbColors, fadeColors, trail, twinkle);
float baseAngle = this.random.nextFloat() * (float) Math.PI;
double angleMod = flat ? 0.034 : 0.34;
for (int angleStep = 0; angleStep < 3; angleStep++) {
double angle = baseAngle + angleStep * (float) Math.PI * angleMod;
double ox = sx;
double oy = sy;
for (int c = 1; c < coords.length; c++) {
double tx = coords[c][0];
double ty = coords[c][1];
for (double subStep = 0.25; subStep <= 1.0; subStep += 0.25) {
double xa = Mth.lerp(subStep, ox, tx) * baseSpeed;
double ya = Mth.lerp(subStep, oy, ty) * baseSpeed;
double za = xa * Math.sin(angle);
xa *= Math.cos(angle);
for (double flip = -1.0; flip <= 1.0; flip += 2.0) {
this.createParticle(this.x, this.y, this.z, xa * flip, ya, za * flip, rgbColors, fadeColors, trail, twinkle);
}
}
ox = tx;
oy = ty;
}
}
}
private void createParticleBurst(IntList rgbColors, IntList fadeColors, boolean trail, boolean twinkle) {
double baseOffX = this.random.nextGaussian() * 0.05;
double baseOffZ = this.random.nextGaussian() * 0.05;
for (int i = 0; i < 70; i++) {
double xa = this.xd * 0.5 + this.random.nextGaussian() * 0.15 + baseOffX;
double za = this.zd * 0.5 + this.random.nextGaussian() * 0.15 + baseOffZ;
double ya = this.yd * 0.5 + this.random.nextDouble() * 0.5;
this.createParticle(this.x, this.y, this.z, xa, ya, za, rgbColors, fadeColors, trail, twinkle);
}
}
}
}引用的其他类
-
- 引用位置:
方法调用 - 关联成员:
Minecraft.getInstance()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ColorParticleOption.create()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.lerp(), Mth.sin()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.getRandom()
- 引用位置: