Java、LibGDX、矩形交集因负尺寸而失败?
Java, LibGDX, Rectangle intersection fails with negative dimensions?
我正在 Java 和 LibGDX 中制作一个用于 RTS 游戏的单位选择器。我创建了一个矩形来检查单位碰撞箱是否与选择的碰撞箱发生碰撞,如果是,该单元将添加到所选单位列表中。
如果我在一个方向上拖动鼠标,则会选择单位,而在另一个方向上,(当创建带有负 width/height 的矩形时,它们不会)。你对这是为什么有什么建议吗?
谢谢。
选择器代码:
boolean selectInProg = false;
public List<Entity> createSelection(List<Entity> entities){
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
if(!selectInProg){
xDown = Gdx.input.getX();
yDown = Gdx.graphics.getHeight() - Gdx.input.getY();
selectInProg = true;
}
hitbox.set(xDown, yDown, Gdx.input.getX() - xDown, (Gdx.graphics.getHeight() - Gdx.input.getY()) - yDown);
}else{
hitbox = new Rectangle();
selectInProg = false;
}
List<Entity> selected = new ArrayList();
for(Entity entity : entities){
if(Intersector.intersectRectangles(hitbox, entity.hitbox, new Rectangle())){
selected.add(entity);
entity.selected = true;
}
}
return selected;
}
取自here and here,那是因为Rectangle.overlaps
:
public boolean overlaps (Rectangle r) {
return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
}
此代码假定矩形的 widths/heights 具有相同的符号。因此,如果 x
描述了 两个 矩形的左侧或右侧,它就有效。当然,这同样适用于 y
。但是,如果 x
描述矩形 1 的右侧和矩形 2 的左侧,它 不 起作用。
我建议你简单地构造你的 Rectangle 来覆盖 overlaps
:
hitbox = new Rectangle(){
public boolean overlaps (Rectangle r) {
float left = Math.min(x, x + width);
float right = Math.max(x, x + width);
float top = Math.min(y, y + height);
float bottom = Math.max(y, y + height);
float left2 = Math.min(r.x, r.x + r.width);
float right2 = Math.max(r.x, r.x + r.width);
float top2 = Math.min(r.y, r.y + r.height);
float bottom2 = Math.max(r.y, r.y + r.height);
return left < right2 && right > left2 && top < bottom2 && bottom > top2;
}
};
那么重要的是将 hitbox
作为第一个参数传递给 Intersector.intersectRectangles
,但你已经这样做了。
当然,如果你更喜欢上面的内容,你也可以在一行中支持:
hitbox = new Rectangle(){
public boolean overlaps (Rectangle r) {
return Math.min(x, x + width) < Math.max(r.x, r.x + r.width) && Math.max(x, x + width) > Math.min(r.x, r.x + r.width) && Math.min(y, y + height) < Math.max(r.y, r.y + r.height) && Math.max(y, y + height) > Math.min(r.y, r.y + r.height);
}
};
我正在 Java 和 LibGDX 中制作一个用于 RTS 游戏的单位选择器。我创建了一个矩形来检查单位碰撞箱是否与选择的碰撞箱发生碰撞,如果是,该单元将添加到所选单位列表中。
如果我在一个方向上拖动鼠标,则会选择单位,而在另一个方向上,(当创建带有负 width/height 的矩形时,它们不会)。你对这是为什么有什么建议吗?
谢谢。
选择器代码:
boolean selectInProg = false;
public List<Entity> createSelection(List<Entity> entities){
if(Gdx.input.isButtonPressed(Input.Buttons.LEFT)){
if(!selectInProg){
xDown = Gdx.input.getX();
yDown = Gdx.graphics.getHeight() - Gdx.input.getY();
selectInProg = true;
}
hitbox.set(xDown, yDown, Gdx.input.getX() - xDown, (Gdx.graphics.getHeight() - Gdx.input.getY()) - yDown);
}else{
hitbox = new Rectangle();
selectInProg = false;
}
List<Entity> selected = new ArrayList();
for(Entity entity : entities){
if(Intersector.intersectRectangles(hitbox, entity.hitbox, new Rectangle())){
selected.add(entity);
entity.selected = true;
}
}
return selected;
}
取自here and here,那是因为Rectangle.overlaps
:
public boolean overlaps (Rectangle r) {
return x < r.x + r.width && x + width > r.x && y < r.y + r.height && y + height > r.y;
}
此代码假定矩形的 widths/heights 具有相同的符号。因此,如果 x
描述了 两个 矩形的左侧或右侧,它就有效。当然,这同样适用于 y
。但是,如果 x
描述矩形 1 的右侧和矩形 2 的左侧,它 不 起作用。
我建议你简单地构造你的 Rectangle 来覆盖 overlaps
:
hitbox = new Rectangle(){
public boolean overlaps (Rectangle r) {
float left = Math.min(x, x + width);
float right = Math.max(x, x + width);
float top = Math.min(y, y + height);
float bottom = Math.max(y, y + height);
float left2 = Math.min(r.x, r.x + r.width);
float right2 = Math.max(r.x, r.x + r.width);
float top2 = Math.min(r.y, r.y + r.height);
float bottom2 = Math.max(r.y, r.y + r.height);
return left < right2 && right > left2 && top < bottom2 && bottom > top2;
}
};
那么重要的是将 hitbox
作为第一个参数传递给 Intersector.intersectRectangles
,但你已经这样做了。
当然,如果你更喜欢上面的内容,你也可以在一行中支持:
hitbox = new Rectangle(){
public boolean overlaps (Rectangle r) {
return Math.min(x, x + width) < Math.max(r.x, r.x + r.width) && Math.max(x, x + width) > Math.min(r.x, r.x + r.width) && Math.min(y, y + height) < Math.max(r.y, r.y + r.height) && Math.max(y, y + height) > Math.min(r.y, r.y + r.height);
}
};