4Mechanix
4Mechanix

Reputation: 98

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 !

Upvotes: 0

Views: 131

Answers (1)

camickr
camickr

Reputation: 324118

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().

Upvotes: 1

Related Questions