Java 2D Game - класс KeyListener / KeyEvent - проблема с неактивными анимациями - PullRequest
0 голосов
/ 24 апреля 2018

У меня есть следующий код:

package myprojectgame.entities.creature;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import myprojectgame.Game;
import myprojectgame.Handler;
import myprojectgame.gfx.Animation;
import myprojectgame.gfx.Assets;
import myprojectgame.input.KeyManager;
import static myprojectgame.input.KeyManager.keys;



public abstract class Player extends Creature {
   // Animations ---> while moving
   private Animation down;
   private Animation up;
   private Animation left;
   private Animation right;

   // Animations --> idle
   private Animation down_idle;
   private Animation up_idle;
   private Animation left_idle;
   private Animation right_idle;

   // Last pressed boolean variable --> initialize it to down 
   public boolean lastPressed = handler.getKeyManager().down;


public Player(Handler handler,float x, float y) {
    super(handler,x, y,Creature.DEFAULT_CREATURE_WIDTH,Creature.DEFAULT_CREATURE_HEIGHT);
    bounds.x = 16;
    bounds.y = 14;
    bounds.width = 25;
    bounds.height = 43;

    // Animations --> while moving instantiation 
    down = new Animation(300,Assets.player_down);
    left = new Animation(300,Assets.player_left);
    right = new Animation(300,Assets.player_right);
    up = new Animation(300,Assets.player_up);

    // Animations --> while idle instantiation
    down_idle= new Animation(500,Assets.player_down_idle);
    right_idle= new Animation(500,Assets.player_right_idle);
    left_idle= new Animation(500,Assets.player_left_idle);
    up_idle= new Animation(500,Assets.player_up_idle);
}

@Override
public void tick() {
    down.tick();
    up.tick();
    right.tick();
    left.tick();
    down_idle.tick();
    up_idle.tick();
    right_idle.tick();
    left_idle.tick();
    getInput();
    move();
    handler.getCamera().centerOnEntity(this);
}

private void getInput() {
    xMove = 0;
    yMove = 0;

    if (handler.getKeyManager().up) {
        yMove = -speed;
        lastPressed = handler.getKeyManager().up;
    }
    if (handler.getKeyManager().down) {
        yMove = speed;
        lastPressed = handler.getKeyManager().down;
    }
    if (handler.getKeyManager().left) {
        xMove = -speed;
        lastPressed = handler.getKeyManager().left;
    }
    if (handler.getKeyManager().right) {
        xMove = speed;
        lastPressed = handler.getKeyManager().right;
    }
}

@Override
public void render(Graphics g) {
    g.drawImage(getCurrentAnimationFrame(),(int) (x - handler.getCamera().getxOffset()), (int) (y - handler.getCamera().getyOffset()),(width),(height), null);
}


private BufferedImage getCurrentAnimationFrame() {
    if (handler.getKeyManager().left && lastPressed == handler.getKeyManager().left) {
        return left.getCurrentFrame();
      } else if ( !(handler.getKeyManager().left)) {
        return left_idle.getCurrentFrame();
      }

    if (handler.getKeyManager().right && lastPressed == handler.getKeyManager().right) {
        return right.getCurrentFrame();
      } else if ( !(handler.getKeyManager().right) && lastPressed == handler.getKeyManager().right) {
        return right_idle.getCurrentFrame();
      }

     if (handler.getKeyManager().up && lastPressed == handler.getKeyManager().up) {
        return up.getCurrentFrame();
      } else if ( !(handler.getKeyManager().up) && lastPressed == handler.getKeyManager().up ) {
          return up_idle.getCurrentFrame();
      } 

     if (handler.getKeyManager().down && lastPressed == handler.getKeyManager().down) {
        return down.getCurrentFrame();
       } else if ( !(handler.getKeyManager().down) && lastPressed == 
          handler.getKeyManager().down ) {
            return down_idle.getCurrentFrame();
       } 

    return null;

    }
}

