после некоторого копания я нашел решение, по крайней мере, на данный момент, поэтому для всех, у кого есть такая же проблема, вот как я ее решил.
PlayerAttackState.java
Я начал с созданияновое состояние атаки с именем PlayerAttackState
.
public enum PlayerAttackState implements State<PlayerAgent> {
NONE(){
@Override
public void enter(PlayerAgent agent) {
agent.attacking = false;
agent.lastAttack = System.currentTimeMillis();
}
@Override
public void update(PlayerAgent agent) {
if (KeyboardController.attack && !agent.attacking) {
agent.attacking = true;
KeyboardController.attack = false;
agent.attackStateMachine.changeState(Attacking);
//agent.playerComp.attack();
}
}
},
Attacking(){
@Override
public void enter(PlayerAgent agent) {
agent.timer = 0f;
agent.attackCombo++;
if (agent.attackCombo > 3 || System.currentTimeMillis() - agent.lastAttack > 100) agent.attackCombo = 1;
if (agent.stateMachine.isInState(PlayerState.Jumping) || agent.stateMachine.isInState(PlayerState.DoubleJumping))
agent.attackStateMachine.changeState(AirAttack);
}
@Override
public void update(PlayerAgent agent) {
super.update(agent);
if (agent.stateMachine.isInState(PlayerState.Jumping) || agent.stateMachine.isInState(PlayerState.DoubleJumping))
agent.attackStateMachine.changeState(AirAttack);
}
},
AirAttack(){
@Override
public void enter(PlayerAgent agent) {
if (agent.attackCombo >= 2) {
agent.attackCombo = 1;
agent.attackStateMachine.changeState(FallingAttack);
}
}
@Override
public void update(PlayerAgent agent) {
super.update(agent);
if (agent.attackCombo == 3) {
agent.attackCombo = 1;
agent.attackStateMachine.changeState(FallingAttack);
}
}
},
FallingAttack(){
@Override
public void enter(PlayerAgent agent) {
}
@Override
public void update(PlayerAgent agent) {
if (agent.stateMachine.isInState(PlayerState.Idle) || agent.stateMachine.isInState(PlayerState.Walking))
agent.attackStateMachine.changeState(FallAttack);
else if (agent.stateMachine.isInState(PlayerState.DoubleJumping))
agent.attackStateMachine.changeState(AirAttack);
}
},
FallAttack(){
@Override
public void update(PlayerAgent agent) {
super.update(agent);
}
},
;
@Override
public void enter(PlayerAgent agent) {
}
@Override
public void update(PlayerAgent agent) {
if (agent.animation.isAnimationFinished(agent.timer))
agent.attackStateMachine.changeState(NONE);
}
@Override
public void exit(PlayerAgent agent) {
}
@Override
public boolean onMessage(PlayerAgent agent, Telegram telegram) {
return false;
}
}
PlayerAgent.java
Поэтому после этого мне нужно было добавить конечный автомат для него в классе PlayerAgent
и некоторые другие переменные.
public class PlayerAgent implements Updateable {
private Entity player;
protected Body body;
private TransformComponent transform;
public SensorCollisionComponent sensors;
public PlayerComponent playerComp;
public AttackComponent attackComp;
protected static StateMachine<PlayerAgent, PlayerState> stateMachine;
protected static StateMachine<PlayerAgent, PlayerAttackState> attackStateMachine;
public boolean isTouchingGround = true;
public boolean isTouchingWallLeft = false;
public boolean isTouchingWallRight = false;
public static boolean attacking = false;
public static Animation animation = null;
public static float timer = 0.0f;
public static int attackCombo = 0;
public long lastAttack = 0l;
public PlayerAgent(Entity player) {
this.player = player;
body = player.getComponent(B2dBodyComponent.class).body;
transform = player.getComponent(TransformComponent.class);
sensors = player.getComponent(SensorCollisionComponent.class);
playerComp = player.getComponent(PlayerComponent.class);
attackComp = player.getComponent(AttackComponent.class);
stateMachine = new DefaultStateMachine<PlayerAgent, PlayerState>(this, PlayerState.Idle);
attackStateMachine = new DefaultStateMachine<PlayerAgent, PlayerAttackState>(this, PlayerAttackState.NONE);
}
@Override
public void update(float deltaTime) {
isTouchingGround = (sensors.numFoot > 0);
isTouchingWallLeft = (sensors.numLeftWall > 0);
isTouchingWallRight = (sensors.numRightWall > 0);
stateMachine.update();
attackStateMachine.update();
if (!KeyboardController.left && !KeyboardController.right)
body.setLinearVelocity(MathUtils.lerp(body.getLinearVelocity().x, 0, 0.2f), body.getLinearVelocity().y);
}
public static PlayerState getCurrentState(){
return stateMachine.getCurrentState();
}
public static PlayerAttackState getAttackState(){return attackStateMachine.getCurrentState();}
public static PlayerState getLastState(){
return stateMachine.getPreviousState();
}
public static boolean isInState(PlayerState state){
return stateMachine.isInState(state);
}
public boolean moveOnGround() {
if (KeyboardController.left) {
body.setLinearVelocity(MathUtils.lerp(body.getLinearVelocity().x, -3f, 0.1f), body.getLinearVelocity().y);
transform.flipX = true;
}
if (KeyboardController.right){
body.setLinearVelocity(MathUtils.lerp(body.getLinearVelocity().x, 3f, 0.1f), body.getLinearVelocity().y);
transform.flipX = false;
}
if (KeyboardController.up) {
body.applyLinearImpulse(0, 2.7f, body.getWorldCenter().x, body.getWorldCenter().y, true);
KeyboardController.up = false;
}
return (KeyboardController.left || KeyboardController.right);
}
public boolean moveOnAir(){
if (KeyboardController.left){
body.setLinearVelocity(MathUtils.lerp(body.getLinearVelocity().x, -1.5f, 0.1f), body.getLinearVelocity().y);
transform.flipX = true;
}if (KeyboardController.right){
transform.flipX = false;
body.setLinearVelocity(MathUtils.lerp(body.getLinearVelocity().x, 1.5f, 0.1f), body.getLinearVelocity().y);
}
return (KeyboardController.left || KeyboardController.right);
}
public boolean jumpOnAir(){
if (KeyboardController.up) {
body.applyLinearImpulse(0, 2.5f, body.getWorldCenter().x, body.getWorldCenter().y, true);
KeyboardController.up = false;
return true;
}
return false;
}
}
PlayerAnimations.java
Наконец, мне нужно было настроить анимацию для игрока, поэтому я создал перечисление под названием PlayerAnimations
.
public enum PlayerAnimations {
Idle,
Walking,
Jumping, DoubleJumping,
Falling,
Attack_1, Attack_2, Attack_3,
AirAttack_1, AirAttack_2,
FallingAttack, FallAttack,
Hit,
Die
}
AnimationSystem.java
А затем визуализируйте их, используя AniamtionSystem
.
switch (PlayerAgent.getAttackState()) {
case NONE:
switch (PlayerAgent.getCurrentState()) {
case Idle:
key = PlayerAnimations.Idle.ordinal();
break;
case Walking:
key = PlayerAnimations.Walking.ordinal();
break;
case Jumping:
key = PlayerAnimations.Jumping.ordinal();
break;
case DoubleJumping:
key = PlayerAnimations.DoubleJumping.ordinal();
break;
case Falling:
key = PlayerAnimations.Falling.ordinal();
break;
default:
key = PlayerAnimations.Idle.ordinal();
break;
}
break;
case Attacking:
switch (PlayerAgent.attackCombo) {
case 1:
key = PlayerAnimations.Attack_1.ordinal();
break;
case 2:
key = PlayerAnimations.Attack_2.ordinal();
break;
case 3:
key = PlayerAnimations.Attack_3.ordinal();
break;
default:
key = PlayerAnimations.Attack_1.ordinal();
System.out.println("Attack Combo Error");
break;
}
break;
case AirAttack:
switch (PlayerAgent.attackCombo) {
case 1:
key = PlayerAnimations.AirAttack_1.ordinal();
break;
case 2:
key = PlayerAnimations.AirAttack_2.ordinal();
break;
default:
key = PlayerAnimations.AirAttack_1.ordinal();
System.out.println("Air Attack Combo Error");
break;
}
break;
case FallingAttack:
key = PlayerAnimations.FallingAttack.ordinal();
break;
case FallAttack:
key = PlayerAnimations.FallAttack.ordinal();
break;
default:
key = PlayerAnimations.Idle.ordinal();
break;
}
timer = PlayerAgent.timer;
PlayerAgent.timer += deltaTime;
PlayerAgent.animation = ani.animations.get(key);
}
tex.region = ani.animations.get(key).getKeyFrame(timer);
Надеюсь, это поможет кому-нибудь и, еще раз, извините за мой плохой английский.Если у вас есть какие-либо вопросы, не стесняйтесь спрашивать меня.