2010-10-24 1 views
2

Хотелось бы узнать, в каком направлении игрок попадает на рельефную плиту (просто вверх/вниз, влево/вправо). Все, что я нахожу, либо слишком простое, либо гораздо более сложное и, по-видимому, слишком много для того, что мне нужно, например, с AABB (при условии, что трудно сказать, у моего мозга проблемы с перевариванием, что составляет очень длинные уравнения). То, что у меня есть до сих пор, является результатом большей части сегодняшнего чтения и экспериментов:2D Collision Detection между квадратами, простой, но более конкретный, чем логический + иммунный к большим пространственным прыжкам.

public int move(double toX, double toY) { 

    int col = COLLISION_NONE; //these are bit flags, in case I collide with a block to my right as well as below me 

    double nextX = mX+(toX*main.getDelta()); //delta regulates speed 
    double nextY = mY+(toY*main.getDelta()); 

    if(mTerrainCollision){ 

     int w = GameView.GameLoop.TILE_WIDTH; 
     int h = GameView.GameLoop.TILE_HEIGHT; 

     for(int i = -2; i <= 2; i++) //broad tile picking will be optimized later, better trace around players path 
      for(int j = -2; j <= 2; j++) { 
       GameTerrain.Block block = main.mTerrain.get(((int)Math.round(mX)/w)+i,((int)Math.round(mY)/h)+j); 
       if(block.type != GameTerrain.BLOCK_TYPE_NONE) { 

        if(nextX+w >= block.x() && mX+w <= block.x()){ //COLLISION ON THE RIGHT? 
         if(mY+h > block.y() && mY < block.y()+h) { //<THIS is a problem line, see below 
          nextX = block.x() - w; 
          xMomentum = 0; 

          col |= COLLISION_RIGHT; 
         } 
        } 

        else if(nextX < block.x()+w && mX >= block.x()+w){ //COLLISION ON THE LEFT? 
         if(mY+h > block.y() && mY < block.y()+h) { //same as above, make sure were on the same plane 
          nextX = block.x() + w; 
          xMomentum = 0; 

          col |= COLLISION_LEFT; 
         } 
        } 


        if(nextY+h >= block.y() && mY+h <= block.y()){ //COLLISION ON THE BOTTOM? 
         if(mX+w > block.x() && mX < block.x()+w) { //make sure were on the same plane 
          nextY = block.y() - h; 
          yMomentum = 0; 

          col |= COLLISION_DOWN; 
         } 
        } 

        else if(nextY < block.y()+h && mY >= block.y()+h){ //COLLISION ON THE TOP? 
         if(mX+w > block.x() && mX < block.x()+w) { //make sure were on the same plane 
          nextY = block.y() + h; 
          yMomentum = 0; 

          col |= COLLISION_UP; 
         } 
        } 
       } 
      } 
    } 

    mX = nextX; 
    mY = nextY; 

    return col; 

} 

Это работает ... в основном. Игрок не будет проходить через блоки даже после долгих снов, создавая стремительный рост дельты. Само обнаружение столкновения работает, если предыдущая позиция игрока (mX/mY) не находится на той же плоскости, что и блок, который мы проверяем (см. Прокомментированную строку с «ЭТО ...»). Скажем, мы абсолютно диагональны к блоку и движемся прямо к нему, игрок будет молчать прямо. Некоторое время я почесывал голову, пытаясь понять, как решить этот последний вопрос, желательно без серьезного ремонта всего, но если это должно было прийти к этому, хорошо! Меня интересуют только простые данные о столкновении для таких вещей, как «Я коснулся пола в этом кадре? Хорошо, я могу прыгать», «Я касаюсь стены прямо сейчас? Хорошо, я могу прыгать в стену, но нет, если бы я также коснулся пола »и т.д.

ответ

0

Grow AABB стены путем размером AABB объекта (удерживая центр AABB в стенах фиксированный), построить отрезок от объекта перед тем и после позиций (использовать центр AABB объекта), затем выполните команду segment-AABB intersection test.