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(){}
и так далее.