Завершить state machine персонажа
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
package com.projectsacrifice.game;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public final class CharacterStateMachineTest {
|
||||
@Test
|
||||
public void groundedVelocitySelectsIdleAndRunDeterministically() {
|
||||
CharacterStateMachine machine = new CharacterStateMachine(PhysicsConfig.release());
|
||||
|
||||
machine.reset(true, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.IDLE, machine.state());
|
||||
|
||||
machine.observe(1f / 60f, true, true, 370f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.RUN, machine.state());
|
||||
|
||||
machine.observe(1f / 60f, true, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.IDLE, machine.state());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verticalMotionSelectsJumpFallAndDeathHasPriority() {
|
||||
CharacterStateMachine machine = new CharacterStateMachine(PhysicsConfig.release());
|
||||
|
||||
machine.reset(true, false, 120f, -300f, 1);
|
||||
assertEquals(CharacterStateMachine.State.JUMP, machine.state());
|
||||
|
||||
machine.observe(1f / 60f, true, false, 120f, 80f, 1);
|
||||
assertEquals(CharacterStateMachine.State.FALL, machine.state());
|
||||
|
||||
machine.observe(1f / 60f, false, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.DEATH, machine.state());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changingFacingEmitsOneConfiguredTurnWindow() {
|
||||
PhysicsConfig physics = PhysicsConfig.release();
|
||||
CharacterStateMachine machine = new CharacterStateMachine(physics);
|
||||
machine.reset(true, true, physics.runSpeed(), 0f, 1);
|
||||
|
||||
machine.observe(physics.fixedStepSeconds(), true, true,
|
||||
-physics.runSpeed(), 0f, -1);
|
||||
assertEquals(CharacterStateMachine.State.TURN, machine.state());
|
||||
|
||||
machine.observe(physics.turnSeconds() + physics.fixedStepSeconds(),
|
||||
true, true, -physics.runSpeed(), 0f, -1);
|
||||
assertEquals(CharacterStateMachine.State.RUN, machine.state());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void firstGroundedFrameAfterFallingEmitsConfiguredLandWindow() {
|
||||
PhysicsConfig physics = PhysicsConfig.release();
|
||||
CharacterStateMachine machine = new CharacterStateMachine(physics);
|
||||
machine.reset(true, false, 0f, 300f, 1);
|
||||
|
||||
machine.observe(physics.fixedStepSeconds(), true, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.LAND, machine.state());
|
||||
|
||||
machine.observe(physics.landSeconds() + physics.fixedStepSeconds(),
|
||||
true, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.IDLE, machine.state());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interactionIsAConfiguredCommandAndDeathCancelsIt() {
|
||||
PhysicsConfig physics = PhysicsConfig.release();
|
||||
CharacterStateMachine machine = new CharacterStateMachine(physics);
|
||||
machine.reset(true, true, 0f, 0f, 1);
|
||||
|
||||
machine.beginInteraction();
|
||||
assertEquals(CharacterStateMachine.State.INTERACT, machine.state());
|
||||
machine.observe(physics.interactSeconds() * 0.5f,
|
||||
true, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.INTERACT, machine.state());
|
||||
|
||||
machine.observe(physics.fixedStepSeconds(), false, true, 0f, 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.DEATH, machine.state());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void stunOverridesInteractionThenReturnsToObservedMovement() {
|
||||
PhysicsConfig physics = PhysicsConfig.release();
|
||||
CharacterStateMachine machine = new CharacterStateMachine(physics);
|
||||
machine.reset(true, true, physics.runSpeed(), 0f, 1);
|
||||
machine.beginInteraction();
|
||||
|
||||
machine.stun();
|
||||
assertEquals(CharacterStateMachine.State.STUNNED, machine.state());
|
||||
machine.observe(physics.stunnedSeconds() * 0.5f,
|
||||
true, true, physics.runSpeed(), 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.STUNNED, machine.state());
|
||||
|
||||
machine.observe(physics.stunnedSeconds(),
|
||||
true, true, physics.runSpeed(), 0f, 1);
|
||||
assertEquals(CharacterStateMachine.State.RUN, machine.state());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interactionCannotDowngradeAnActiveStun() {
|
||||
CharacterStateMachine machine = new CharacterStateMachine(PhysicsConfig.release());
|
||||
machine.reset(true, true, 0f, 0f, 1);
|
||||
|
||||
machine.stun();
|
||||
machine.beginInteraction();
|
||||
|
||||
assertEquals(CharacterStateMachine.State.STUNNED, machine.state());
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,10 @@ public final class PhysicsConfigTest {
|
||||
assertEquals(0.13f, physics.coyoteSeconds(), 0f);
|
||||
assertEquals(0.14f, physics.jumpBufferSeconds(), 0f);
|
||||
assertEquals(0.78f, physics.respawnSeconds(), 0f);
|
||||
assertEquals(0.10f, physics.turnSeconds(), 0f);
|
||||
assertEquals(0.12f, physics.landSeconds(), 0f);
|
||||
assertEquals(0.24f, physics.interactSeconds(), 0f);
|
||||
assertEquals(0.32f, physics.stunnedSeconds(), 0f);
|
||||
assertTrue(physics.maximumBodies() >= 10);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,4 +84,32 @@ public final class VolunteerRigTest {
|
||||
assertEquals(VolunteerRig.Motion.DEAD,
|
||||
VolunteerRig.bodyMotion(false, false, false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void everyLivingCharacterStateHasAnExplicitAnimationMotion() {
|
||||
for (CharacterStateMachine.State state : CharacterStateMachine.State.values()) {
|
||||
assertEquals(state.name(), VolunteerRig.motionFor(state).name());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void transientCharacterStatesHaveNonColorPoseSignals() {
|
||||
VolunteerRig.Skin skin = VolunteerRig.Skin.BRASS_SCOUT;
|
||||
VolunteerRig.Pose idle = VolunteerRig.pose(skin, VolunteerRig.Motion.IDLE, 0.25f, 1);
|
||||
VolunteerRig.Pose turn = VolunteerRig.pose(skin, VolunteerRig.Motion.TURN, 0.25f, 1);
|
||||
VolunteerRig.Pose land = VolunteerRig.pose(skin, VolunteerRig.Motion.LAND, 0.25f, 1);
|
||||
VolunteerRig.Pose interact = VolunteerRig.pose(
|
||||
skin, VolunteerRig.Motion.INTERACT, 0.25f, 1);
|
||||
VolunteerRig.Pose stunned = VolunteerRig.pose(
|
||||
skin, VolunteerRig.Motion.STUNNED, 0.25f, 1);
|
||||
|
||||
assertNotEquals(idle.x(VolunteerRig.Joint.LEFT_HAND),
|
||||
turn.x(VolunteerRig.Joint.LEFT_HAND), 0.001f);
|
||||
assertNotEquals(idle.y(VolunteerRig.Joint.ROOT),
|
||||
land.y(VolunteerRig.Joint.ROOT), 0.001f);
|
||||
assertNotEquals(idle.x(VolunteerRig.Joint.RIGHT_HAND),
|
||||
interact.x(VolunteerRig.Joint.RIGHT_HAND), 0.001f);
|
||||
assertNotEquals(idle.y(VolunteerRig.Joint.LEFT_HAND),
|
||||
stunned.y(VolunteerRig.Joint.LEFT_HAND), 0.001f);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user