Выделить CorpseManager
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.projectsacrifice.game;
|
||||
|
||||
import com.projectsacrifice.game.CorpseManager.Body;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
@@ -190,18 +192,6 @@ public final class GameView extends View implements Runnable {
|
||||
int facing = 1;
|
||||
}
|
||||
|
||||
private static final class Corpse {
|
||||
float x, y, width = 72f, height = 54f, vx, vy;
|
||||
boolean frozen;
|
||||
boolean conductive;
|
||||
boolean pinned;
|
||||
boolean grounded;
|
||||
int supportIndex = -1;
|
||||
DeathType type;
|
||||
|
||||
RectF rect() { return new RectF(x, y, x + width, y + height); }
|
||||
}
|
||||
|
||||
private static final class PlatformState {
|
||||
float x, y, previousX, previousY, motionTime;
|
||||
final LevelDefinition.Platform definition;
|
||||
@@ -235,7 +225,8 @@ public final class GameView extends View implements Runnable {
|
||||
private final Player player = new Player();
|
||||
private final CharacterStateMachine characterStateMachine =
|
||||
new CharacterStateMachine(PHYSICS);
|
||||
private final ArrayList<Corpse> corpses = new ArrayList<>();
|
||||
private final CorpseManager corpseManager = new CorpseManager(MAX_CORPSES);
|
||||
private final List<Body> corpses = corpseManager.bodies();
|
||||
private final ArrayList<PlatformState> platformStates = new ArrayList<>();
|
||||
private final Map<String, Boolean> toggleSignals = new HashMap<>();
|
||||
private final Map<String, Float> timedSignals = new HashMap<>();
|
||||
@@ -400,7 +391,7 @@ public final class GameView extends View implements Runnable {
|
||||
userPaused = false;
|
||||
pointers.clear();
|
||||
deriveControls();
|
||||
corpses.clear();
|
||||
corpseManager.reset();
|
||||
platformStates.clear();
|
||||
toggleSignals.clear();
|
||||
timedSignals.clear();
|
||||
@@ -517,7 +508,7 @@ public final class GameView extends View implements Runnable {
|
||||
private boolean switchContact(LevelDefinition.Switch item) {
|
||||
int mass = 0;
|
||||
if (player.alive && intersects(player.x, player.y, PLAYER_WIDTH, PLAYER_HEIGHT, item.box)) mass++;
|
||||
for (Corpse corpse : corpses) {
|
||||
for (Body corpse : corpses) {
|
||||
if (intersects(corpse.x, corpse.y, corpse.width, corpse.height, item.box)) mass++;
|
||||
}
|
||||
return mass >= item.requiredMass;
|
||||
@@ -533,7 +524,7 @@ public final class GameView extends View implements Runnable {
|
||||
}
|
||||
for (LevelDefinition.Hazard hazard : level.hazards) {
|
||||
if (id.equals(hazard.relayId)) {
|
||||
for (Corpse corpse : corpses) {
|
||||
for (Body corpse : corpses) {
|
||||
if (corpse.conductive && intersects(corpse.x, corpse.y, corpse.width, corpse.height, hazard.box)) return true;
|
||||
}
|
||||
}
|
||||
@@ -566,7 +557,7 @@ public final class GameView extends View implements Runnable {
|
||||
player.x += support.x - support.previousX;
|
||||
player.y += support.y - support.previousY;
|
||||
}
|
||||
for (Corpse corpse : corpses) {
|
||||
for (Body corpse : corpses) {
|
||||
if (!corpse.frozen && corpse.supportIndex >= 0 && corpse.supportIndex < platformStates.size()) {
|
||||
PlatformState support = platformStates.get(corpse.supportIndex);
|
||||
corpse.x += support.x - support.previousX;
|
||||
@@ -650,8 +641,8 @@ public final class GameView extends View implements Runnable {
|
||||
player.vy = 0f;
|
||||
current = playerRect();
|
||||
}
|
||||
for (Corpse corpse : corpses) {
|
||||
RectF solid = corpse.rect();
|
||||
for (Body corpse : corpses) {
|
||||
RectF solid = corpseRect(corpse);
|
||||
if (!RectF.intersects(current, solid)) continue;
|
||||
if (amount >= 0f) {
|
||||
player.y = solid.top - PLAYER_HEIGHT;
|
||||
@@ -666,7 +657,7 @@ public final class GameView extends View implements Runnable {
|
||||
}
|
||||
|
||||
private void updateCorpses(float dt) {
|
||||
for (Corpse corpse : corpses) {
|
||||
for (Body corpse : corpses) {
|
||||
if (corpse.frozen || corpse.pinned) continue;
|
||||
corpse.vy += GRAVITY * dt;
|
||||
corpse.grounded = false;
|
||||
@@ -680,7 +671,7 @@ public final class GameView extends View implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean settleCorpseOnPressurePlate(Corpse corpse) {
|
||||
private boolean settleCorpseOnPressurePlate(Body 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;
|
||||
@@ -691,26 +682,26 @@ public final class GameView extends View implements Runnable {
|
||||
}
|
||||
corpse.vx = 0f;
|
||||
corpse.vy = 0f;
|
||||
corpse.pinned = true;
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.PINNED);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void resolveCorpseHorizontal(Corpse corpse) {
|
||||
RectF current = corpse.rect();
|
||||
private void resolveCorpseHorizontal(Body corpse) {
|
||||
RectF current = corpseRect(corpse);
|
||||
for (RectF solid : solidRects(false)) {
|
||||
if (!RectF.intersects(current, solid)) continue;
|
||||
if (corpse.vx > 0f) corpse.x = solid.left - corpse.width;
|
||||
else if (corpse.vx < 0f) corpse.x = solid.right;
|
||||
corpse.vx *= -0.18f;
|
||||
current = corpse.rect();
|
||||
current = corpseRect(corpse);
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveCorpseVertical(Corpse corpse) {
|
||||
private void resolveCorpseVertical(Body corpse) {
|
||||
corpse.supportIndex = -1;
|
||||
RectF current = corpse.rect();
|
||||
RectF current = corpseRect(corpse);
|
||||
for (int i = 0; i < platformStates.size(); i++) {
|
||||
RectF solid = platformStates.get(i).rect();
|
||||
if (!RectF.intersects(current, solid)) continue;
|
||||
@@ -723,7 +714,7 @@ public final class GameView extends View implements Runnable {
|
||||
corpse.y = solid.bottom;
|
||||
corpse.vy *= -0.1f;
|
||||
}
|
||||
current = corpse.rect();
|
||||
current = corpseRect(corpse);
|
||||
}
|
||||
for (LevelDefinition.Door door : level.doors) {
|
||||
if (doorOpen(door)) continue;
|
||||
@@ -737,7 +728,7 @@ public final class GameView extends View implements Runnable {
|
||||
corpse.y = solid.bottom;
|
||||
corpse.vy *= -0.1f;
|
||||
}
|
||||
current = corpse.rect();
|
||||
current = corpseRect(corpse);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -745,7 +736,7 @@ public final class GameView extends View implements Runnable {
|
||||
ArrayList<RectF> result = new ArrayList<>();
|
||||
for (PlatformState platform : platformStates) result.add(platform.rect());
|
||||
for (LevelDefinition.Door door : level.doors) if (!doorOpen(door)) result.add(rect(door.box));
|
||||
if (includeCorpses) for (Corpse corpse : corpses) result.add(corpse.rect());
|
||||
if (includeCorpses) for (Body corpse : corpses) result.add(corpseRect(corpse));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -778,10 +769,8 @@ public final class GameView extends View implements Runnable {
|
||||
cameraController.impact(type == DeathType.PIT ? 12f : 24f);
|
||||
|
||||
if (type != DeathType.PIT) {
|
||||
Corpse corpse = new Corpse();
|
||||
corpse.type = type;
|
||||
corpse.x = player.x;
|
||||
corpse.y = player.y + PLAYER_HEIGHT - corpse.height;
|
||||
Body corpse = corpseManager.register(type.name(), player.x,
|
||||
player.y + PLAYER_HEIGHT - 54f);
|
||||
if (source != null) {
|
||||
corpse.vx = source.impulseX;
|
||||
corpse.vy = source.impulseY;
|
||||
@@ -789,23 +778,21 @@ public final class GameView extends View implements Runnable {
|
||||
if (type == DeathType.SPIKE && source != null) {
|
||||
corpse.y = source.box.y - corpse.height;
|
||||
corpse.vx = corpse.vy = 0f;
|
||||
corpse.pinned = true;
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.PINNED);
|
||||
} else if (type == DeathType.FREEZE && source != null) {
|
||||
corpse.width = 104f;
|
||||
corpse.height = 104f;
|
||||
corpse.x = source.box.x - 2f;
|
||||
corpse.y = 880f - corpse.height;
|
||||
corpse.vx = corpse.vy = 0f;
|
||||
corpse.frozen = true;
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.FROZEN);
|
||||
} else if (type == DeathType.ELECTRIC && source != null) {
|
||||
corpse.conductive = true;
|
||||
corpse.x = source.box.x + (source.box.width - corpse.width) * 0.5f;
|
||||
corpse.y = 880f - corpse.height;
|
||||
corpse.vx = corpse.vy = 0f;
|
||||
corpse.pinned = true;
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.CONDUCTIVE);
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.PINNED);
|
||||
}
|
||||
corpses.add(corpse);
|
||||
while (corpses.size() > MAX_CORPSES) corpses.remove(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,6 +828,11 @@ public final class GameView extends View implements Runnable {
|
||||
return new RectF(player.x, player.y, player.x + PLAYER_WIDTH, player.y + PLAYER_HEIGHT);
|
||||
}
|
||||
|
||||
private static RectF corpseRect(Body corpse) {
|
||||
return new RectF(corpse.x, corpse.y,
|
||||
corpse.x + corpse.width, corpse.y + corpse.height);
|
||||
}
|
||||
|
||||
private static RectF rect(LevelDefinition.Box box) {
|
||||
return new RectF(box.x, box.y, box.right(), box.bottom());
|
||||
}
|
||||
@@ -902,7 +894,7 @@ public final class GameView extends View implements Runnable {
|
||||
drawHazards(canvas);
|
||||
drawDoors(canvas);
|
||||
drawGoal(canvas);
|
||||
for (Corpse corpse : corpses) drawCorpse(canvas, corpse);
|
||||
for (Body corpse : corpses) drawCorpse(canvas, corpse);
|
||||
VolunteerRig.Skin skin = VolunteerRig.Skin.forLevel(level.number);
|
||||
if (player.alive) {
|
||||
VolunteerRig.Motion motion = VolunteerRig.motionFor(characterStateMachine.state());
|
||||
@@ -1140,7 +1132,7 @@ public final class GameView extends View implements Runnable {
|
||||
canvas.drawCircle(box.centerX() - 6f, box.centerY() - 7f, 7f, paint);
|
||||
}
|
||||
|
||||
private void drawCorpse(Canvas canvas, Corpse corpse) {
|
||||
private void drawCorpse(Canvas canvas, Body corpse) {
|
||||
canvas.save();
|
||||
float cx = corpse.x + corpse.width * 0.5f;
|
||||
float cy = corpse.y + corpse.height * 0.5f;
|
||||
@@ -2280,12 +2272,12 @@ public final class GameView extends View implements Runnable {
|
||||
player.x, player.y, player.vx, player.vy,
|
||||
player.alive, player.onGround, player.coyote,
|
||||
player.jumpBuffer, player.supportIndex, player.facing));
|
||||
for (Corpse corpse : corpses) {
|
||||
for (Body corpse : corpses) {
|
||||
builder.addBody(new GameSessionSnapshot.BodyData(
|
||||
corpse.x, corpse.y, corpse.width, corpse.height,
|
||||
corpse.vx, corpse.vy, corpse.frozen, corpse.conductive,
|
||||
corpse.pinned, corpse.grounded, corpse.supportIndex,
|
||||
corpse.type == null ? DeathType.SPIKE.name() : corpse.type.name()));
|
||||
corpse.deathType()));
|
||||
}
|
||||
ArrayList<Float> motionTimes = new ArrayList<>(platformStates.size());
|
||||
for (PlatformState state : platformStates) motionTimes.add(state.motionTime);
|
||||
@@ -2353,22 +2345,22 @@ public final class GameView extends View implements Runnable {
|
||||
characterStateMachine.reset(player.alive, player.onGround,
|
||||
player.vx, player.vy, player.facing);
|
||||
|
||||
corpses.clear();
|
||||
for (GameSessionSnapshot.BodyData savedBody : snapshot.bodies()) {
|
||||
Corpse corpse = new Corpse();
|
||||
corpse.x = savedBody.x();
|
||||
corpse.y = savedBody.y();
|
||||
corpse.width = savedBody.width();
|
||||
corpse.height = savedBody.height();
|
||||
corpse.vx = savedBody.velocityX();
|
||||
corpse.vy = savedBody.velocityY();
|
||||
corpse.frozen = savedBody.frozen();
|
||||
corpse.conductive = savedBody.conductive();
|
||||
corpse.pinned = savedBody.pinned();
|
||||
corpse.grounded = savedBody.grounded();
|
||||
corpse.supportIndex = savedBody.supportIndex();
|
||||
corpse.type = DeathType.valueOf(savedBody.deathType());
|
||||
corpses.add(corpse);
|
||||
Body corpse = corpseManager.register(savedBody.deathType(),
|
||||
savedBody.x(), savedBody.y())
|
||||
.size(savedBody.width(), savedBody.height())
|
||||
.velocity(savedBody.velocityX(), savedBody.velocityY())
|
||||
.grounded(savedBody.grounded())
|
||||
.supportIndex(savedBody.supportIndex());
|
||||
if (savedBody.frozen()) {
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.FROZEN);
|
||||
}
|
||||
if (savedBody.conductive()) {
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.CONDUCTIVE);
|
||||
}
|
||||
if (savedBody.pinned()) {
|
||||
corpseManager.transform(corpse, CorpseManager.Transformation.PINNED);
|
||||
}
|
||||
}
|
||||
|
||||
leftPressed = false;
|
||||
@@ -2452,4 +2444,8 @@ public final class GameView extends View implements Runnable {
|
||||
public void triggerStunForAutomation() {
|
||||
characterStateMachine.stun();
|
||||
}
|
||||
|
||||
public CorpseManager.Diagnostics corpseDiagnosticsForAutomation() {
|
||||
return corpseManager.diagnostics();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user