2011-10-16 2 views
0

Можно создать дубликат:
Java 2D Collision?Java 2D Столкновение

Эй, ребята, у меня есть еще один пост по поводу этого, который только что ушел мертв, так что я думал, что я хотел бы попробовать получить некоторые свежие ответы относительно этого ,

Я пытаюсь заставить мое обнаружение столкновения работать. Мое обнаружение столкновений отлично работает, когда я прихожу к моим блокам карт и прекрасно, когда я только держусь или опускаю и ударяю блок сверху или снизу. Но когда я держусь вверх или вниз, а также направо или налево и ударяю блок сверху или снизу, он будет смещаться в смешных направлениях.

Небольшое видео со мной демонстрирует (извините, если не ясно): http://www.youtube.com/watch?v=6ILccRtw8ME Надеюсь, это поможет.

Если вы не смотрите видео здесь картина изображения карты я буду использовать:

enter image description here

Вот мой текущий код столкновения:

public void checkCollision() { 
    Rectangle player_rectangle = new Rectangle(player.getX(),player.getY(),32,32); 

    for(Wall wall : walls) { 

     Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 32,32); 

     if (player_rectangle.intersects(wall_rectangle)) { 
      Rectangle intersection = (Rectangle) player_rectangle.createIntersection(wall_rectangle); 


      if (player.xspeed < 0 && player.x >= intersection.x) { 
       player.x += intersection.getWidth(); 
      } else { 

      if (player.xspeed > 0 && player.x <= intersection.x) { 
       player.x -= intersection.getWidth(); 
      } else { 

      if (player.yspeed < 0 && player.y >= intersection.y) { 
       player.y += intersection.getHeight(); 
      }else { 

      if (player.yspeed > 0 && player.y <= intersection.y) { 
       player.y -= intersection.getHeight(); 
      } 
      } 
      } 
      } 



      Print(Integer.toString(intersection.width) + ", " + Integer.toString(intersection.height)); 

     } 

    } 

} 

Вся помощь будет оцените, спасибо.

+0

не так ли один и тот же вопрос, который вы просили на своем [старшем сообщение] (http://stackoverflow.com/questions/7763244/java-2d-collision)? Если «да», пожалуйста, отредактируйте и/или запустите награду за свой последний вопрос и не отправляйте ее. если нет, пожалуйста, объясните проблему с более подробной информацией. – amit

+0

+1 для смешного видео. блок деформирования ftw. –

+0

@ThomasJungblut Что значит смешно? : L –

ответ

3

Это моя первая попытка ответить на вопрос о StackOverflow, поэтому, пожалуйста, будьте терпеливы со мной. Я попытаюсь структурировать этот ответ, сначала диагностируя проблему, найдя симптомы, которые могут вызвать вашу проблему, и, наконец, представить решение и посмотреть, работает ли оно с вами.

Прежде всего, позвольте мне отформатировать код с правильным уровнем отступов, чтобы у нас было более четкое представление о том, что происходит.

public void checkCollision() { 
    Rectangle player_rectangle = new Rectangle(player.getX(), 
      player.getY(), 32, 32); 

    for (Wall wall : walls) { 

     Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 
       32, 32); 

     if (player_rectangle.intersects(wall_rectangle)) { 
      Rectangle intersection = (Rectangle) player_rectangle 
        .createIntersection(wall_rectangle); 

      if (player.xspeed < 0 && player.x >= intersection.x) { 
       player.x += intersection.getWidth(); 
      } else { 

       if (player.xspeed > 0 && player.x <= intersection.x) { 
        player.x -= intersection.getWidth(); 
       } else { 

        if (player.yspeed < 0 && player.y >= intersection.y) { 
         player.y += intersection.getHeight(); 
        } else { 

         if (player.yspeed > 0 && player.y <= intersection.y) { 
          player.y -= intersection.getHeight(); 
         } 
        } 
       } 
      } 

      Print(Integer.toString(intersection.width) + ", " 
        + Integer.toString(intersection.height)); 

     } 

    } 

} 

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

