好的,调整我在这里找到的一些代码,我想出了一个完美的解决方案:
Float newX = ev.getX() - (b.getMeasuredWidth()/2);
Float newY = ev.getY() - (b.getMeasuredHeight()/2);
for (TouchButton t:myButtons)
{
if(!(t.equals(b)))
{
Rectangle r1 = new Rectangle(t.getX(), t.getY(), (float)t.getMeasuredWidth(), (float)t.getMeasuredHeight());
Rectangle r2 = new Rectangle(newX, b.getY(), (float)b.getMeasuredWidth(), (float) b.getMeasuredHeight());
Rectangle r3 = new Rectangle(b.getX(), newY, (float)b.getMeasuredWidth(), (float) b.getMeasuredHeight());
if(r1.interects(r2))
{
MoveX = false;
}
if(r1.interects(r3))
{
MoveY = false;
}
}
}
这是 Rectangle.java:
public class Rectangle
{
private Float startX;
private Float startY;
private Float width;
private Float height;
private Float endX;
private Float endY;
public Rectangle(Float _x, Float _y, Float _width, Float _height)
{
startX = _x;
startY = _y;
width = _width;
height = _height;
endX = _width + _x;
endY = _height + _y;
}
public Float getX()
{
return startX;
}
public Float getY()
{
return startY;
}
public float getWidth()
{
return width;
}
public float getHeight()
{
return height;
}
public float getEndX()
{
return endX;
}
public float getEndY()
{
return endY;
}
public boolean interects (Rectangle _r2)
{
return rectOverlap(this, _r2);
}
private boolean valueInRange(float value, float min, float max)
{ return (value >= min) && (value <= max); }
private boolean rectOverlap(Rectangle A, Rectangle B)
{
boolean xOverlap = valueInRange(A.getX(), B.getX(), B.getEndX()) ||
valueInRange(B.getX(), A.getX(), A.getEndX());
boolean yOverlap = valueInRange(A.getY(), B.getY(), B.getEndY()) ||
valueInRange(B.getY(), A.getY(), A.getY() + B.getHeight());
return xOverlap && yOverlap;
}
}
[这里是旧的断断续续的答案]
[出于历史目的]
我不确定这有多优雅,也许有人可以想出更好的东西?
基于 Khaled A Khunaifer 的回答,我意识到如果要进行移动,我需要检查按钮的放置位置,然后仅在之后没有碰撞的情况下执行每个移动:
Boolean MoveX = true;
Boolean MoveY = true;
Float newX = ev.getX() - (b.getMeasuredWidth()/2);
Float newY = ev.getY() - (b.getMeasuredHeight()/2);
for (TouchButton t:myButtons)
{
if(!(t.equals(b)))
{
if (areOverlapping(t,b.getX(), newY))
{
MoveY=false;
}
if(areOverlapping(t,newX,b.getY()))
{
MoveX = false;
}
}
}
if (MoveX)
{
b.setX(newX);
}
if (MoveY)
{
b.setY(newY);
}
boolean areOverlapping (TouchButton a, double x, double y)
{
return (y >= a.getY()
&& (y <= (a.getY() + a.getMeasuredHeight()))
&& x >= a.getX()
&& (x <= (a.getX() + a.getMeasuredWidth())));
}
这种实现了我正在寻找的东西,但它有点不稳定,有时允许按钮重叠。我将尝试使用 areTouching 进行试验,但我需要先解码逻辑,因为它的编写方式会产生错误。