XNA 4.0: 2D-камера Y и X движутся в неверном направлении - PullRequest
1 голос
/ 19 августа 2011

Итак, я знаю, что есть несколько вопросов / ответов относительно создания 2D-камеры для XNA, однако люди, похоже, просто рады опубликовать свой код без объяснения причин.Я ищу больше объяснений того, что я делаю неправильно.

Прежде всего, я понимаю весь Мир -> Вид -> Проекция -> Преобразование экрана.

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

Мне трудно реализовать эту функцию, потому что значение Y в окне просмотра инвертировано.

//In Camera Class
private void UpdateViewTransform()
{
//My thinking here was that I would create a projection matrix to center the camera and then flip the Y axis appropriately
     Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0)) * 
                   Matrix.CreateScale(new Vector3(1f, -1f, 1f));

//Here is the camera Matrix. I have to give the Inverse of this matrix to the Spritebatch I believe since I want to go from World Coordinates to Camera Coordinates
     _viewMatrix = Matrix.CreateRotationZ(_rotation) *
                  Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) *
                  Matrix.CreateTranslation(_position.X, _position.Y, 0.0f);

     _viewMatrix = proj * _viewMatrix;

}

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

РЕДАКТИРОВАТЬ

Это как преобразование, кажется, работает, однако я не уверен, почему.Может, кто-нибудь объяснит мне это в понимании:

Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));
    _viewMatrix = Matrix.CreateRotationZ(_rotation) *
                 Matrix.CreateScale(new Vector3(_zoom, _zoom, 1.0f)) *
                 Matrix.CreateTranslation(-1 * _position.X, _position.Y, 0.0f);

    _viewMatrix = proj * _viewMatrix;

Я уже построил raytracer, поэтому я должен понять ваше понимание, моя путаница заключается в том, что он 2D и SpriteBatch скрывает то, что он делаетот меня.Спасибо!Фарид

Ответы [ 3 ]

2 голосов
/ 19 августа 2011

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

По умолчанию SpriteBatch использует RasterizerState.CullCounterClockwise. Когда вы звоните SpriteBatch.Begin, вам нужно вместо этого ввести RasterizerState.CullClockwise.

И, конечно же, Begin - это место, где вы переходите в матрицу преобразования.

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

1 голос
/ 02 марта 2012

Я много боролся с XNA, пытаясь заставить его быть похожим на другие движки, с которыми я работал раньше ... мое мнение, оно того не стоит ... Просто следуйте стандартам XNA и используйте вспомогательные методы Matrix для создания ваших матриц перспективы / видового экрана.

0 голосов
/ 20 августа 2011

Итак, просто подумав логически , я смог вывести правильное преобразование.Здесь я опишу шаги, если кто-то захочет получить настоящую разбивку:

Важно понять, что такое Преобразование камеры или Просмотр трансформации .Трансформация вида - это обычно то, что необходимо для перехода от координат относительно к вашей камере в координаты мирового пространства.Тогда обратное преобразование вида создаст мировую координату относительно вашей камеры!

Создание матрицы вида

  1. Примените вращение камеры.Мы делаем это по оси Z только потому, что это для 2D-камеры.
  2. Примените преобразование камеры.Это имеет смысл, так как мы хотим, чтобы мировая координата была суммой координаты камеры и объекта относительно камеры.
    1. Вы можете заметить, что я умножил Y-компонент на -1.Это связано с тем, что увеличение положения Y камеры соответствует движению вверх, поскольку значение Y на экране указывает вниз.
  3. Примените зум камеры

Теперь обратное значениеМатрица будет выполнять World Coordinate -> View Cordinates.

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

Matrix proj = Matrix.CreateTranslation(new Vector3(_viewport.Width * 0.5f, _viewport.Height * 0.5f, 0));

        _viewMatrix = Matrix.CreateRotationZ(moveComponent.Rotation) *
                    Matrix.CreateTranslation(moveComponent.Position.X, -1 * moveComponent.Position.Y, 0.0f) *
                     Matrix.CreateScale(new Vector3(zoomComponent.Zoom, zoomComponent.Zoom, 1.0f));

        _viewMatrix = proj * Matrix.Invert(_viewMatrix);
...