JAVA边界框/碰撞检测

时间:2014-01-15 17:28:40

标签: java bounding-box

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

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;
}
}

1 个答案:

答案 0 :(得分:5)

检查与此线路的碰撞时

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

你只用一块砖brick检查交叉点,而不是用你制作的其他9块砖,brick1,...,brick9

我建议制作一个砖块阵列,然后循环遍历它们并检查每个砖块的碰撞。然后,您可以拥有任意数量的砖块,并且不需要更多代码来检查。