Вращение 2D BoundingRectangle в XNA 4.0

У меня возникли проблемы с определением того, что мне нужно сделать, чтобы иметь 2D BoundingRectangle для объекта спрайта в моей игре, вращая и обновляя положение в зависимости от того, каким образом пользователь хочет, чтобы спрайт перемещался.

Я рисую спрайт с его вращением и значениями масштаба следующим образом:

spriteBatch.Draw(texture, position, null, Color.White, rotation, origin, scale, SpriteEffects.None, 1f);

Моя текущая настройка для получения BoundingRectangle:

public Rectangle BoundingRectangle
{
    get { return new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height); }
}

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

Буду признателен за подсказки, что мне нужно сделать.


person diggersworld    schedule 23.09.2012    source источник
comment
Вы хотите, чтобы ваш прямоугольник тоже вращался или оставался ограничивающим прямоугольником, выровненным по осям x/y? (AABB)   -  person Joe Shanahan    schedule 23.09.2012
comment
Мне нужна ограничивающая рамка для обнаружения столкновений, основанная на области, покрытой повернутым спрайтом.   -  person diggersworld    schedule 23.09.2012


Ответы (1)


Класс Rectangle не содержит информации о повороте, поэтому вам нужна некоторая структура для ее хранения.

Хорошим выбором было бы вернуть список из четырех точек, основанных на возвращаемом прямоугольнике и примененном к нему вращении.

Вы можете применить поворот к набору точек, используя класс Matrix. вот так:

var m = Matrix.CreateRotationZ(angle);
Vector3 rotatedVector = Vector3.Transform(vector, m);

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

var rotation = Matrix.CreateRotationZ(angle);
var translateTo = Matrix.CreateTranslation(vector);
var translateBack = Matrix.CreateTranslation(-vector);
var comnbined = translateTo * rotation * translateBack;
Vector3 rotatedVector = Vector3.Transform(vectorToRotate, combined);

Обязательно ознакомьтесь со всеми другими преобразованиями, которые можно выполнить с помощью матрицы. Матрицы являются ключевыми элементами в разработке игр/графики.

person zeebonk    schedule 23.09.2012
comment
Я пытаюсь реализовать ваше предложение, я загрузил класс Matrix, но, похоже, он не распознает методы RotateAt или TransformPoints. - person diggersworld; 23.09.2012
comment
@diggersworld Плохо, в моем предыдущем примере использовался класс Matrix в пространстве имен Drawing2D, я изменил пример, чтобы использовать матричную структуру по умолчанию в XNA. - person zeebonk; 23.09.2012
comment
Не волнуйтесь. Я понял это сейчас, просто интересно, поскольку моя игра 2D, должен ли я использовать Vector2.Transform, а не Vector3? - person diggersworld; 23.09.2012
comment
Да, используйте Vector2, когда вы делаете 2D-материал. Но даже если бы вы использовали Vector3, результаты были бы такими же, дополнительное измерение просто проигнорировалось бы. - person zeebonk; 23.09.2012
comment
Хммм... Я проверяю это на спрайте 20x20, повернутом относительно центральной точки 10,10. Когда я поворачиваю его, он возвращается с отрицательными результатами, когда они должны быть положительными, то есть для поворотов в верхнем левом углу я ожидал бы 0,0, 0,40, 40,40, 40,0 при движении против часовой стрелки. Вместо этого они отрицательные. - person diggersworld; 23.09.2012
comment
Я перешел на этот translateTo * rotation * translateBack, который теперь дает положительные значения, которые я ожидал увидеть. - person diggersworld; 23.09.2012