Проблема в том, что я не могу заставить мой метод getCurrentAnimationFrame() возвращать правильные анимации бездействия (или в этой итерации моего кода, любую другую анимацию, кроме left и left_idle).

Мои ключи определены в моем KeyManager классе следующим образом:

    up = keys[KeyEvent.VK_W] || keys[KeyEvent.VK_UP];
    down = keys[KeyEvent.VK_S] || keys[KeyEvent.VK_DOWN];
    left = keys[KeyEvent.VK_A] || keys[KeyEvent.VK_LEFT];
    right = keys[KeyEvent.VK_D] || keys[KeyEvent.VK_RIGHT];

Как правильно реализовать ключевые события / удары, чтобы вернуть правильную анимацию при отпускании / нажатии клавиши?

1 Ответ

0 голосов
/ 26 апреля 2018

Ваши условия и логическая логика слишком сложны:

private void getInput() {
  xMove = 0;
  yMove = 0;

  if (handler.getKeyManager().up) {
      yMove = -speed;
      lastPressed = handler.getKeyManager().up;
  }
  //...
}

private BufferedImage getCurrentAnimationFrame() {
  if (handler.getKeyManager().left && lastPressed == handler.getKeyManager().left) {
    return left.getCurrentFrame();
  } else if ( !(handler.getKeyManager().left)) {
    return left_idle.getCurrentFrame();
  }
  //...
  return null;
}

То же, что и:

private void getInput() {
    xMove = 0;
    yMove = 0;

    KeyManager km = handler.getKeyManager();
    if (km.up) {
        yMove = -speed;
        lastPressed = true;
    }
    //...
}

private BufferedImage getCurrentAnimationFrame() {
    KeyManager km = handler.getKeyManager();
    if (km.left && lastPressed) { 
    // replaced lastPressed == handler.getKeyManager().left since km.left must be true
        return left.getCurrentFrame();
    } else if (!km.left) {
        return left_idle.getCurrentFrame();
    }
    //...
    return null;
}

Я не вижу, где вы устанавливаете lastPressed в false, выглядитдля меня это будет установлено в true (с первым нажатием клавиши) и остается true.Поскольку это всегда true, ваше условие в getCurrentAnimationFrame эффективно:

private BufferedImage getCurrentAnimationFrame() {
    KeyManager km = handler.getKeyManager();
    if (km.left) {
        return left.getCurrentFrame();
    } else {
        return left_idle.getCurrentFrame();
    }
    //UNREACHABLE CODE!
    return null;
}

Даже если оно не остается верным, ваш код похож на if left, return left animation, if not left return left idle animation.Я думаю, что ваши как-то смешанные логические значения с кодами клавиш, как вы говорите, «переменная lastPressed должна хранить значение последней нажатой клавиши».Я бы, вероятно, определил бы направление enum:

public enum DirectionEnum {
LEFT, RIGHT, UP, DOWN;
}

И использовал бы его так:

DirectionEnum lastPressed = null;

private void getInput() {
xMove = 0;
yMove = 0;
KeyManager km = handler.getKeyManager();
if (km.up) {
    yMove = -speed;
    lastPressed = DirectionEnum.UP;
}
//...
}

private BufferedImage getCurrentAnimationFrame() {    
    KeyManager km = handler.getKeyManager();
    if (lastPressed == null) {
        if (km.left) {
        return left.getCurrentFrame();
        }
        //...
    } else {
        switch (lastPressed) {
        case DOWN:
            if (!km.down){
                return down_idle.getCurrentFrame();
            }
            break;
            //...
        default:
            throw new RuntimeException("Invalid direction " + lastPressed);
        }
    }
    return null;
}

Но я не знаю, правильно ли это, потому что lastPressed будет nullтолько в первый раз (или никогда), и тогда вы увидите только праздную анимацию.Так что вы, вероятно, должны решить, когда установить lastPressed обратно на null?

...