Keep jumps at natural sprint distance, grow new blocks out of the top of the previous one and show one more preview block
This commit is contained in:
1 parent
452f2f3ef7
commit
b1950dd664
2 files changed
+31
-18
No files matched your search
@@ -10,27 +10,35 @@ import net.minestom.server.instance.block.Block;
|
||||
import net.minestom.server.timer.TaskSchedule;
|
||||
|
||||
/**
|
||||
* Lässt einen neuen Block als Block-Display aus dem vorherigen Block „herauswachsen“ und
|
||||
* zu seiner Zielposition gleiten. Erst bei Ankunft wird der echte Block gesetzt.
|
||||
* Lässt einen neuen Block als Block-Display klein oben aus dem vorherigen Block herauswachsen
|
||||
* und zu seiner Zielposition gleiten. Erst bei Ankunft wird der echte Block gesetzt.
|
||||
*/
|
||||
public class BlockTransition {
|
||||
private static final int DURATION_TICKS = 8;
|
||||
public static final int DURATION_TICKS = 8;
|
||||
/** Zeit vom Start bis der echte Block steht (Spawn-Vorlauf + Animation + Puffer). */
|
||||
public static final int TOTAL_TICKS = DURATION_TICKS + 3;
|
||||
private static final double START_SCALE = 0.3;
|
||||
|
||||
public static void animate(Instance world, Pos from, Pos to, Block block, Runnable onArrival) {
|
||||
public static void animate(Instance world, Pos from, Pos to, Block block, int delayTicks, Runnable onArrival) {
|
||||
world.scheduler().buildTask(() -> spawn(world, from, to, block, onArrival))
|
||||
.delay(TaskSchedule.tick(Math.max(1, delayTicks)))
|
||||
.schedule();
|
||||
}
|
||||
|
||||
private static void spawn(Instance world, Pos from, Pos to, Block block, Runnable onArrival) {
|
||||
Entity display = new Entity(EntityType.BLOCK_DISPLAY);
|
||||
display.setNoGravity(true);
|
||||
display.editEntityMeta(BlockDisplayMeta.class, meta -> {
|
||||
meta.setBlockState(block);
|
||||
meta.setPosRotInterpolationDuration(DURATION_TICKS);
|
||||
meta.setTransformationInterpolationDuration(DURATION_TICKS);
|
||||
// klein und mittig im Ursprungsblock starten
|
||||
// klein und mittig auf der Oberseite des vorherigen Blocks starten
|
||||
meta.setScale(new Vec(START_SCALE));
|
||||
meta.setTranslation(new Vec((1 - START_SCALE) / 2));
|
||||
meta.setTranslation(new Vec((1 - START_SCALE) / 2, 1, (1 - START_SCALE) / 2));
|
||||
});
|
||||
|
||||
display.setInstance(world, from).thenRun(() -> {
|
||||
// einen Moment warten, damit der Client das Display kennt, bevor die Interpolation startet
|
||||
// kurz warten, damit der Client das Display kennt, bevor die Interpolation startet
|
||||
display.scheduler().buildTask(() -> {
|
||||
display.editEntityMeta(BlockDisplayMeta.class, meta -> {
|
||||
meta.setTransformationInterpolationStartDelta(0);
|
||||
@@ -43,7 +51,7 @@ public class BlockTransition {
|
||||
display.scheduler().buildTask(() -> {
|
||||
onArrival.run();
|
||||
display.remove();
|
||||
}).delay(TaskSchedule.tick(DURATION_TICKS + 3)).schedule();
|
||||
}).delay(TaskSchedule.tick(TOTAL_TICKS)).schedule();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ public class JumpGenerator {
|
||||
|
||||
private int combo = 0;
|
||||
|
||||
private final int preview = 2;
|
||||
private final int preview = 3;
|
||||
|
||||
private static final int FULL_DIFFICULTY_AT = 1000;
|
||||
|
||||
@@ -37,6 +37,10 @@ public class JumpGenerator {
|
||||
}
|
||||
|
||||
public void generateNext() {
|
||||
this.generateNext(0);
|
||||
}
|
||||
|
||||
private void generateNext(int animationDelayTicks) {
|
||||
boolean isTenth = this.blocks.size() % 10 == 0;
|
||||
boolean standingTenth = (this.blocks.size()-this.preview-1) % 10 == 0;
|
||||
boolean isHundredth = this.blocks.size() % 100 == 0;
|
||||
@@ -51,7 +55,7 @@ public class JumpGenerator {
|
||||
Pos previous = blocks.get(blocks.size()-1);
|
||||
Pos target = previous.add(this.nextOffset(index, r));
|
||||
Block block = isHundredth ? Block.DIAMOND_BLOCK : isTenth ? Block.GOLD_BLOCK : BlockPalette.getRandom(index, r);
|
||||
BlockTransition.animate(this.world, previous, target, block, () -> {
|
||||
BlockTransition.animate(this.world, previous, target, block, animationDelayTicks, () -> {
|
||||
this.world.setBlock(target, block);
|
||||
this.world.setBlock(target.add(0, 1, 0), Block.LIGHT);
|
||||
this.player.sendPacket(new ParticlePacket(Particle.CRIT, target, target.add(0.5), 1, 10));
|
||||
@@ -76,16 +80,15 @@ public class JumpGenerator {
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstand zum nächsten Block. Die Schwierigkeit steigt über die ersten {@link #FULL_DIFFICULTY_AT}
|
||||
* Sprünge von leicht (2–3 weit, kaum seitlich/aufwärts) bis zum bisherigen Niveau (3–4 weit,
|
||||
* oft seitlich und aufwärts) und bleibt danach dort.
|
||||
* Abstand zum nächsten Block. Sprünge sind immer mindestens 3 weit (natürliche Sprint-Weite,
|
||||
* kürzere werden überjumpt). Über die ersten {@link #FULL_DIFFICULTY_AT} Sprünge steigen der
|
||||
* Anteil an 4er-Sprüngen, seitlichen Versätzen und Sprüngen nach oben bis zum bisherigen
|
||||
* Niveau und bleiben danach dort.
|
||||
*/
|
||||
private Pos nextOffset(int index, Random r) {
|
||||
double difficulty = Math.min(1.0, (double) index / FULL_DIFFICULTY_AT);
|
||||
|
||||
int dz = 2;
|
||||
if(r.nextDouble() < 0.5 + 0.5 * difficulty) dz++;
|
||||
if(r.nextDouble() < 0.5 * difficulty) dz++;
|
||||
int dz = r.nextDouble() < 0.1 + 0.4 * difficulty ? 4 : 3;
|
||||
|
||||
int dx = r.nextDouble() < 0.1 + 0.57 * difficulty ? (r.nextBoolean() ? 1 : -1) : 0;
|
||||
|
||||
@@ -95,7 +98,8 @@ public class JumpGenerator {
|
||||
if(roll < 0.05 + 0.28 * difficulty && y <= 120) dy = 1;
|
||||
else if(roll > 1 - (0.2 + 0.13 * difficulty) && y >= 80) dy = -1;
|
||||
|
||||
// weite Diagonalsprünge nach oben erst gegen Ende
|
||||
// weite Sprünge nach oben erst ab mittlerer, diagonal erst ab hoher Schwierigkeit
|
||||
if(dy == 1 && dz == 4 && difficulty < 0.4) dz = 3;
|
||||
if(dy == 1 && dz == 4 && dx != 0 && difficulty < 0.7) dx = 0;
|
||||
|
||||
return new Pos(dx, dy, dz);
|
||||
@@ -111,7 +115,8 @@ public class JumpGenerator {
|
||||
this.checkpoint = start;
|
||||
this.blocks.add(this.starting);
|
||||
this.world.setBlock(this.starting, Block.DIAMOND_BLOCK);
|
||||
for(int i = 0; i <= preview; i++) generateNext();
|
||||
// nacheinander animieren, damit jeder Block aus seinem bereits stehenden Vorgänger wächst
|
||||
for(int i = 0; i <= preview; i++) generateNext(i * BlockTransition.TOTAL_TICKS);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
|
||||
Reference in new issue
Block a user