Java: Hit Detection неправильно обнаруживает перекрытие между двумя объектами

Поэтому у меня есть игра в гребле, в которой объект лодки должен уклоняться от случайно расположенных объектов препятствий с помощью клавиш со стрелками. Если лодка попадает в одно из препятствий, лодка получает случайное количество урона. Лодка представляет собой картинку 27х52 (с 2 пикселями по обе стороны ничего нет, поэтому код показывает 2-25), а препятствия - это прямоугольники.

У меня обнаружение попадания работает по большей части; однако всякий раз, когда лодка находится с правой стороны прямоугольника, который выше ее ширины, она будет повреждена, даже если лодка находится на расстоянии 5-10 пикселей от правого края прямоугольника. Обратитесь к этому изображению для лучшего понимания проблемы: http://imgur.com/pqDLMrl

В своем коде я создаю массив из 15 препятствий. Препятствия принимают параметры (Цветовой цвет, intmageDealt, int xPos, int yPos, int width, int height, логический hasHit).

//Create array of obstacles
for(int x = 0; x < 15; x++) {
        obstacles[x] = new Obstacle((new Color(rand.nextInt(81), rand.nextInt(51), rand.nextInt(51))), rand.nextInt(21) + 10, rand.nextInt(601), 
            (-x * (rand.nextInt(51) + 31)), (rand.nextInt(31) + 5), (rand.nextInt(31) + 5), false); 
    }

Вот код обнаружения попадания (это цикл for, циклически проходящий по массиву объектов препятствий:

for(int y = 2; y <= 25; y++) {
                //Obstacles hit detection
                for(int z = 0; z <= obstacles[x].getw(); z++) {           
                      if(boat.getx() + y == obstacles[x].getx() + z && boat.gety() == obstacles[x].gety()) {
                            if(!obstacles[x].getDamaged()) {
                                 boat.setHealth(boat.getHealth() - obstacles[x].getdmg());
                                 obstacles[x].setDamaged(true);
                            }
                      }             
                }

Прямо сейчас он циклически перебирает значения x лодки, от 2 до 25, вместо от 0 до 27, потому что два пикселя ничего не стоят по обе стороны. Затем он циклически перебирает значения x препятствия (от xPos до xPos+width) и проверяет, совпадает ли какое-либо из этих значений. Если есть совпадение, и значения y совпадают, тогда лодка получит повреждение. Имейте в виду, что это происходит только тогда, когда лодка находится на правой стороне препятствия, и препятствие выше, чем оно широко. Я не вижу проблемы с моим кодом, но не могу найти решение для моей ошибки. Благодарю.

РЕДАКТИРОВАТЬ: Вот код для классов лодки и препятствий.

import java.awt.Color;
import java.awt.Rectangle;

public class Obstacle {
    private int dmg, xPos, yPos, height, width;
    private Color color;
    private boolean hasDamaged;

    public Obstacle(Color hue, int damage, int x, int y, int w, int h, boolean damaged) {
        dmg = damage;
        xPos = x;
        yPos = y;
        width = w;
        height = h;
        color = hue;
        hasDamaged = damaged;
    }

    public boolean getDamaged() {
        return hasDamaged;
    }
    public void setDamaged(boolean damaged) {
        hasDamaged = damaged;
    }

    public Color getColor() {
        return color;
    }

    public int getdmg() {
        return dmg;
    }
    public void setdmg(int damage) {
        dmg = damage;
    }

    public int getx() {
        return xPos;
    }
    public void setx(int x) {
        xPos = x;
    }

    public int gety() {
        return yPos;
    }
    public void sety(int y) {
        yPos = y;
    }

    public int getw() {
        return width;
    }
    public void setw(int w) {
        width = w;
    }

    public int geth() {
        return height;
    }
    public void seth(int h) {
        height = h;
    }

    public Rectangle getBounds() {
        return new Rectangle(xPos, yPos, width, height);
    }
}

И класс лодки:

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.Rectangle;

public class Boat {

private int hp, xPos, yPos, dx;
private BufferedImage boatPic;

public Boat(BufferedImage img, int health, int x, int y, int velX) {
    boatPic = img;
    hp = health;
    xPos = x;
    yPos = y;
    dx = velX;
}


public BufferedImage getImage() {
    return boatPic;
}
public void setImage(BufferedImage img) {
    boatPic = img;
}

public int getHealth() {
    return hp;
}
public void setHealth(int health) {
    hp = health;
}

public int getx() {
    return xPos;
}
public void setx(int x) {
    xPos = x;
}

public int gety() {
    return yPos;
}
public void sety(int y) {
    yPos = y;
}

public int getdx() {
    return dx;
}
public void setdx(int velX) {
    dx = velX;
}

public Rectangle getBounds() {
    return new Rectangle(xPos, yPos, 25, 49);
}    
}

1 ответ

Решение

Если ваш корабль всегда направлен в одном направлении, вы можете намного легче проверить столкновение.

Создав метод для вашего корабля и для препятствий, который возвращает прямоугольник с размером вашего объекта.

public Rectangle getBounds() {
    return new Rectangle(shipPosX, shipPosY, widht, height);
}

Как это. Таким образом, вы можете проверить столкновение в одной строке:

getBounds().intersects(obstacle.getBounds());

Это вернет истину, если они пересекаются.

Если вы хотите быть более точным или хотите использовать разные случаи столкновений с разных направлений, вы можете создать прямоугольник для разных частей вашего корабля, таких как его тело и крылья.

public Rectangle getRightWingBound(){}
public Rectangle getLeftWindBound(){}

и так далее.

Другие вопросы по тегам