2014-01-15 118 views
0

我想在JAVA中构建一个基本的Arcanoid/Breakout风格的游戏。我在球和砖之间的碰撞检测方面遇到了麻烦。我在游戏中的所有实体周围都使用了边界框。当球击中球员的桨时,就会检测到碰撞。当球击中砖块坐标时,不会检测到碰撞。有人有主意吗。下面的代码。JAVA边界框/ Collison检测

Game.java

package com.seadnamcgillycuddy.unipong; 

import java.awt.Color; 
import java.awt.Font; 
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.JOptionPane; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

@SuppressWarnings("serial") 
public class Game extends JPanel { 

Ball ball = new Ball(this); 
Paddle paddle = new Paddle(this); 
Brick brick = new Brick(this, 50, 20); 
Brick brick2 = new Brick(this, 75, 20); 
Brick brick3 = new Brick(this, 100, 20); 
Brick brick4 = new Brick(this, 125, 20); 
Brick brick5 = new Brick(this, 150, 20); 
Brick brick6 = new Brick(this, 175, 20); 
Brick brick7 = new Brick(this, 200, 20); 
Brick brick8 = new Brick(this, 225, 20); 
Brick brick9 = new Brick(this, 250, 20); 
int speed = 1; 

private int getScore() { 
    return speed - 1; 
} 

public Game() { 
    addKeyListener(new KeyListener() { 
     @Override 
     public void keyTyped(KeyEvent e) { 
     } 

     @Override 
     public void keyReleased(KeyEvent e) { 
      paddle.keyReleased(e); 
     } 

     @Override 
     public void keyPressed(KeyEvent e) { 
      paddle.keyPressed(e); 
     } 
    }); 
    setFocusable(true); 
} 

private void move() { 
    ball.move(); 
    paddle.move(); 
} 

@Override 
public void paint(Graphics g) { 
    super.paint(g); 
    Graphics2D g2d = (Graphics2D) g; 
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
    ball.paint(g2d); 
    paddle.paint(g2d); 
    brick.paint(g2d); 
    brick2.paint(g2d); 
    brick3.paint(g2d); 
    brick4.paint(g2d); 
    brick5.paint(g2d); 
    brick6.paint(g2d); 
    brick7.paint(g2d); 
    brick8.paint(g2d); 
    brick9.paint(g2d); 


    g2d.setColor(Color.GRAY); 
    g2d.setFont(new Font("Verdana", Font.BOLD, 30)); 
    g2d.drawString(String.valueOf(getScore()), 10, 30); 
} 

public void gameOver() { 
    JOptionPane.showMessageDialog(this, "Your Score Is: " + getScore(), "Game Over", JOptionPane.YES_NO_OPTION); 
    System.exit(ABORT); 
} 

public static void main(String[] args) throws InterruptedException { 
    JFrame frame = new JFrame("UniPong"); 
    Game game = new Game(); 
    frame.add(game); 
    frame.setSize(400, 750); 
    frame.setVisible(true); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    while (true){ 
     game.move(); 
     game.repaint(); 
     Thread.sleep(10); 
    } 
} 
} 

Ball.java

package com.seadnamcgillycuddy.unipong; 

import java.awt.Graphics2D; 
import java.awt.Rectangle; 

public class Ball { 

private static final int DIAMETER = 10; 
int x = 0; 
int y = 0; 
int xa = 1; 
int ya = 1; 
private Game game; 

public Ball(Game game) { 
    this.game = game; 
} 

void move() { 
    boolean changeDirection = true; 
    if (x + xa < 0) 
     xa = game.speed; 

    else if (brickCollision()){ 
     System.out.println("Collission!!!!"); 


    } 
    else if (x + xa > game.getWidth() - DIAMETER) 
     xa = -game.speed; 
    else if (y + ya < 0) 
     ya = game.speed; 
    else if (y + ya > game.getHeight() - DIAMETER) 
     game.gameOver(); 
    else if (collision()) { 
     ya = -game.speed; 
     y = game.paddle.getTopY() - DIAMETER; 
     game.speed++; 

    } else 
     changeDirection = false; 

    x = x + xa; 
    y = y + ya; 
} 

private boolean collision() { 
    return game.paddle.getBounds().intersects(getBounds()); 
} 

private boolean brickCollision() { 
    return game.brick.getBounds().intersects(getBounds()); 
    //return game.ball.getBounds().intersects(getBounds()); 
} 

public void paint (Graphics2D g) { 
    g.fillOval(x, y, DIAMETER, DIAMETER); 
} 

public Rectangle getBounds() { 
    return new Rectangle(x, y, DIAMETER, DIAMETER); 
} 
} 

Brick.java

package com.seadnamcgillycuddy.unipong; 

import java.awt.Graphics2D; 
import java.awt.Rectangle; 

public class Brick { 

int Y; 
int X; 
private static final int WIDTH = 20; 
private static final int HEIGHT = 10; 

private Game game; 

public Brick(Game game, int X, int Y) { 
    this.X = X; 
    this.Y = Y; 
    this.game = game; 
} 

public void paint(Graphics2D g) { 
    g.fillRect(X, Y, WIDTH, HEIGHT); 
} 

public Rectangle getBounds() { 
    return new Rectangle(X, Y, WIDTH, HEIGHT); 
} 

public int getBrickBottomY() { 
    return Y - HEIGHT; 
} 

} 

Paddle.java

package com.seadnamcgillycuddy.unipong; 

import java.awt.Graphics2D; 
import java.awt.event.KeyEvent; 
import java.awt.Rectangle; 

public class Paddle { 

private static final int Y = 680; 
private static final int WIDTH = 60; 
private static final int HEIGHT = 10; 
int x = 0; 
int xa = 0; 
private Game game; 

public Paddle(Game game) { 
    this.game = game; 
} 

public void move() { 
    if (x + xa > 0 && x + xa < game.getWidth() - 60) 
     x = x + xa; 
} 

public void paint(Graphics2D g) { 
    g.fillRect(x, Y, WIDTH, HEIGHT); 
} 

public void keyReleased(KeyEvent e) { 
    xa = 0; 
} 

public void keyPressed(KeyEvent e) { 
    if (e.getKeyCode() == KeyEvent.VK_LEFT) 
     xa = -game.speed; 
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) 
     xa = game.speed; 
} 

public Rectangle getBounds() { 
    return new Rectangle(x, Y, WIDTH, HEIGHT); 
} 

public int getTopY() { 
    return Y - HEIGHT; 
} 
} 
+0

你不能只发布你的整个项目,并要求我们浏览一切。请发布一个最简单的工作示例(或只是碰撞代码)。这就是说,是否有可能你只是检查与Game.brick的碰撞,而不是所有的砖块? – RaptorDotCpp

+0

我们不是调试器的替代品。通过一个调试器运行你的代码(Eclipse自带一个)并逐步运行,看看有什么不对。 – Darkhogg

+1

采取了点。我第一次在堆栈溢出。干杯。 – user3199261

回答

5

当你检查碰撞这一行

return game.brick.getBounds().intersects(getBounds()); 

你只用一砖一瓦,brick,而不是检查路口与您提出的其他9个砖,brick1,... brick9

我建议制作一系列砖块,然后循环遍历它们并检查每块砖块的碰撞情况。然后,你可以拥有尽可能多的砖块,而且不需要更多的代码来检查。

+0

谢谢你的帮助。 – user3199261