我目前有一个Android应用程序,如果我单击屏幕上不是圆本身的某个位置,它会将绘制的圆移动到屏幕上的随机位置。
我的问题是,我如何实现它,使这个逻辑只在点击距离圆圈相对较近时执行?距离的定义并不严格,但是,如果一个圆位于屏幕的左下方,单击屏幕的右上方不会触发该圆移动到新位置。我在想象一个比圆形稍大的正方形,它可以作为点击框(但仍然排除圆形内的点击)
我假设必须在isInsideCircle函数中进行更改,但我缺乏必要的知识来理解应该添加/减去哪些变量来限制触发逻辑的区域。以下是我目前掌握的代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Circle(this));
}
public class Circle extends View {
private float x = 300;
private float y = 300;
private int r = 150;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Random random = new Random();
// draws circle
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
canvas.drawCircle(x, y, r, mPaint);
}
// constructor
public Circle(Context context) {
super(context);
}
// gets random coordinates
void generateRandom() {
int w = getWidth() - r - 50;
int h = getHeight()- r - 50;
int border = r + 50;
this.x = border + random.nextInt(w-border);
this.y = border + random.nextInt(h-border);
}
// when screen is tapped, old circle removed, new circle drawn
@Override
public boolean onTouchEvent(MotionEvent event) {
if (!isInsideCircle(event.getX(), event.getY())) { // only register clicks outside of circle
generateRandom();
invalidate();
}
return super.onTouchEvent(event);
}
boolean isInsideCircle(float xPoint, float yPoint) {
float dx = (x - xPoint);
float dxPow = (float) Math.pow(dx, 2);
float dy = (y - yPoint);
float dyPow = (float) Math.pow(dy, 2);
float radPow = (float) Math.pow(r, 2);
return ((dxPow + dyPow) <= radPow));
}
}
}
任何帮助都将不胜感激,谢谢!
这个问题有几个部分,我想确保在讨论之前非常清楚。
我实际上要先从第二点开始,然后继续到第一点。
这一点非常简单,因为您已经在测试单击是否在圆内,至少这是由类的isInsideCircle方法假设的。碰巧,如果你不是(!)的话,可以很安全地假设在圈内,你就在圈外。如果(!isInsideCircle(…)修改<代码>) 到<代码>如果(isInsideCircle(…)) (删除not[!])运营商)应该在这方面帮助我们,不是吗?嗯,这是相当痛苦的,希望测试是在一个正方形内是一样容易!
。。。不会像检查我们是否在袭击区域内部而不是外部那么容易
我的意思是,它确实需要在isInsideCircle执行的逻辑中进行整个转换。此外,我不确定更改isInsideCircle的主体是否是一个好主意,以测试它是否位于正方形内。这可能有点令人困惑,不是吗?
因此,创建一个新方法来测试给定的(x, y)坐标是否在正方形内可能是一个更好的主意。也许isInside Square
?等一下!一个Square
肯定不是一个Circle
那么,我们需要什么信息来表示Square
?现在我们需要一种方法来表示Square
以及一种方法来判断坐标是否在正方形内。正方形是一个特殊的矩形,您只需要一个特殊的坐标位置(顶点或确切的中心)和边长来比较坐标与它。我们只是碰巧有一个坐标位置可以用作中心,所以,我想我们需要hitbox的边长。让我们在我们的圆形类中添加一个新字段来表示hitbox边长。下面的行将默认为比圆的直径多50个像素。
private int hitboxLength = (2 * r) + 50;
现在我们有一个坐标点,有点遗憾,它位于正方形的中间,它是边长。那么,我们如何确定一个点是否在我们的方形命中框内?很高兴知道一个矩形也可以被描述为4个顶点。对于边长为2、以(0,0)为中心的正方形,顶点位于(1,1)、(1,-1)、(-1,-1)和(-1,1)。为了找出(x,y)是否在我们的矩形内,我们只需要不在这4个坐标内。X从1到-1,Y也从1到-1。如果x介于-1和1之间,则表示
boolean isInsideSquare(float xPoint, float yPoint) {
// The center of a square is HALF it's length from any vertex.
// Always try to use equivalent number types when comparing
float halfHitboxLength = this.hitboxLength / 2.0F;
float xUpperBound = this.x + halfHitboxLength;
float xLowerBound = this.x - halfHitboxLength;
// smallest expected X <= xPoint <= largest expected X
boolean xInSquare = xLowerBound <= xPoint && xPoint <= xUpperBound;
float yUpperBound = this.y + halfHitboxLength;
float yLowerBound = this.y - halfHitboxLength;
boolean yInSquare = yLowerBound <= yPoint && yPoint <= yUpperBound;
return xInSquare && yInSquare;
}
毫无疑问,这不是最有效的处理方法,但它应该为我们提供在给定范围内的逻辑。
现在我们只需要在onTouchEvent
方法中使用isInsideSquare
而不是isinsidercle
。
// This "if"
if (!isInsideCircle(event.getX(), event.getY())) {
// Would become
if (!isInsideSquare(event.getX(), event.getY())) {
然而,我不禁认为用正方形表示一个圆圈感觉有点奇怪。至少,考虑到它们的形状有多么不同。更不用说isInside Square
是否属于Circle
类的问题了!如何用另一个稍微大一点的圆圈外观来表示我们圆圈的命中区域?
我们已经有了检查(x,y)坐标对是否在当前圆内的逻辑。我的意思是有一种方法叫做isInsideCircle。
boolean isInsideCircle(float xPoint, float yPoint) {
float dx = (x - xPoint);
float dxPow = (float) Math.pow(dx, 2);
float dy = (y - yPoint);
float dyPow = (float) Math.pow(dy, 2);
float radPow = (float) Math.pow(r, 2);
return ((dxPow + dyPow) <= radPow));
}
就我个人而言,我的注意力立刻被吸引到了几个地方
返回,因为这是我们确定给定(xPoint,
yPoint)对是否在我们的圆实例中的方式,但更重要的是,radPow变量,因为它似乎是引用的,我只能假设是圆的半径,要测试一个更大的圆,我们真正需要做的就是调整它的半径!
int userWithinPixels = 50;
float radPow = (float) Math.pow(r + userWithinPixels, 2);
嗯,这是相当无痛的!
再次值得指出的是,在圆上调用isInsideCircle可以测试它是否在所表示的圆内而不是稍大的圆内,但这仍然是个人偏好,您应该做对项目程序员有意义的事情。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Circle(this));
}
public class Circle extends View {
private float x = 300;
private float y = 300;
private int r = 150;
// Add hitbox side length
private int hitboxLength = (2 * r) + 50;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Random random = new Random();
// draws circle
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
canvas.drawCircle(x, y, r, mPaint);
}
// constructor
public Circle(Context context) {
super(context);
}
// gets random coordinates
void generateRandom() {
int w = getWidth() - r - 50;
int h = getHeight()- r - 50;
int border = r + 50;
this.x = border + random.nextInt(w-border);
this.y = border + random.nextInt(h-border);
}
// when screen is tapped, old circle removed, new circle drawn
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isInsideSquare(event.getX(), event.getY())) { // only register clicks outside of circle
generateRandom();
invalidate();
}
return super.onTouchEvent(event);
}
boolean isInsideSquare(float xPoint, float yPoint) {
// The center of a square is HALF it's length from any vertex.
// Always try to use the same number types when comparing/computing
float halfHitboxLength = this.hitboxLength / 2.0F;
float xUpperBound = this.x + halfHitboxLength;
float xLowerBound = this.x - halfHitboxLength;
// smallest expected X <= xPoint <= largest expected X
boolean xInSquare = xLowerBound <= xPoint && xPoint <= xUpperBound;
float yUpperBound = this.y + halfHitboxLength;
float yLowerBound = this.y - halfHitboxLength;
boolean yInSquare = yLowerBound <= yPoint && yPoint <= yUpperBound;
return xInSquare && yInSquare;
}
boolean isInsideCircle(float xPoint, float yPoint) {
float dx = (x - xPoint);
float dxPow = (float) Math.pow(dx, 2);
float dy = (y - yPoint);
float dyPow = (float) Math.pow(dy, 2);
float radPow = (float) Math.pow(r, 2);
return ((dxPow + dyPow) <= radPow));
}
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new Circle(this));
}
public class Circle extends View {
private float x = 300;
private float y = 300;
private int r = 150;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Random random = new Random();
// draws circle
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColor(Color.RED);
canvas.drawCircle(x, y, r, mPaint);
}
// constructor
public Circle(Context context) {
super(context);
}
// gets random coordinates
void generateRandom() {
int w = getWidth() - r - 50;
int h = getHeight()- r - 50;
int border = r + 50;
this.x = border + random.nextInt(w-border);
this.y = border + random.nextInt(h-border);
}
// when screen is tapped, old circle removed, new circle drawn
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isInsideCircle(event.getX(), event.getY())) { // only register clicks outside of circle
generateRandom();
invalidate();
}
return super.onTouchEvent(event);
}
boolean isInsideCircle(float xPoint, float yPoint) {
float dx = (x - xPoint);
float dxPow = (float) Math.pow(dx, 2);
float dy = (y - yPoint);
float dyPow = (float) Math.pow(dy, 2);
// maximum amount of pixels user can click off the circle and trigger event
float userWithinPixels = 25;
float radPow = (float) Math.pow(r + userWithinPixels, 2);
return ((dxPow + dyPow) <= radPow));
}
}
}
我想在我的一个项目中更改RadioButton圆圈的颜色,但我不知道要设置哪个属性。背景色为黑色,因此不可见。我想把圆圈的颜色设置为白色。
问题内容: 如何将几个元素放置在另一个元素周围的圆中,并使这些元素也都可单击链接?我希望它看起来像下面的图片,但是我不知道如何实现这种效果。 这有可能吗? 问题答案: 是的,仅使用CSS很有可能而且非常简单。您只需要 清楚要与图像链接的角度即可 (我在末尾添加了一段代码,用于在 您悬停其中一个角度时显示它们)。 演示 您首先需要一个包装器。我将其直径设置为24em(width: 24em; hei
问题内容: 我正在创建一个应用程序,该应用程序在gridPane的每个单元格内随机显示(不同颜色的)圆圈。 我想要做的是创建一个“随机播放”按钮,以随机更改gridPane中每个圆的位置。但是,我一直遇到很多问题。 这是我到目前为止所拥有的。我的两个类(尚未添加XML文件): 控制器类 主班 问题答案: 这是一个示例,演示了如何在。如果添加了一个,你可以删除从。然后,您可以随机播放。最后,您可以将
我正在尝试制作重力的效果,但它看起来只是有越来越多的圆圈条纹,而不是单个圆圈向下移动。我不知道如何删除我已经绘制的圆圈。顺便说一句,代码中没有错误。
问题内容: 我正在JPanel中绘制两个形状(圆形),我需要用一条 线将它们连接起来。我这样做是通过简单地获得圆的中点并 相互连接来实现的。 问题在于,现在我需要制作单向线,该单向线 的末尾带有“箭头”,以指出线的前进方向。所以现在我不能 使用圆的中点,因为我需要从 边界到边界相互连接,因此“箭头”可以正确显示。 在我上一次尝试的结果是,没有任何好处: PS:在屏幕截图中,我并不是为了看到 直线的
问题内容: 我只想在鼠标单击后绘制圆圈。由于paintComponent方法调用了自身,因此首先绘制圆而无需单击。 问题答案: 您的代码存在一些问题: 你永远不会打电话 你只需要一个和 请注意,当您调整框架大小时,某些圆圈将消失,并且总体上以奇怪的方式表现。 我会将所有s 存储在用户单击的位置,然后在方法内部遍历该列表。这样您就可以通话,而圈子不会消失。 更改后的工作代码: