user2192629
user2192629

Reputation:

Java moving a BufferedImage on JFrame

I'm new to Java, currently studying GUI. I'm creating a simple Maze game. Currently i have my maze 'layout' using a String array converted into a 2D array and placing a image for walls and space by using 'W' and 'S' in in String array.

The problem i am facing now is my character image moving with the array keys, i have created a BufferedImage, painted it to the form and have my key listener and i just cant find where im going wrong.

Here is my code;

public class Maze extends JFrame  implements KeyListener {

    private Container contain;
    private JPanel pEast, pNorth, pSouth, pCenter, pWest;
    private JButton btnStart, btnReset, btnExit;
    private JLabel lblTitle, lblmazewall;
    private JTextArea txtArea;
    //private String s;
    //private FileInputStream in;
    //private int no;
    //private char ch;
    private ImageIcon mazewall;
    private BufferedImage player;
    private int xpos = 100, ypos = 100;
    private String [] mazeLayout;
    private String [][] mazeLayout2d;



    Maze(){

        loadImage();
        mazeLayout = new String[10];
        mazeLayout2d = new String[10][10];

        contain = getContentPane();
        pEast = new JPanel();
        pNorth = new JPanel();
        pSouth = new JPanel();
        pCenter = new JPanel();
        pWest = new JPanel();



        //pCenter.setBackground(Color.BLUE);

        pCenter.setLayout(new FlowLayout (FlowLayout.CENTER,0,0));

        pWest.setLayout(new FlowLayout (FlowLayout.CENTER, 10, 10));

        btnStart = new JButton("Start");
        btnStart.setFont(new Font("Dialog", Font.BOLD, 18));
        btnReset = new JButton("Reset");
        btnReset.setFont(new Font("Dialog",Font.BOLD,18));
        pEast.setLayout(new FlowLayout (FlowLayout.CENTER,10,10));
        pEast.add(btnStart);
        pEast.add(btnReset);

        btnExit = new JButton("Exit");
        btnExit.setFont(new Font("Dialog",Font.BOLD,18));
        pSouth.setLayout( new FlowLayout (FlowLayout.CENTER, 20,10));
        pSouth.add(btnExit);

        lblTitle = new JLabel("Maze Game");
        lblTitle.setFont( new Font("Dialog",Font.BOLD,24));
        lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
        pNorth.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 10));
        pNorth.add(lblTitle);

        txtArea = new JTextArea(20,70);
        txtArea.setFont(new Font("dialog",Font.BOLD,16));

        mazewall = new ImageIcon("mazewall.png");

//      Read in from a text file, needed later          
//      try{
//          in = new FileInputStream("maze.txt");
//          while((no = in.read()) != -1){
//              ch = (char)no;
//              s+=ch;
//          }
//          txtArea.setText(s); 
//      }catch(FileNotFoundException ef){
//          JOptionPane.showMessageDialog(null, "File not found - maze.txt");
//          }catch(IOException e){
//              JOptionPane.showMessageDialog(null, "Unable to read file maze.txt");
//          }

        contain.add(pEast, BorderLayout.EAST);
        contain.add(pNorth, BorderLayout.NORTH);
        contain.add(pSouth, BorderLayout.SOUTH);
        contain.add(pCenter, BorderLayout.CENTER);
        contain.add(pWest, BorderLayout.WEST);  

        //Array for maze
        mazeLayout[0] = "WWWWWWWWWW";
        mazeLayout[1] = "WSSSWWSWWW";
        mazeLayout[2] = "WSWSWWSSSW";
        mazeLayout[3] = "WSWSWWWWSW";
        mazeLayout[4] = "WSWSWWWWSW";
        mazeLayout[5] = "WSWSWSSSSW";
        mazeLayout[6] = "WSWSWSWWWW";
        mazeLayout[7] = "WSWSWSWWWW";
        mazeLayout[8] = "WSWSSSWWWW";
        mazeLayout[9] = "WWWWWWWWWW";


        //Converting array into 2d array
        for(int y = 0; y < 10; y++){
            for(int x = 0; x < 10; x++){
                mazeLayout2d[y][x] = mazeLayout[y].substring(x, x+1);
                if (mazeLayout2d[y][x].equals("W")){
                    lblmazewall = new JLabel();
                    mazewall = new ImageIcon("mazewall.png");
                    lblmazewall.setIcon(mazewall);
                    pCenter.add(lblmazewall);
                }
                if (mazeLayout2d[y][x].equals("S")){
                    lblmazewall = new JLabel();
                    mazewall = new ImageIcon("mazefloor.png");
                    lblmazewall.setIcon(mazewall);
                    pCenter.add(lblmazewall);
                }
            }
        }       
    }

    public void loadImage(){
        try{
            String playerPath = "player.png";
            player = ImageIO.read(new File(playerPath));
        }catch(IOException ex){
            ex.printStackTrace();
        }   
        addKeyListener(this);
    }

    @Override
    public void paint(Graphics g){
        super.paint(g);
        g.drawImage(player, xpos, ypos,50,80, this);    
    }


    public void keyPressed(KeyEvent ke){
        switch(ke.getKeyCode()){
        case KeyEvent.VK_RIGHT:{
            xpos+=3;
        }
        break;
        case KeyEvent.VK_LEFT:{
            xpos-=3;
        }
        break;
        case KeyEvent.VK_DOWN:{
            ypos+=3;
        }
        break;
        case KeyEvent.VK_UP:{
            ypos-=3;
        }
        break;
    }
    repaint();
}
    public void keyTyped(KeyEvent ke){}
    public void keyReleased(KeyEvent ke){}


}

Hopefully someone can tell me where my problem is, thankyou.

Upvotes: 0

Views: 1046

Answers (1)

camickr
camickr

Reputation: 324128

Don't override the paint() method of a top level container (ie JFrame).

Custom painting is done by overriding the paintComponent() method of a JPanel (or JComponent). So in your case you would override the center panel since that is where you create the maze.

KeyEvent are only generated for the component that has focus. So you will then need to make the Center panel focusable.

Also, it is not recommended to use a KeyListener. You just found one of the limitations of this old approach that was used for AWT applications. For Swing applications you should be using Key Bindings. Search the forum, this advice is given daily.

Also, don't keep creating new ImageIcons when you build the maze. You only need a single Icon for each image, then you can reuse the Icon.

Upvotes: 1

Related Questions