我正在编写一个小游戏,我在交叉路口遇到了一些问题。我需要一个有效的算法来检查两个对象(有x和y坐标,还有宽度和高度)是否相交。
我尝试了以下内容,但它并不总是有效,有时它不会识别交叉点。
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x >= this.x) && (y < this.y + this.height) && (y >= this.y))
return true;
else
return false;
}
我有一个包含对象的ArrayList,我执行以下操作:
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equalsIgnoreCase("right") && car.contains(walls.get(i).getX() - 1, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("left") && car.contains(walls.get(i).getX() + 30, walls.get(i).getY()))
return true;
if (pDirection.equalsIgnoreCase("top") && car.contains(walls.get(i).getX(), walls.get(i).getY() + 30))
return true;
if (pDirection.equalsIgnoreCase("down") && car.contains(walls.get(i).getX(), walls.get(i).getY() - 1))
return true;
}
return false;
}
注意“-1”和“+30”是为了避免汽车进入“墙壁”,那里的墙壁宽度为30,高度为30.汽车也有相同的尺寸。
另请注意,x和y是矩形的左上角。汽车和墙壁是矩形。
我很感谢你的帮助。
信息:如果我在墙上方并且我将方向改为“向下”或反之,则它不会在一排墙的开始处重新识别交叉点。 See picture
编辑1(我尝试反转对象,但它也不总是有效):
private boolean checkIntersection(String pDirection) {
for (int i = 0; i < walls.size(); i++) {
if (pDirection.equals("right") && walls.get(i).contains(car.getX() + 30, car.getY()))
return false;
if (pDirection.equals("left") && walls.get(i).contains(car.getX() - 1, car.getY()))
return false;
if (pDirection.equals("top") && walls.get(i).contains(car.getX(), car.getY() - 1))
return false;
if (pDirection.equals("down") && walls.get(i).contains(car.getX(), car.getY() + 30))
return false;
}
return true;
}
答案 0 :(得分:0)
算法中的缺陷是,你总是检查墙的左上角是否在汽车中。但是,这并不等同于交叉。
相反,您应检查其中任何一个对象是否包含(至少)另一个对象的一个角(不一定是左上角)。
请注意,您应对两侧执行此检查,即车辆包含墙壁的任何角落或墙壁包含汽车的任何角落。
答案 1 :(得分:0)
我解决了以下面的方式修改contains方法,它现在完美无缺:
public boolean contains(int x, int y) {
if ((x < this.x + this.width) && (x > this.x-this.width) && (y < this.y + this.height) && (y > this.y-this.height))
return true;
else
return false;
}
我认为我不由自主地做了(检查非交叉而不是交叉),但我可以使用@samgak和@Gene的答案/建议来优化它。谢谢,问题解决了。