爪哇:瓷砖碰撞的问题

我使用PNG的BufferedImage(img)创建了一个平铺的地图。 从这个角度来看,我想要在地图上检测到玩家与对象之间的碰撞。 但是,我的代码将不会运行,控制台给我: 线程“main”java.lang.StackOverflowErrorexception

我正在做这个跨越单独的课程:彼得和地图

在我的Peter课程中,我为玩家创建了碰撞盒(左,右,上,下)。 我想这样做是为了让玩家的不同侧面的碰撞能够被检测到。

public Rectangle getBoundsL() { return new Rectangle(x, y+4, 4, HEIGHT-8); } public Rectangle getBoundsR() { return new Rectangle(x+WIDTH-4, y+4, 4, HEIGHT-8); } public Rectangle getBoundsU(){ return new Rectangle(x+4, y, WIDTH-8, 4); } public Rectangle getBoundsD(){ return new Rectangle(x+4, y+HEIGHT-4, WIDTH-8, 4); } 

在我的Map类中,我通过一个嵌套的for循环来检查BufferedImage像素的颜色,以绘制代表墙的边界的矩形。

我的checkCollision方法应该返回一个布尔值,当一个玩家的碰撞盒与任何一个墙砖(在这种情况下,玩家的左边的方框)相交。

 Peter peter = new Peter(); public boolean checkCollisionL(){ for(int y = 0; y < mapHeight; y++){ for(int x = 0; x < mapWidth; x++){ if((img.getRGB(x,y) == 0xff000000) && peter.getBoundsL().intersects(new Rectangle(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE))){ return true; } } } return false; } 

但是我的游戏无法运行,而控制台反而给我以下错误:

  Exception in thread "main" java.lang.StackOverflowError at peterslostworld.Peter.<init>(Peter.java:12) at peterslostworld.Map.<init>(Map.java:25) at peterslostworld.Peter.<init>(Peter.java:12) at peterslostworld.Map.<init>(Map.java:25) at peterslostworld.Peter.<init>(Peter.java:12) at peterslostworld.Map.<init>(Map.java:25) etc, etc.... 

这对我来说(至less对我来说)是在Map类中引用Peter类时需要解决的问题。 但是,我不知道如何解决这个问题。

编辑:根据要求,这里是游戏中涉及(不完整)的类:

  package peterslostworld; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; @SuppressWarnings("serial") public class PetersLostWorld extends JPanel { Peter pete = new Peter(this); Map map = new Map(); public PetersLostWorld() { addKeyListener(new KeyListener() { @Override public void keyTyped(KeyEvent e) { } @Override public void keyReleased(KeyEvent e) { pete.keyReleased(e); } @Override public void keyPressed(KeyEvent e) { pete.keyPressed(e); } }); setFocusable(true); } @Override public void paint(Graphics g) { super.paint(g); Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); map.paint(g2); pete.paint(g2); } public static void main(String[] args) throws InterruptedException { JFrame frame = new JFrame("Peter's Lost World"); PetersLostWorld game = new PetersLostWorld(); frame.add(game); frame.setSize(800, 600); frame.setVisible(true); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); while (true) { game.repaint(); Thread.sleep(10); } } } package peterslostworld; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.event.KeyEvent; public class Peter { private static final int WIDTH = 32; private static final int HEIGHT = 32; Map map = new Map(); boolean right = false; boolean left = false; boolean up = false; boolean down = false; int x = 40; int y = 40; int pSpeed = 5; private PetersLostWorld game; public Peter(PetersLostWorld game) { this.game = game; } Peter() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_A){ left = true; } if (e.getKeyCode() == KeyEvent.VK_D){ right = true; } if (e.getKeyCode() == KeyEvent.VK_W){ up = true; } if (e.getKeyCode() == KeyEvent.VK_S){ down = true; } } public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_A){ left = false; } if (e.getKeyCode() == KeyEvent.VK_D){ right = false; } if (e.getKeyCode() == KeyEvent.VK_W){ up = false; } if (e.getKeyCode() == KeyEvent.VK_S){ down = false; } } public void paint(Graphics2D g2) { g2.setColor(Color.red); g2.fillRect(x, y, WIDTH, HEIGHT); if(left){ x-=pSpeed; } if(right){ x+=pSpeed; } if(up){ y-=pSpeed; } if(down){ y+=pSpeed; } g2.setColor(Color.blue); g2.draw(getBoundsL()); g2.draw(getBoundsR()); g2.draw(getBoundsU()); g2.draw(getBoundsD()); } public Rectangle getBoundsL() { return new Rectangle(x, y+4, 4, HEIGHT-8); } public Rectangle getBoundsR() { return new Rectangle(x+WIDTH-4, y+4, 4, HEIGHT-8); } public Rectangle getBoundsU(){ return new Rectangle(x+4, y, WIDTH-8, 4); } public Rectangle getBoundsD(){ return new Rectangle(x+4, y+HEIGHT-4, WIDTH-8, 4); } } package peterslostworld; import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class Map { String path = "C:\\Users\\Owner\\Documents\\Eclispe\\Game03\\src\\game03\\maze.png"; public int mapHeight = 0; public int mapWidth = 0; BufferedImage img; public Rectangle[] mapTiles = new Rectangle[mapWidth*mapHeight]; public boolean collideLeft = false; public boolean collideRight = false; public boolean collideUp = false; public boolean collideDown = false; public static int TILESIZE = 32; Peter peter = new Peter(); public Map(){ try{ BufferedImage image = ImageIO.read(new File(path)); img = image; mapHeight = image.getHeight(); mapWidth = image.getWidth(); } catch (IOException e){ } } public boolean checkCollisionL(){ for(int y = 0; y < mapHeight; y++){ for(int x = 0; x < mapWidth; x++){ if((img.getRGB(x,y) == 0xff000000) && peter.getBoundsL().intersects(new Rectangle(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE))){ return true; } } } return false; } public boolean checkCollisionR(){ for(int y = 0; y < mapHeight; y++){ for(int x = 0; x < mapWidth; x++){ if((img.getRGB(x,y) == 0xff000000) && peter.getBoundsR().intersects(new Rectangle(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE))){ return true; } } } return false; } public boolean checkCollisionU(){ for(int y = 0; y < mapHeight; y++){ for(int x = 0; x < mapWidth; x++){ if((img.getRGB(x,y) == 0xff000000) && peter.getBoundsU().intersects(new Rectangle(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE))){ return true; } } } return false; } public boolean checkCollisionD(){ for(int y = 0; y < mapHeight; y++){ for(int x = 0; x < mapWidth; x++){ if((img.getRGB(x,y) == 0xff000000) && peter.getBoundsD().intersects(new Rectangle(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE))){ return true; } } } return false; } public void paint(Graphics2D g2){ for(int y = 0; y < mapHeight; y++){ for(int x = 0; x < mapWidth; x++){ if(img.getRGB(x,y) == 0xff000000){ g2.fillRect(x*TILESIZE, y*TILESIZE, TILESIZE, TILESIZE); } } } } } 

在你的Map类中,你在第25行创建一个Peter对象:

 Peter peter = new Peter(); 

在你的Peter类中,你在第12行创建一个创建Map对象:

 Map map = new Map(); 

所以,当你创建这两个对象时,它将开始创建无限量的地图和Peters(可能不是你想要的)。

这是一个交叉引用的基本问题,可以通过删除我的答案顶部指定的两行之一来解决。

编辑

仔细看过你的代码,我可以看到你不需要在你的Peter类中创建一个Map对象,也不需要任何地图对象的句柄,所以你可以在第12行删除这行:

 Map map = new Map();