if (condition){ 
    // do something 
    else{ 
     if(anotherCondition){ 
      // do something 
      else{ 
       //etc 
      } 
     } 
    } 
} 

То, что вы должны делать это с помощью нескольких условных операторов в строке, как это:

if (condition){ 
    //do something 
} 

if (anotherCondition){ 
    //do something else 
} 

//etc 

Это происходит потому, что если у вас есть два случая, такие, как вы находясь в нижнем левом углу, вам нужно будет выполнить условия для пересечения влево, а также пересечения с нижней. Однако это не имеет значения для вашего примера, поскольку вы проходите каждую стену отдельно.

Так почему же это важно?

Ну, мне кажется, что если первое условие не выполняется, то все остальные условия не будут выполняться. Если player.xspeed < 0 && player.x >= intersection.x возвращает true, то даже если остальные 3 вложенные в него выражения возвращают true, они не будут выполнены, потому что он полагается на этот первый оператор: false. Поэтому, когда вы переходите к краю, где два или более случаев будут истинными, вы получаете только один из них.

Поэтому предложил мое решение, основанное на все вышесказанное следующим образом:

public void checkCollision() { 
     Rectangle player_rectangle = new Rectangle(player.getX(), 
       player.getY(), 32, 32); 

     for (Wall wall : walls) { 

      Rectangle wall_rectangle = new Rectangle(wall.getX(), wall.getY(), 
        32, 32); 

      if (player_rectangle.intersects(wall_rectangle)) { 
       Rectangle intersection = (Rectangle) player_rectangle 
         .createIntersection(wall_rectangle); 

       if (player.xspeed < 0 && player.x >= intersection.x) { 
        player.x += intersection.getWidth(); 
       } 

       if (player.xspeed > 0 && player.x <= intersection.x) { 
        player.x -= intersection.getWidth(); 
       } 

       if (player.yspeed < 0 && player.y >= intersection.y) { 
        player.y += intersection.getHeight(); 
       } 

       if (player.yspeed > 0 && player.y <= intersection.y) { 
        player.y -= intersection.getHeight(); 
       } 

       Print(Integer.toString(intersection.width) + ", " 
         + Integer.toString(intersection.height)); 

      } 

     } 

    } 

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

+0

Спасибо, что ответили, к сожалению, теперь он не работает, используя этот код: L Он скачет случайно, даже когда он идет справа или слева и удерживает вверх/вниз –

+0

Интересно. Возможно, мне нужно будет отредактировать мой ответ в ближайшее время. Нужно думать об этом дальше. – CodingMo

0

Я предлагаю написать кучу модульных тестов для всех разных состояний, которые вы можете себе представить, с которыми нужно иметь дело checkCollision. Таким образом, вы будете:

  • Легко выяснить, какие конкретные входы вызывают блок прыгать (потому что модульные тесты короткие и хорошо содержатся)
  • Убедитесь, что эта функция не будет нарушена будущих изменений (потому что модульные тесты запускаются с каждым билдом)

тест единица выборки для этого будет выглядеть примерно так:

public class CollisionTests { 

    @Test 
    public void hitFromLeftHeadOn() throws Exception { 
     List<Wall> walls = Lists.newArrayList(
      new Wall(...), // south wall 
      new Wall(...), // east wall 
      // etc. 
     ); 
     Player player = new Player(...); 

     // Set player to collide with the east wall head on 
     player.setX(...); 
     player.setY(...); 
     player.setXSpeed(...); 
     player.setYSpeed(...); 

     checkCollision(); 

     // Now check if the checkCollision method worked properly 
     assertEquals("Player's x coordinate should be set to ...", ..., player.getX()); 
     assertEquals("Player's y coordinate should be set to ...", ..., player.getY()); 
    } 

Как только вы написали один тест, его легко добавить. Вы можете создавать различные вспомогательные методы для создания стен, проигрывателя и т. Д., Чтобы каждый тестовый пример сжимался до нескольких строк.

Here's a tutorial on unit testing.

В качестве дополнительного бонуса, если вы пишете тест блок вы также написали SSCCE :)

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