2013-02-25 3 views
0

Это назначение OPP класса 12.Нужна помощь в обнаружении ошибки столкновения игры

В настоящее время у меня есть проблема, что мяч иногда попадает в блоки вместо отражения.

Вот мой код:

как основные проверки, если мяч ударяет блок:

public void theBall(){ 
    //System.out.println(blocks.size()); 
    if(!started){ 
     balls.get(0).withPaddle(paddle.returnX()); 
    } 
    if(started){ 
     for(int i=0;i<balls.size();i++){ 
      if(balls.get(i).returnX()>=0 && balls.get(i).returnX()<=800 && balls.get(i).returnY()>=0){ 
       balls.get(i).move(); 
      } 
      if(balls.get(i).returnX()+balls.get(i).returnDx()<= 0){ 
       balls.get(i).collide(1);//collide with left wall 
      } 
      if(balls.get(i).returnX()+10+balls.get(i).returnDx() >= 800){ 
       balls.get(i).collide(2);//collide with right wall 
      } 
      if(balls.get(i).returnY()-balls.get(i).returnDy() <= 0){ 
       balls.get(i).collide(3);//collide with up wall 
      } 

      if(paddle.returnX() < balls.get(i).returnX() && balls.get(i).returnX()< paddle.returnX()+paddle.returnSize() && balls.get(i).returnY()-balls.get(i).returnDy() >= 545){//fix this && balls.get(i).returnY()-balls.get(i).returnDy() <= 560 
       balls.get(i).collidePaddle(balls.get(i).returnX()-paddle.returnX());//collide with paddle 
       //System.out.println(ball.returnDy()); 
      } 
      for(int j=0;j<blocks.size();j++){ 
       //blocks.get(j).getHit(balls.get(i)); 
       if(balls.get(i).returnX()+10+balls.get(i).returnDx() >= blocks.get(j).returnX() && balls.get(i).returnX()+10+balls.get(i).returnDx() <= blocks.get(j).returnX()+5 && balls.get(i).returnY() >= blocks.get(j).returnY() && balls.get(i).returnY() < blocks.get(j).returnY()+50){ 
        if(!blocks.get(j).returnHit()){ 
         balls.get(i).collide(2);//collide with right wall (block's left) 
         blocks.get(j).getHit(balls.get(i)); 
         System.out.println("boiboiboiboibo1"); 
        } 
       } 

       if(balls.get(i).returnX()+balls.get(i).returnDx() <= blocks.get(j).returnX()+50 && balls.get(i).returnX()+balls.get(i).returnDx() >= blocks.get(j).returnX()+45 && balls.get(i).returnY() >= blocks.get(j).returnY() && balls.get(i).returnY() < blocks.get(j).returnY()+50){ 
        if(!blocks.get(j).returnHit()){ 
         balls.get(i).collide(1);//collide with left wall (block's right) 
         blocks.get(j).getHit(balls.get(i)); 
         System.out.println("boiboiboiboibo2"); 
        } 
       } 

       if(balls.get(i).returnX() >= blocks.get(j).returnX() && balls.get(i).returnX() < blocks.get(j).returnX()+50 && balls.get(i).returnY()-balls.get(i).returnDy() <= blocks.get(j).returnY()+50 && balls.get(i).returnY()-balls.get(i).returnDy() >= blocks.get(j).returnY()+45){ 
        if(!blocks.get(j).returnHit()){ 
         balls.get(i).collide(3);//collide with up wall (block's bottom) 
         blocks.get(j).getHit(balls.get(i)); 
         System.out.println("boiboiboiboibo3"); 
        } 
       } 
       if(balls.get(i).returnX() >= blocks.get(j).returnX() && balls.get(i).returnX() < blocks.get(j).returnX()+50 && balls.get(i).returnY()+10-balls.get(i).returnDy() >= blocks.get(j).returnY() && balls.get(i).returnY()+10-balls.get(i).returnDy() <= blocks.get(j).returnY()+5){ 
        if(!blocks.get(j).returnHit()){ 
         balls.get(i).collide(4);//collide with down wall (block's top) 
         blocks.get(j).getHit(balls.get(i)); 
         System.out.println("boiboiboiboibo4"); 
        } 
       } 
      } 
      for(int j=0;j<specialBlocks.size();j++){ 
       if(balls.get(i).returnX()>=specialBlocks.get(j).returnX() && balls.get(i).returnX()<=specialBlocks.get(j).returnX()+100 && balls.get(i).returnY()>=specialBlocks.get(j).returnY() && balls.get(i).returnY()<=specialBlocks.get(j).returnY()+100){ 
        oneAndThreeBalls(i, j); 
        balls.get(i).changeType(j); 
       } 
      } 
     } 
    } 
} 

Как мяч отражает:

public void collide(int collideWith){ 
    if(collideWith==1){//collide with left wall 
     if(90<direction && direction<180){ 
      direction = 180-direction; 
     } 
     if(180<direction && direction<270){ 
      direction = 540-direction; 
     } 
    } 
    if(collideWith==2){//collide with right wall 
     if(0<direction && direction<90){ 
      direction = 180-direction; 
     } 
     if(270<direction && direction<360){ 
      direction = 540-direction; 
     } 
    } 
    if(collideWith==3){//collide with up wall 
     direction = 360-direction; 
    } 
    if(collideWith==4){//collide with down wall 
     direction = 360-direction; 

    } 
} 

Это очень ясно, что ошибка связана с двойной проверкой границ. Когда мяч находится в углу блока, это происходит. Но это единственный способ, с помощью которого я могу проверить, чтобы позиция мяча отражалась. Любые идеи о том, как я могу исправить эту ошибку? Спасибо.

+0

Попробуйте добавить 'continue;' в цикл for, как только вы обнаружите одно столкновение. Это предотвратит запуск нескольких коллизий. – Zyerah

ответ

1

Почему бы не сделать так:

1) После выполнения отскока, вы перестаете не проверяя столкновения для этого шара до следующего клеща игры. Таким образом, мяч может только подпрыгивать только один раз.

2) После столкновения и отскока от блока вы игнорируете столкновение между этим конкретным блоком и мячом до тех пор, пока шар не перекрывает блок. Таким образом, мяч не может ложно отскакивать от блока дважды при одном и том же ударе.

Btw, у вас есть много скопированного и вставленного кода с небольшими изменениями в количестве и т. Д. Если вы нашли способ переформулировать его с точки зрения метода, который вы используете, имея несколько разные параметры, ваш код станет намного опрятным, и основная симметрия проблемы также будет более очевидной.

+0

Спасибо, но даже первый удар может быть неправильным направлением столкновения. –

+0

@cook cook Только если мяч движется так быстро, что он может вставлять себя на полпути через блок за один тик. Если он не может, то, если вы нажмете на угол блока, неважно, в каком направлении вы отскакиваете - оба они одинаково важны, поскольку они отталкивают вас от блока. Для внутреннего угла вы будете отскакивать от другого, так что даже если вы встроены в него на один тик, это не имеет значения. – Patashu

+0

Я все еще не думаю, что это из-за двойного подпрыгивания. Я думаю, это из-за того, что у мяча есть два пути, и один будет неправильным. Например, если мяч идет в правый нижний угол со степенью 45. Если столкновение происходит с нижней стеной, это будет нормально, что отражается под углом 315. Но если столкновение происходит с правую стену. Тогда шар отразится с углом 135, который войдет в блок. –

Смежные вопросы