2015-01-24 1 views
0

Я делаю селектор единиц для использования в игре RTS, на Java с LibGDX. Я создал прямоугольник, чтобы проверить, сталкивается ли блок hitbox с ячейкой выбора, и если это так, блок добавляется в список выбранных единиц.Java, LibGDX, пересечение прямоугольника с отрицательными размерами?

Если я перетаскиваю мышь в одном направлении, то единицы выбираются, а в другом (когда создается прямоугольник с отрицательной шириной/высотой, это не так). Есть ли у вас какие-либо предложения, почему это так.

Спасибо.

Код для выбора:

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; 

} 

Arrow shows mouse movement during selection, on the left the entities are selected. On the right they are not.

ответ

1

Взятые из here и 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; 
} 

Этот код предполагает, что ширина/heig hts прямоугольников имеют один и тот же знак. Так что, если x описывает левую или правую сторону и прямоугольников, это работает. То же самое относится и к y. Однако, если x описывает правую сторону прямоугольника 1 и левую сторону прямоугольника 2, то не Работа.

Я предлагаю вам просто построить прямоугольник, чтобы переопределить 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); 
    } 
}; 
+0

Это гениальные спасибо, работает отлично! – DrDominic