0

我是 Java 新手,目前正在学习 GUI。我正在创建一个简单的迷宫游戏。目前,我的迷宫“布局”使用字符串数组转换为二维数组,并通过在字符串数组中使用“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){}


}

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

4

1 回答 1

1

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

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

KeyEvent 仅针对具有焦点的组件生成。因此,您需要使 Center 面板具有焦点。

此外,不建议使用 KeyListener。您刚刚发现了这种用于 AWT 应用程序的旧方法的限制之一。对于 Swing 应用程序,您应该使用键绑定。搜索论坛,每天都会给出这个建议。

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

于 2013-05-10T00:33:30.450 回答