Java在JFrame上移动BufferedImage

时间:2013-05-09 19:30:17

标签: java image swing jframe bufferedimage

我是Java的新手,目前在研究GUI。我正在创建一个简单的迷宫游戏。目前我的迷宫'布局'使用String数组转换为2D数组,并在String数组中使用'W'和'S'放置墙和空间的图像。

我现在面临的问题是我的角色形象随着数组键移动,我创建了一个BufferedImage,将其绘制到表单并拥有我的主要监听器,我只是无法找到我出错的地方。

这是我的代码;

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


}

希望有人可以告诉我我的问题在哪里,谢谢你。

1 个答案:

答案 0 :(得分:1)

不要覆盖顶级容器(即JFrame)的paint()方法。

自定义绘制是通过覆盖JPanel(或JComponent)的paintComponent()方法完成的。因此,在您的情况下,您将覆盖中心面板,因为那是您创建迷宫的地方。

仅为具有焦点的组件生成KeyEvent。因此,您需要使“中心”面板具有可调焦性。

此外,建议不要使用KeyListener。您刚刚发现了用于AWT应用程序的这种旧方法的一个局限性。对于Swing应用程序,您应该使用Key Bindings。搜索论坛,每天都会提供此建议。

此外,在构建迷宫时不要继续创建新的ImageIcons。每个图像只需要一个图标,然后就可以重复使用Icon。