【发布时间】:2020-07-03 08:56:57
【问题描述】:
我正在创建一个简单的小游戏,我需要一些帮助来找出我所犯的错误。这个想法是将一些面板存储在主框架内的 CardLayout 中,并在必要时在它们之间切换;我创建了一个自定义 JFrame (MainFrame) 和一堆自定义 JPanel,其中一个是 GamePanel,它已附加到自定义 KeyListener (MovementListener) 以捕获关键事件并根据需要移动玩家。问题是当我切换到 GamePanel 时,似乎 keyListener 没有实例化。 明确一点,做了一堆测试,结果是在addKeyListener()方法中,“new MovementListener()”部分为空,但我不知道为什么。
这里是 MovementListener 类:
package controller.listeners;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import application.core.GameController;
import entities.Player;
import movement.Direction;
public class MovementListener implements KeyListener {
private Player player;
public MovementListener() {
this.player=GameController.getInstance().getPlayer();
}
@Override
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W:
player.move(Direction.NORTH);
player.getAnimatedSprite().startMoving();
break;
case KeyEvent.VK_A:
player.move(Direction.WEST);
player.getAnimatedSprite().startMoving();
break;
case KeyEvent.VK_S:
player.move(Direction.SOUTH);
player.getAnimatedSprite().startMoving();
break;
case KeyEvent.VK_D:
player.move(Direction.EAST);
player.getAnimatedSprite().startMoving();
break;
default:
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_W:
player.getAnimatedSprite().stopMoving();
break;
case KeyEvent.VK_A:
player.getAnimatedSprite().stopMoving();
break;
case KeyEvent.VK_S:
player.getAnimatedSprite().stopMoving();
break;
case KeyEvent.VK_D:
player.getAnimatedSprite().stopMoving();
break;
default:
break;
}
}
@Override
public void keyTyped(KeyEvent e) {}
}
GamePanel 类:
package graphics.panels;
import java.awt.Component;
import java.awt.Graphics;
import javax.swing.JPanel;
import application.core.GameController;
import controller.listeners.MovementListener;
import entities.Entity;
import entities.Living;
import graphics.ConstantsCollector;
import graphics.sprites.AnimatedSprite;
import graphics.sprites.Tile;
@SuppressWarnings("serial")
public class GamePanel extends JPanel {
public static final String NAME="Game";
private static GamePanel instance=null;
private Tile grassTile;
private Entity[][] logicMap;
private GamePanel() {
super();
logicMap = GameController.getInstance().logicMap;
grassTile = new Tile(ConstantsCollector.GRASSTEXTURE);
addKeyListener(new MovementListener());
setAlignmentX(Component.CENTER_ALIGNMENT);
setVisible(true);
setFocusable(true);
requestFocusInWindow();
grabFocus();
}
@Override
public void paintComponent(Graphics g) {
drawFloorMap(g);
drawObjects(g);
drawEntities(g);
}
private void drawFloorMap(Graphics g) {
for(int i = 0; i < ConstantsCollector.MAP_SIZE; i++)
for(int j = 0; j < ConstantsCollector.MAP_SIZE; j++)
g.drawImage(grassTile.getSprite(), Tile.calculateXPosition(i), Tile.calculateYPosition(j), Tile.calculateWidth(), Tile.calculateHeight(), null);
}
private void drawObjects(Graphics g) {
for(int i = 0; i < ConstantsCollector.MAP_SIZE; i++)
for(int j = 0; j < ConstantsCollector.MAP_SIZE; j++)
if (logicMap[i][j]!=null && !(logicMap[i][j] instanceof Living))
g.drawImage(logicMap[i][j].getTile().getSprite(), logicMap[i][j].getTile().getWidth(), logicMap[i][j].getTile().getHeight(), null);
else
g.drawImage(grassTile.getSprite(), Tile.calculateXPosition(i), Tile.calculateYPosition(j), Tile.calculateWidth(), Tile.calculateHeight(), null);
}
private void drawEntities(Graphics g) {
for(int i = 0; i < ConstantsCollector.MAP_SIZE; i++)
for(int j = 0; j < ConstantsCollector.MAP_SIZE; j++)
if (logicMap[i][j]!=null && (logicMap[i][j] instanceof Living))
{
AnimatedSprite sprite=((Living)logicMap[i][j]).getAnimatedSprite();
g.drawImage(sprite.getCurrentImage(), sprite.getWidht(), sprite.getHeight(), null);
}
}
public void update() {
repaint();
}
public static GamePanel getInstance() {
if (instance==null)
instance=new GamePanel();
return instance;
}
}
【问题讨论】:
-
问题是,当我切换到 GamePanel 时,keyListener 似乎没有实例化 - KeyEvents 仅被分派到具有焦点的组件。不要使用 KeyListener。相反,您应该使用键绑定。有关更多信息和工作示例,请参阅 Motion Using the Keyboard。
标签: java swing keylistener