Вопрос

I am trying to build a basic Arcanoid/Breakout style game in JAVA. I am having trouble with the collision detection between the ball and the bricks. I am using bounding boxes around all entities in the game. When the ball hits the player's paddle, the collision is detected. When the ball hits the bricks coordinates, no collision is detected. Any one have any ideas. Code below.

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;
}
}
Это было полезно?

Решение

When you check for collisions with this line

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

you're only checking intersection with one brick, brick, and not with the other 9 bricks you made, brick1, ..., brick9.

I'd recommend making an array of bricks, and then looping through them and checking collisions with each of them. Then, you can have as many bricks as you want and it won't take more code to check.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top