Завершить инженерную проверку этапа 2

This commit is contained in:
2026-08-18 13:54:48 +03:00
parent 3ad959dde0
commit 80822b74b1
17 changed files with 384 additions and 69 deletions
@@ -53,8 +53,12 @@ public final class GameView extends View implements Runnable {
private final float playerY;
private final int deaths;
private final int corpseCount;
private final float firstMovingPlatformX;
private final float firstMovingPlatformY;
private final boolean playerOnMovingPlatform;
private final boolean firstMovingPlatformPowered;
private final float firstCorpseX;
private final boolean playerOnGround;
AutomationSnapshot(boolean completed, boolean playerAlive, boolean allDoorsOpen,
boolean visiblyPaused, boolean inputActive, int levelNumber,
@@ -62,14 +66,17 @@ public final class GameView extends View implements Runnable {
float playerX, float playerY, int deaths, int corpseCount) {
this(completed, playerAlive, allDoorsOpen, visiblyPaused, inputActive, levelNumber,
elapsedMilliseconds, playerX, playerY, deaths, corpseCount,
Float.NaN, false);
Float.NaN, Float.NaN, false, false, Float.NaN, false);
}
AutomationSnapshot(boolean completed, boolean playerAlive, boolean allDoorsOpen,
boolean visiblyPaused, boolean inputActive, int levelNumber,
long elapsedMilliseconds,
float playerX, float playerY, int deaths, int corpseCount,
float firstMovingPlatformY, boolean playerOnMovingPlatform) {
float firstMovingPlatformX, float firstMovingPlatformY,
boolean playerOnMovingPlatform,
boolean firstMovingPlatformPowered, float firstCorpseX,
boolean playerOnGround) {
this.completed = completed;
this.playerAlive = playerAlive;
this.allDoorsOpen = allDoorsOpen;
@@ -81,8 +88,12 @@ public final class GameView extends View implements Runnable {
this.playerY = playerY;
this.deaths = deaths;
this.corpseCount = corpseCount;
this.firstMovingPlatformX = firstMovingPlatformX;
this.firstMovingPlatformY = firstMovingPlatformY;
this.playerOnMovingPlatform = playerOnMovingPlatform;
this.firstMovingPlatformPowered = firstMovingPlatformPowered;
this.firstCorpseX = firstCorpseX;
this.playerOnGround = playerOnGround;
}
public boolean completed() { return completed; }
@@ -96,8 +107,12 @@ public final class GameView extends View implements Runnable {
public float playerY() { return playerY; }
public int deaths() { return deaths; }
public int corpseCount() { return corpseCount; }
public float firstMovingPlatformX() { return firstMovingPlatformX; }
public float firstMovingPlatformY() { return firstMovingPlatformY; }
public boolean playerOnMovingPlatform() { return playerOnMovingPlatform; }
public boolean firstMovingPlatformPowered() { return firstMovingPlatformPowered; }
public float firstCorpseX() { return firstCorpseX; }
public boolean playerOnGround() { return playerOnGround; }
}
private static final class Player {
@@ -235,6 +250,8 @@ public final class GameView extends View implements Runnable {
respawnTimer = 0f;
cameraX = 0f;
userPaused = false;
pointers.clear();
deriveControls();
corpses.clear();
platformStates.clear();
toggleSignals.clear();
@@ -465,11 +482,29 @@ public final class GameView extends View implements Runnable {
resolveCorpseHorizontal(corpse);
corpse.y += corpse.vy * dt;
resolveCorpseVertical(corpse);
if (corpse.grounded && settleCorpseOnPressurePlate(corpse)) continue;
if (corpse.grounded) corpse.vx *= (float) Math.pow(0.05, dt);
if (Math.abs(corpse.vx) < 4f) corpse.vx = 0f;
}
}
private boolean settleCorpseOnPressurePlate(Corpse corpse) {
for (LevelDefinition.Switch item : level.switches) {
if (item.type != LevelDefinition.SwitchType.PRESSURE) continue;
if (!intersects(corpse.x, corpse.y, corpse.width, corpse.height, item.box)) continue;
if (item.box.width >= corpse.width) {
corpse.x = GameMath.clamp(corpse.x, item.box.x, item.box.right() - corpse.width);
} else {
corpse.x = item.box.x + (item.box.width - corpse.width) * 0.5f;
}
corpse.vx = 0f;
corpse.vy = 0f;
corpse.pinned = true;
return true;
}
return false;
}
private void resolveCorpseHorizontal(Corpse corpse) {
RectF current = corpse.rect();
for (RectF solid : solidRects(false)) {
@@ -1131,6 +1166,10 @@ public final class GameView extends View implements Runnable {
startLevel(oneBasedLevelNumber - 1);
}
public void restartLevelForAutomation() {
restartLevel();
}
public void setAutomationInput(boolean moveLeft, boolean moveRight, boolean jump) {
boolean jumpWasPressed = jumpPressed;
leftPressed = moveLeft;
@@ -1144,10 +1183,14 @@ public final class GameView extends View implements Runnable {
if (level != null) {
for (LevelDefinition.Door door : level.doors) allOpen &= doorOpen(door);
}
float firstMovingPlatformX = Float.NaN;
float firstMovingPlatformY = Float.NaN;
boolean firstMovingPlatformPowered = false;
for (PlatformState state : platformStates) {
if (state.definition.isMoving()) {
firstMovingPlatformX = state.x;
firstMovingPlatformY = state.y;
firstMovingPlatformPowered = signalActive(state.definition.controlId);
break;
}
}
@@ -1167,8 +1210,12 @@ public final class GameView extends View implements Runnable {
player.y,
deaths,
corpses.size(),
firstMovingPlatformX,
firstMovingPlatformY,
playerOnMovingPlatform
playerOnMovingPlatform,
firstMovingPlatformPowered,
corpses.isEmpty() ? Float.NaN : corpses.get(0).x,
player.onGround
);
}
}
@@ -109,12 +109,12 @@ public final class LevelCatalog {
8, "Borrowed Time", "Jump for the far blue relay if the timed gate closes.",
2450, 130, 760, goal(2220, 600), 0, 38,
platforms(
floor(0, 970), floor(1510, 940), ledge(1980, 710, 470),
moving(990, 770, 240, 34, 380, 0, 4.0f, "clock")
floor(0, 1040), floor(1510, 940), ledge(1980, 710, 470),
moving(910, 770, 320, 34, 380, 0, 4.0f, "clock")
),
hazards(hazard(PIT, 970, 880, 540, 200)),
hazards(hazard(PIT, 1040, 880, 470, 200)),
switches(
sw(TIMED, 560, 810, 90, 70, "clock", 6.0f, 1),
sw(TIMED, 560, 810, 90, 70, "clock", 8.0f, 1),
sw(TIMED, 1600, 650, 90, 70, "clock", 3.5f, 1)
),
doors(door(1770, 560, 82, 320, "clock"))
@@ -141,11 +141,11 @@ public final class LevelCatalog {
3100, 130, 760, goal(2880, 330), 3, 120,
platforms(
floor(0, 1940), floor(2140, 960), ledge(2420, 440, 680),
moving(1840, 790, 250, 34, 0, -410, 5.0f, "lift")
moving(1800, 790, 290, 34, 0, -410, 10.0f, "lift")
),
hazards(
hazard(SAW, 520, 760, 96, 96, null, 700, -240),
hazard(FREEZER, 1110, 750, 100, 130),
hazard(FREEZER, 1110, 776, 100, 104),
hazard(ELECTRIC, 1510, 780, 110, 100, "power", 0, 0),
hazard(PIT, 1940, 880, 200, 200)
),
@@ -144,6 +144,7 @@ public final class LevelPlaytestBot {
Step step = scenario.steps.get(stepIndex);
lastStep = step.name;
if (step.completion.reached(last)) {
driver.setInput(false, false, false);
stepIndex++;
stepStartedAt = driver.currentTimeMillis();
continue;