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

标签 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 之外的任何其他动画)。

我的 key 在我的 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];

如何正确实现按键事件/击键以在按键释放/按键时返回正确的动画?

最佳答案

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

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;
}

即使它不保持正确,您的代码就像如果离开,返回左侧动画,如果不离开返回左侧空闲动画。我认为您以某种方式将 boolean 值与键代码混合在一起,正如您所说的“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

关于Java 2D 游戏 - KeyListener/KeyEvent 类 - 空闲动画问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50000259/

相关文章:

java - KeyListener 无法与 Java 中的 MediaPlayer 一起正常工作

java - 修复 java 按键操作中的延迟问题

java - Jooq 无法找到 postgres 数据库的驱动程序

java - 无法打开第二个 JFileChooser

java - 如何获取月份中的某一天?

JavaFX KeyEvent 返回 KeyCode.UNDEFINED

jquery 如何捕获回车键并将事件更改为选项卡

java - 如何将Assets文件夹复制到内部存储?

java - 按键监听器不工作

android - CrossWalk的XWalkView如何使用后退按钮返回,或禁用它?