java 台球游戏中如何放置 15 个球

pool game in java how to put 15 balls

我想在java做台球游戏,我想在table的中心做15个面朝左的金字塔形球,但我不知道怎么做到。我必须找到 (x,y) 的正确坐标才能将球放在 table

的中心

我看到某人的代码,并找到了这个解决方案。

  public class cek {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        for(int i=0;i<16;i++) {
           int row = (int) Math.floor((Math.sqrt(1+8*i)/ 2)); // Using quadratic equation formula

            int x = (- (10 * (5- row)));
           System.out.println(i);
           System.out.println(Math.sqrt(1 + 8 * i));
           System.out.println(x);
        }
    }

}

结果:

0
1.0
-50
1
3.0
-40
2
4.123105625617661
-30
3
5.0
-30
4
5.744562646538029
-20
5
6.4031242374328485
-20
6
7.0
-20
7
7.54983443527075
-10
8
8.06225774829855
-10
9
8.54400374531753
-10
10
9.0
-10
11
9.433981132056603
0
12
9.848857801796104
0
13
10.246950765959598
0
14
10.63014581273465
0
15
11.0
0

first ball [0]: -50 

ball 1-15: 
-40,-30,-30,-20,-20,-20,-10,-10,-10,-10,0,0,0,0

如您所见,这可以为球 1-15 生成 x 坐标,例如第一行 1 个球,第二行 2 个球,第三行 3 个球,第四行 4 个球,第五行第 5 个球,但他怎么能想出那个解决方案和方程式? 即使在我看到解决方案之后,我认为我需要 1 天的时间才能弄清楚该代码 我想我永远也想不出那个解决方案 尤其 int row = (int) Math.floor((Math.sqrt(1+8*i)/ 2));

我正在尝试生成上面的代码,这就是我能想到的..

for(int i=0;i<5;i++){
               k=2*i+1-i;//10 20 30 40  50
               int x=-(n*10)+k*10;
               System.out.println(k);
               System.out.println(x);
               for(int r=1;r<k;r++) {
                  System.out.println(x);
              }

        }

但是如果我想用参数 1-15 调用球 class 并从另一个 class 中创建新球的对象,球 class 将设置 (x ,y) 构造函数中每 1-15 个球的坐标.. 这不会工作..

int row = (int) Math.floor((Math.sqrt(1+8*i)/ 2)); // Using quadratic equation formula

这项工作..

更新: 通过使用三角学来排列金字塔球 我设法做到了

     private double rowx(int rowNumber) {
            return rowNumber * (Math.sqrt(5) * r);
        }

     private void generateBalls(){
       balls=new ArrayList<Ball2>();
       int ballid=0;
       indexOfWhiteBall=0;
       if (balls.size()==0)
       {
          int x= Helper.BX + Helper.SW / 4 - r;
          int y = Helper.BY + Helper.SH / 2 - r;
          Ball2 balle=new Ball2(pinball,ballid,(Helper.BX + Helper.SW / 4 - r),Helper.BY + Helper.SH / 2 - r,r);
          balls.add(balle);
          balls.get(0).iswhiteball=true;
          ballid++;

       }
        for(int i=0;i<5;i++) {
          double y= rowx(i);
          for(double x:rowY(i)) {

              Ball2 balle=new Ball2(pinball,ballid,(Helper.BX + (2.5*Helper.SW)/4 ) +y,(Helper.BY + Helper.SH / 2) +x,r);
              balls.add(balle);
              ballid++;
              System.out.print(balle + " ");

          }
      }
    }
     private double[] rowY(int rownum) {

            switch(rownum) {
         case 0: return new double[] {0};
         case 1:return new double[] {-r,r};
         case 2:return new double[] {-2*r,0,2*r};
         case 3: return new double[] {-3*r, -r, r, 3*r};
         case 4: return new double[] {-4*r, -2*r, 0, 2*r, 4*r};
         case 5:return new double[] {Helper.BX + Helper.SW / 4 - r};
         default:throw new IllegalArgumentException("no more than 5");
            }
        }

如你所见,如果你 link 圆心,你会得到等边三角形。

考虑到上面那个小的。它的边长为 2*r,其高度 h 可以使用毕达哥拉斯定理计算:h^2 = r^2 + (2*r)^2。所以 h = sqrt(5) * r,所以这是第二行的 y 坐标。

此外,球在 x 轴上移动 r

所以如果第一个球的中心是(0, 0),那么第二行2个球的中心是(-r, sqrt(5)*r)(r, sqrt(5)*r)

您现在可以应用相同的原理并计算其他球的中心。

所以现在,请提供一些代码来实现它(通过编辑您的问题)。如果您表现出努力,我们可以帮助您进一步获得正确的代码。

实施

假设你有一个球class如下:

class Ball {
    private final int id;
    private final double x, y;

    public Ball(int id, double x, double y) {
        this.id = id;
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Ball{ id=" + id +"(x=" + x +", y=" + y + ") }";
    }
}

你可以在你的 Pool class 上有一个 setupBalls ,内容如下:(我添加了 printlns 以帮助理解它是如何进行的,所有的球都被添加到 balls 列表中)

public class Pool {

    private static double r = 20;

    private void setupBalls() {
        List<Ball> balls = new ArrayList<>();
        int ballId = 0;

        // for each row
        for(int rowNumber = 0; rowNumber<5; rowNumber++) {
            System.out.print("Row "+rowNumber + ": ");

            // get the Xs of the balls in that row, 
            // and create a ball for each
            double y = rowY(rowNumber);
            for(double x : rowXs(rowNumber)) {
                Ball ball = new Ball(ballId, x, y);
                balls.add(ball);
                System.out.print(ball + " ");
                ballId++;
            }

            System.out.println();
        }
    }

    // Returns the Y of a given row 
    private double rowY(int rowNumber) {
        return rowNumber * (Math.sqrt(5) * r);
    }

   // Returns the list of the Xs for the balls on the given row 
   private double[] rowXs(int rowNumber) {
        switch (rowNumber) {
            case 0: return new double[] {0};
            case 1: return new double[] {-r, r};
            case 2: return new double[] {-2*r, 0, 2*r};
            case 3: return new double[] {-3*r, -r, r, 3*r};
            case 4: return new double[] {-4*r, -2*r, 0, 2*r, 4*r};
            default: throw new IllegalArgumentException("no more than 5 rows");
        }
    }

}

然后像这样使用它:

public static void main(String[] args) {
    new Pool().setupBalls();
}