简体   繁体   中英

JPanel not updating after KeyPressed

So I'm trying to make a Roguelike game with procedural generation etc. But I'm having trouble with the character handling. The thing is when i want to move the character around with the keyboard, it is only changing its coordinates - which it should do of course, but i can't see it on the screen. I read some answers on this site, and that helped me a little, but it didn't solve the problem entirely.
So, I'm note sure what I'm doing wrong, here's a bit of code (hope that it is not too long):

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


}

Hope you can help, thanks !

By default a JPanel uses a FlowLayout.

It looks like your code is changing a players position, but then you invoke revalidate() which causes the layout manager code to be invoked and the location of your component is recalculated again.

So for games where you have random movement you want to use a null layout and you don't need to invoke revalidate() and repaint() since your code is not responsible for invoking the setLocation() method directly.

See also Motion Using the Keyboard for problems with using a keyListener.

setRequestFocusEnabled(true);
requestFocus();
setVisible(true);

The above is not needed. The two properties you are setting to true default to true. You can't request focus on a component unless the component is displayed on a visible GUI, so adding that code here does nothing. Also, the proper method to use would be requestFocusInWindow(), not requestFocus().

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM