尝试使用KeyListeners和ImageIcons时出错?

问题描述:

我目前正在努力为学校制作一款迷宫游戏,而且我为什么会遇到这些错误感到困惑。这是涉及的代码段。还需要导入的所有内容都已导入。首先是具有玩家位置的玩家类,然后是他们的图像。尝试使用KeyListeners和ImageIcons时出错?

public class Player { 
int playerX; 
int playerY; 
int moveSpeed = 5; //I can edit move speed here 
Image character; 

//getters and setters to utilize the player's location and image 
public Player(){ //constructor for initial starting points 
    playerX = 50; 
    playerY = 50; 
    ImageIcon player = new ImageIcon("E://Workspace//Maze//images//Player.jpg"); 
    character = player.getImage(); 
} 

public void setPlayerX(int playerX){ 
    this.playerX = playerX; 
} 
public int getPlayerX(){ 
    return playerX; 
} 

public void setPlayerY(int playerY){ 
    this.playerY = playerY; 
} 
public int getPlayerY(){ 
    return playerY; 
} 

public void setMoveSpeed(int moveSpeed){ 
    this.moveSpeed = moveSpeed; 
} 
public int getMoveSpeed(){ 
    return moveSpeed; 
} 

public Image getPlayerImage(){ 
    return character; 
} 
} 

现在是创建的JPanel的布局类,并且应该是什么最终绘制选手图像进入游戏,也是什么是应该让玩家移动。

public class Layout extends JPanel implements ActionListener { //GUI with a  non null FlowLayout 
Player p = new Player(); 
Maze m = new Maze(); 

//500 x 500 seemed like a good size for the maze game 
int x = 500; 
int y = 500; 

public Layout(){ 
    setLayout(new FlowLayout()); 
    addKeyListener(new Move()); 
    setFocusable(true); 
} 

//for use in setting and getting the borders of the game 
public void setX(int x){ 
    this.x = x; 
} 
public int getX(){ 
    return x; 
} 

public void setY(int y){ 
    this.y = y; 
} 
public int getY(){ 
    return y; 
} 

public void paintGame(Graphics g){ 
    super.paint(g); 
    g.drawImage(p.getPlayerImage(), p.getPlayerX(), p.getPlayerY(), null); 
} 
@Overrride 
public void actionPerformed(ActionEvent ae){ 
    repaint(); 
} 
} 

class Move extends Layout implements KeyListener { //Inheritance 
public void keyPressed(KeyEvent press) { //for the movement in the game 
    //I used both keys so that if the player woukld like to use WASD or the arrow keys either will work 
    if(press.getKeyCode() == KeyEvent.VK_W || press.getKeyCode() == KeyEvent.VK_UP){ 
     //move up 
     p.setPlayerY(p.getPlayerY() - p.getMoveSpeed()); 
    } 
    else if(press.getKeyCode() == KeyEvent.VK_S || press.getKeyCode() == KeyEvent.VK_DOWN){ 
     //move down 
     p.setPlayerY(p.getPlayerY() + p.getMoveSpeed()); 
    } 
    else if(press.getKeyCode() == KeyEvent.VK_A || press.getKeyCode() == KeyEvent.VK_LEFT){ 
     //move left 
     p.setPlayerX(p.getPlayerX() - p.getMoveSpeed()); 
    } 
    else if(press.getKeyCode() == KeyEvent.VK_D || press.getKeyCode() == KeyEvent.VK_RIGHT){ 
     //move right 
     p.setPlayerX(p.getPlayerX() + p.getMoveSpeed()); 
    } 
} 


public void keyReleased(KeyEvent release) { 
    //nothing is needed here 
} 

public void keyTyped(KeyEvent e) { 
    //does nothing if a key is type (no need for it) 
} 
} 

最后是应该运行游戏的游戏类(目前我只是试图让玩家跨越一个空格移动,而不尚未实现地图)。

public class Play { 
public static void main(String[]args) { 
    play(); 
} 

public static void play(){ 
    Layout l = new Layout(); 
    Player p = new Player(); 
    Maze m = new Maze(); 

    l.setSize(l.getX(), l.getY()); //size can be changed in layout 
    l.setVisible(true); 
} 
} 

由于某种原因,当我尝试运行此操作时,出现大量错误。我希望很快得到解决,所以我可以开始实施我的迷宫地图。下面是我收到的错误:

Exception in thread "main" java.lang.*Error 
at java.lang.ref.SoftReference.get(Unknown Source) 
at sun.misc.SoftCache$ValueCell.strip(Unknown Source) 
at sun.misc.SoftCache$ValueCell.access$300(Unknown Source) 
at sun.misc.SoftCache.get(Unknown Source) 
at sun.awt.SunToolkit.getImageFromHash(Unknown Source) 
at sun.awt.SunToolkit.getImage(Unknown Source) 
at javax.swing.ImageIcon.<init>(Unknown Source) 
at javax.swing.ImageIcon.<init>(Unknown Source) 
at mazeGame.Player.<init>(Player.java:16) 
at mazeGame.Layout.<init>(Layout.java:11) 
at mazeGame.Move.<init>(Layout.java:49) 
at mazeGame.Layout.<init>(Layout.java:20) 

的:at mazeGame.Move.<init>(Layout.java:49) at mazeGame.Layout.<init>(Layout.java:20)仍在继续为atleast 20行的Eclipse停止outputing错误之前。 请帮我解决这个问题,因为我目前一直在关注如何让玩家移动,并需要开始创建迷宫地图。对不起,真的很长的帖子,但我想发布任何可能会给我的错误。

问题是你的构造函数中有无限递归。 Layout()调用addKeyListener(new Move());Move延伸Layout,所以Move的构造函数也调用Layout(),它又调用Move()

您需要重构代码才能避免这种情况。一个简单的方法将使移动不扩展布局,并将玩家作为构造参数传递给Move

class Move implements KeyListener { 
    final Player p; 
    Move(Player p) { 
     this.p = p; 
    } 
    ... 
} 

Layout

addKeyListener(new Move(p)); 

还要考虑使用key bindings,而不是一个关键听众。这通常是一种更好的方法。

+0

现在它运行,它运行了几秒钟,然后终止。没有Java屏幕显示或任何东西,所以现在我无法真正玩游戏,并测试人物的动作。 – user1234

+0

好,所以我把它改为JFrame,但是现在我只是一个空白的屏幕没有任何东西正在绘制... – user1234

+0

@ user1234我不能确定什么是错的,因为我没有相关的代码 - 这个问题与“JFrames”无关。可见代码不会从任何相关位置调用repaint()(这应该很可能在移动后完成),也可以通过'repaint()'正确绘制它自己,以覆盖'paintComponent()'。有关详细信息,请参见[自定义绘画在摆动](https://docs.oracle.com/javase/tutorial/uiswing/painting/)。 – kiheru

尝试更换线路:通过使用媒体跟踪监视装载

character = ImageIO.read(new File("E://Workspace//Maze//images//Player.jpg")); 

我认为,问题可能是由ImageIcon的的异步加载的原因(图像将被预装:

ImageIcon player = new ImageIcon("E://Workspace//Maze//images//Player.jpg"); 
character = player.getImage(); 

与)http://docs.oracle.com/javase/7/docs/api/javax/swing/ImageIcon.html

+0

当我这样做时,我得到一个错误,但是当我保留我的旧的它的工作。我不知道为什么(我得到了IOException错误)。 – user1234