一种方法,一个接一个地检查球的四个边缘,看它是否与墙壁碰撞

2020年3月18日 7点热度 0条评论

在您的代码中添加一个方法,该方法一个接一个地检查球的四个边缘中的每一个,并检查该边缘是否与窗口的边缘碰撞。如果是这样,它应该相应地改变方向。例如,如果球向东北移动(↗),并且顶部边缘碰到了屏幕的顶部,它将改变方向向东南(↘),以便球看起来会从边缘反弹。 (请记住,如果球直接沿对角线方向进入一个角,则两个边缘可能会立即撞击,从而使其沿相反的对角线方向弹回。)

我不确定如何获得椭圆形的四个边缘。我已经完成了其他4个方向(上,下,左,右)的操作,但是不确定如何处理窗口的各个角落。

public void move()
  {
   //direction right
   if(dir == 1)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x + 1,y);        
            if(x>425)
            {
                dir = 2;                           
            }
   }           
   //direction left
   if(dir == 2)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x - 1,y);          
            if(x<0)
            {
                dir = 1;
            }
   }           
   //direction down
   if(dir == 3)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x,y + 1);               
            if(y>425)
            {
                dir = 4;
            }
   }       
   //direction up
   if(dir == 4)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x ,y - 1);         
            if(y<0)
            {
                dir = 3;
            }
   }           
   //direction bottom right corner
   if(dir == 5)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x + 1,y + 1);                           
   }           
   //direction upper right corner
   if(dir == 6)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x + 1,y - 1);
   }       

   //direction bottom left corner
   if(dir == 7)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x - 1,y + 1);
   }       
   //direction upper left corner
   if(dir == 8)
   {
       int x = ball.getX();
       int y = ball.getY();
       ball.setLocation(x - 1,y - 1);      
   }
}

最后,确保每次移动球时都调用此方法。这样,在将球沿其当前方向移动1个像素后,您可以运行该方法以检查球是否击中了任何边缘并更改方向。此时,您的球应该随着屏幕跳动而移动。

解决方案如下:

不要为椭圆形考虑太多。就此任务而言,它也可能是一个盒子。与边的情况相比,拐角的情况与边缘的情况之间的唯一区别是,您需要区分以下四个结果:

您碰到了水平和垂直的墙:更改为与对角线运动相反的方向。
您碰到了水平墙:保持垂直方向并将水平方向切换为相反方向。
您碰到了垂直墙:保持水平方向并将垂直方向切换为相反方向。
您根本没有碰壁:什么都不做。

此外,这些说明特别建议您将运动逻辑与更改方向的逻辑分开。在您的初始方法中,您同时执行了两项操作。

在我的示例中,我介绍了一种方法changeDirection(),该方法仅检查是否击中了任何边界,然后使您转身,但没有实际移动。您仍然需要实现move()并加以注意,但是您可以仅调用此方法并假定随后球朝着正确的方向前进。

另外,一旦引入命名常量来引用指令,代码也将变得更易于理解:

  private static final int RIGHT = 1;
  private static final int LEFT = 2;
  private static final int DOWN = 3;
  private static final int UP = 4;
  private static final int DOWN_RIGHT = 5;
  private static final int UP_RIGHT = 6;
  private static final int DOWN_LEFT = 7;
  private static final int UP_LEFT = 8;

  private static final int WIDTH = 425;
  private static final int HEIGHT = 425;

  public void changeDirection()
  {
    int x = ball.getX();
    int y = ball.getY();

    switch ( dir )
    {
      case RIGHT:
        if ( x >= WIDTH )
        {
          dir = LEFT;
        }
        break;
      case LEFT:
        if ( x <= 0 )
        {
          dir = RIGHT;
        }
        break;
      case DOWN:
        if ( y >= HEIGHT )
        {
          dir = UP;
        }
        break;
      case UP:
        if ( y <= 0 )
        {
          dir = DOWN;
        }
        break;
      case DOWN_RIGHT:
        if ( y >= HEIGHT )
        {
          if ( x >= WIDTH )
          {
            dir = UP_LEFT;
          }
          else
          {
            dir = UP_RIGHT;
          }
        }
        else if ( x >= WIDTH )
        {
          dir = DOWN_LEFT;
        }
        break;
      case UP_RIGHT:
        if ( y <= 0 )
        {
          if ( x >= WIDTH )
          {
            dir = DOWN_LEFT;
          }
          else
          {
            dir = DOWN_RIGHT;
          }
        }
        else if ( x >= WIDTH )
        {
          dir = UP_LEFT;
        }
        break;
      case DOWN_LEFT:
        if ( y >= HEIGHT )
        {
          if ( x <= 0 )
          {
            dir = UP_RIGHT;
          }
          else
          {
            dir = UP_LEFT;
          }
        }
        else if ( x <= 0 )
        {
          dir = DOWN_RIGHT;
        }
        break;
      case UP_LEFT:
        if ( y <= 0 )
        {
          if ( x <= 0 )
          {
            dir = DOWN_RIGHT;
          }
          else
          {
            dir = UP_LEFT;
          }
        }
        else if ( x <= 0 )
        {
          dir = UP_RIGHT;
        }
        break;
    }
  }