所以我试图用程序生成等来制作一个Roguelike游戏。但是我在处理字符时遇到了麻烦。 问题是,当我想用键盘移动角色时,它只是改变它的坐标 - 当然应该这样做,但我无法在屏幕上看到它。 我在这个网站上看到了一些答案,这对我有所帮助,但它并没有完全解决问题 所以,我注意到我做错了什么,这里有一些代码(希望它不会太长):
public class PanelTest extends JPanel implements KeyListener{
private static final long serialVersionUID = 1L;
private Game game;
private int width, height;
private int tileSize;
public PanelTest(Game game, int tileSize) {
super();
this.game = game;
this.tileSize = tileSize;
this.width = game.getMap().getWidth()*tileSize;
this.height = game.getMap().getHeight()*tileSize;
this.addKeyListener(this);
setPreferredSize(new Dimension(width, height));
setRequestFocusEnabled(true);
requestFocus();
setVisible(true);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
for(int i=0; i < game.getMap().getWidth(); i++){
for(int j=0; j < game.getMap().getHeight(); j++){
g.setColor(game.getMap().getColor(i,j));
g.fillRect(i*tileSize, j*tileSize, tileSize, tileSize);
}
}
// print the correct coordinates
System.out.println(game.getPlayer().getX()+" "+game.getPlayer().getY());
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
switch(e.getKeyCode()){
case(KeyEvent.VK_Z) : game.getPlayer().moveUp();break;
case(KeyEvent.VK_S) : game.getPlayer().moveDown(); break;
case(KeyEvent.VK_Q) : game.getPlayer().moveLeft(); break;
case(KeyEvent.VK_D) : game.getPlayer().moveRight(); break;
}
revalidate();
repaint();
}
public void addNotify() {
super.addNotify();
requestFocus();
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setBounds(0, 0, 400, 400);
Map map = MapFactory.createNewEmptyMap();
RoomMaker rm = new RoomMaker(map.getWidth()/7,map);
TunnelMaker tm = new TunnelMaker(rm, map);
rm.carveOut();
tm.carveOut();
Room r = rm.getRandomRoom();
Player p = new Player(map, r.getxCenter(),r.getyCenter());
Game game = new Game(map,p);
frame.getContentPane().add(new PanelTest(game, 10));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
希望你能帮忙,谢谢!
答案 0 :(得分:1)
默认情况下,JPanel使用FlowLayout。
看起来您的代码正在更改玩家位置,但随后您调用revalidate()会导致调用布局管理器代码并重新计算组件的位置。
因此,对于随机移动的游戏,您希望使用空布局,并且不需要调用revalidate()和repaint(),因为您的代码不负责直接调用setLocation()方法。
有关使用keyListener的问题,另请参阅Motion Using the Keyboard。
setRequestFocusEnabled(true);
requestFocus();
setVisible(true);
以上不需要。您设置为true的两个属性默认为true。除非组件显示在可见的GUI上,否则您无法请求关注组件,因此在此处添加该代码不会执行任何操作。另外,使用的正确方法是requestFocusInWindow(),而不是requestFocus()。