【问题标题】:JAVA Bounding Box / Collison DetectionJAVA边界框/碰撞检测
【发布时间】:2014-02-04 07:48:39
【问题描述】:

我正在尝试用 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);
    }
}
}

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

【问题讨论】:

  • 您不能只发布您的整个项目并要求我们查看所有内容。请发布一个最小的工作示例(或只是碰撞代码)。话虽如此,您是否有可能只检查与 Game.brick 的碰撞而不是检查所有的砖块?
  • 我们不是调试器的替代品。通过调试器(Eclipse 自带)运行你的代码,然后一步一步地运行,看看有什么问题。
  • 点了。我第一次在 Stack Overflow 上。干杯。
  • 这是“Java”而不是“JAVA”。 Java 不是首字母缩写词。

标签: java bounding-box


【解决方案1】:

当你检查与这条线的冲突时

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

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

我建议制作一组砖块,然后循环遍历它们并检查每个砖块的碰撞情况。然后,您可以拥有任意数量的积木,而无需检查更多代码。

【讨论】:

  • 感谢您的帮助。
猜你喜欢
  • 2015-02-01
  • 1970-01-01
  • 2015-02-02
  • 1970-01-01
  • 1970-01-01
  • 2011-04-21
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多