Java 2D游戏 - KeyListener / KeyEvent类 - 空闲动画问题

时间:2018-04-24 11:13:07

标签: java keylistener keyevent

我有以下代码:

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()方法返回正确的空闲动画(或者在我的代码的迭代中,除leftleft_idle之外的任何其他动画。)< / p>

我的密钥在我的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 :(得分:0)

您的条件和布尔逻辑过于复杂:

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变量应该存储最后一个按键的值”。 我可能会定义方向枚举:

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