我是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){}
}
希望有人可以告诉我我的问题在哪里,谢谢你。
答案 0 :(得分:1)
不要覆盖顶级容器(即JFrame)的paint()方法。
自定义绘制是通过覆盖JPanel(或JComponent)的paintComponent()方法完成的。因此,在您的情况下,您将覆盖中心面板,因为那是您创建迷宫的地方。
仅为具有焦点的组件生成KeyEvent。因此,您需要使“中心”面板具有可调焦性。
此外,建议不要使用KeyListener。您刚刚发现了用于AWT应用程序的这种旧方法的一个局限性。对于Swing应用程序,您应该使用Key Bindings。搜索论坛,每天都会提供此建议。
此外,在构建迷宫时不要继续创建新的ImageIcons。每个图像只需要一个图标,然后就可以重复使用Icon。