2013-09-28 4 views
1

У меня есть идеальное столкновение пикселей, но оно работает только с текстурой, вращающейся на 0 радианах. Вот мой код для определения с точностью до пиксела столкновительногоPixel-Perfect Collision With Texture Rotation

public static bool IntersectPixels(Texture2D sprite, Rectangle rectangleA, Color[] dataA, Texture2D sprite2, Rectangle rectangleB, Color[] dataB) 
{ 
    sprite.GetData<Color>(dataA); 
    sprite2.GetData<Color>(dataB); 

    // Find the bounds of the rectangle intersection 
    int top = Math.Max(rectangleA.Top, rectangleB.Top); 
    int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom); 
    int left = Math.Max(rectangleA.Left, rectangleB.Left); 
    int right = Math.Min(rectangleA.Right, rectangleB.Right); 

    // Check every point within the intersection bounds 
    for (int y = top; y < bottom; y++) 
    { 
     for (int x = left; x < right; x++) 
     { 
      // Get the color of both pixels at this point 
      Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width]; 
      Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width]; 

      // If both pixels are not completely transparent, 
      if (colorA.A != 0 && colorB.A != 0) 
      { 
       // then an intersection has been found 
       return true; 
      } 
     } 
    } 

    // No intersection found 
    return false; 
} 

У меня возникли проблемы с моим столкновения, когда он вращается. Как я могу проверить столкновение пикселей с повернутым спрайтом? Спасибо, любая помощь приветствуется.

+0

Вы знаете, что вы могли бы нарисовать повернутую текстуру на 'RenderTardet2D', приводите его к' Texture2D', а затем проверить, что против с вашим существующий метод. Просто знайте, что это, вероятно, уберет тонну процессора для этого. Я бы рекомендовал более эффективный, другой подход, но я не знаю. – user1306322

+0

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

ответ

0

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

Предположим, объект A имеет трансформацию transA, а объект B имеет transB. Затем вы будете перебирать все пиксели объекта A. Если пиксель не прозрачен, проверьте, какой пиксель объекта B находится в этом самом положении и проверьте, прозрачен ли этот пиксель.

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

Вы знаете позицию в пространстве объекта A. Во-первых, мы хотим преобразовать это локальное положение в глобальную позицию на экране. Это именно то, что делает transA. После этого мы хотим преобразовать глобальное местоположение в локальное место в пространстве объекта B. Это инверсия transB. Таким образом, мы должны преобразовать локальную позицию в со следующей матрицей:

var fromAToB = transA * Matrix.Invert(transB); 
//now iterate over each pixel of A 
for(int x = 0; x < ...; ++x) 
    for(int y = 0; y < ...; ++y) 
    { 
     //if the pixel is not transparent, then 
     //calculate the position in B 
     var posInA = new Vector2(x, y); 
     var posInB = Vector2.Transform(posInA, fromAToB); 
     //round posInB.X and posInB.Y to integer values 
     //check if the position is within the range of texture B 
     //check if the pixel is transparent 
    }