【问题标题】:Bouncing a ball within a circle在一个圆圈内反弹一个球
【发布时间】:2023-03-29 22:37:01
【问题描述】:

我有一个 Pong-360 游戏,在该游戏中,弧形桨会偏转应该保持在圆形边界内的球。如果球在到达边界时没有遇到桨,则继续出界,最后击球的球员得分。我遇到的问题是在用桨击球时将球以正确的方向返回。如果球接触到球拍的某一半,它应该朝那个方向弹跳,但无论如何都应该回到边界的另一侧,而不会再次击中边界的同一侧。

现在我已经通过将边界分成 16 个切片并在一个范围内给球一个随机角度来完成弹跳,这个范围取决于它在撞击时所处的切片。即使这也不能按预期工作,因为我的数学不正确,但需要以任何方式重做。我不知道如何获得一个角度,以确保球无论在哪里被击中,都会返回到边界的另一半。我已经多次尝试从诸如球的行进方向、边界内的当前位置以及接触的桨的位置等变量中获取角度,但到目前为止我都经历了失败。目前改变小球方向的代码如下:

    public void bounce(){

        boolean changeAngle = false;

        if( bluePaddle.intersects( ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter() ) ){

            lastHit = 1;
            changeAngle = true;
        }
        else if( redPaddle.intersects( ball.getX(), ball.getY(), ball.getDiameter(), ball.getDiameter() ) ){

            lastHit = 2;
            changeAngle = true;
        }

        if ( changeAngle ){

            //  Right side of boundary
            if ( ball.getX() > center_x ) {

                //  Quadrant 4
                if ( ball.getY() > center_y ){

                    //  Slice 13
                    if ( ball.getY() - center_y > Math.sin(3 * Math.PI / 8) ){                      
                        angle = (double) ( randNum.nextInt(90) + 90 );
                    }
                    //  Code for other slices omitted
                }//end Quadrant 4
                // Code for other quadrants omitted
            }//end right side of boundary

            //  Code for Left side of boundary omitted

            ball.setDx( (int) (speed * Math.cos(Math.toRadians(angle))) );
            ball.setDy( (int) (speed * Math.sin(Math.toRadians(angle))) );
        }//end if (changeAngle)

        bouncing = false;       
    }//end bounce method

正如您所看到的,就像现在一样,角度只是在我认为对每个切片都有利的范围内随机生成。强调一下,我主要需要数学方面的帮助,用 Java 实现它是次要的。编译和运行的完整代码(所有 .java 和 .class 文件)可以在这里找到:https://github.com/pideltajah/Pong360/tree/master/Pong360

主要方法在 Pong.java 文件中。

任何帮助将不胜感激。

【问题讨论】:

  • 您画的箭头似乎不可行。请注意,如果桨在最右边的位置,该偏转会导致它撞到自己的一侧。更重要的是,似乎不可能以非常明智的方式解决问题。例如,如果红色桨在顶部,击中桨的右侧也会将球撞到红色自己的墙上。
  • 你可以通过将向量映射到它来强制它击中中心线,但你可能希望在策略中加入反弹
  • 另外,也许您可​​以将圆圈分成四等份,每个玩家将控制两个相距 180 度的桨(如果在正方形上,则控制两个桨)。如果这是一个愚蠢的想法,我的借口是,已经晚了。
  • @dwn 箭头并不是要准确表示所需结果,而是要说明我试图传达的概念。至于桨在顶部,实际上有两种游戏模式,一种允许双方玩家绕圈一直移动,另一种限制他们的运动在边界的左侧/右侧。我正在寻求帮助,让球相对于击球位置向边界的另一侧移动,并且(在左/右模式下)即使在最顶部或最底部被击中,也被引导到其他球员的一侧。
  • 关于您认为似乎无法以明智的方式解决问题的评论,我承认我可能没有以正确的方式看待问题,并愿意接受有关更好定义的建议只要可以达到预期的结果,就可以解决问题或解决方案的不同设置。感谢您的意见。

标签: java math geometry angle bounce


【解决方案1】:

首先,找到它击中桨的位置。在红色桨的情况下您可以这样做(蓝色桨将相似,但您可能需要交换 ang0 和 ang1):

桨的边缘由圆上的两个角度定义,ang0 和 ang1,其中 ang0 是下边缘,而 ang1 是上边缘

假设圆心是点 (0, 0),球在点 pBall = (xBall, yBall)

球会在 [ang0 .. ang1] 范围内的某个角度 ballAng = atan2(yBall, xBall)

现在将其在桨叶上的角度位置转换为 [0 .. 1] 之间的参数。 您可以将其定义为

u = (ballAng - ang0) / (ang1 - ang0);

现在您想将其映射到中心线,如下所示:

说圆中心线的底部位置是点p0,中心线的顶部是点p1

现在定义与中心线的交点为

p = p0 + u * (p1 - p0)

作为球的速度向量,这需要是归一化的差分向量

velBall = normalize(p - pBall)

希望这是有道理的

[编辑:进行更正]

【讨论】:

  • 感谢您抽出宝贵时间回复。我将尝试实施您的解决方案并在之后进行进一步的更新。再次感谢。
  • 如果你真的想变得奇怪,你可以把它当作从乒乓矩形到你的乒乓圈的直接映射,但是球会随着它的移动而弯曲。
  • 关于它的最后一个概念:你可以让弹跳正常发生,但在中心线上添加一种磁力
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-10
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多