Я делаю тестовую игру, где хочу, чтобы уровень постоянно прокручивался. Чтобы создать этот эффект, я установил класс камеры, который просто хранит позицию вектора и направление перечисления. Он также содержит публичный метод «перемещения», который просто меняет позицию с фиксированной ставкой. Затем я использую эту позицию при циклическом просмотре массива плиток при рисовании. Это все отлично работает.
Однако мне сказали, что я должен использовать матрицу Transform для перемещения камеры, и что я должен предоставить это при запуске spritebatch. Я немного запутался.) Как это работает? как будто я даю его только тогда, когда начинается spritebatch, как он знает, что нужно продолжать менять позицию? б.) Почему так же, как и раньше, мне все еще нужно положение камеры, когда я перебираю плитки?
В настоящий момент я не могу заставить его работать, но это не удивительно, так как я не совсем понимаю, как это должно работать. В настоящее время в моей попытке (код для подражания) изменяемые плитки изменяются, что означает, что положение камер меняется, но положение области просмотра остается неизменным (т.е. в начале координат камеры). Я был бы очень признателен за совет / руководство о том, как его следует использовать?
камера:
class Camera {
// The position of the camera.
public Vector2 Position {
get { return mCameraPosition; }
set { mCameraPosition = value; }
}
Vector2 mCameraPosition;
public Vector2 Origin { get; set; }
public float Zoom { get; set; }
public float Rotation { get; set; }
public ScrollDirection Direction { get; set; }
private Vector2 mScrollSpeed = new Vector2(20, 18);
public Camera() {
Position = Vector2.Zero;
Origin = Vector2.Zero;
Zoom = 1;
Rotation = 0;
}
public Matrix GetTransform() {
return Matrix.CreateTranslation(new Vector3(mCameraPosition, 0.0f)) *
Matrix.CreateRotationZ(Rotation) *
Matrix.CreateScale(Zoom, Zoom, 1.0f) *
Matrix.CreateTranslation(new Vector3(Origin, 0.0f));
}
public void MoveCamera(Level level) {
if (Direction == ScrollDirection.Up)
{
mCameraPosition.Y = MathHelper.Clamp(mCameraPosition.Y - mScrollSpeed.Y, 0, (level.Height * Tile.Height - level.mViewport.Height));
}
}
Уровень:
public void Update(GameTime gameTime, TouchCollection touchState) {
Camera.MoveCamera(this);
}
public void Draw(SpriteBatch spriteBatch) {
//spriteBatch.Begin();
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default, RasterizerState.CullCounterClockwise, null, mCamera.GetTransform());
DrawTiles(spriteBatch);
spriteBatch.End();
}
Игра - просто вызывает ничью в пределах уровня:
protected override void Draw(GameTime gameTime) {
mGraphics.GraphicsDevice.Clear(Color.Black);
//mSpriteBatch.Begin();
// Draw the level.
mLevel.Draw(mSpriteBatch);
//mSpriteBatch.End();
base.Draw(gameTime);
}
================================================== =============================== РЕДАКТИРОВАТЬ:
Во-первых, спасибо вам craftworkgames за вашу помощь.
Я играл с предложением. Когда я рисовал все фишки, французы увеличивались до 15 с 30 - вероятно, потому что уровни довольно большие.
Итак, что я сделал, это применил матрицу и переместился в обновлении (как предложено), но при рисовании я использую положение камер для циклического прохода по тайлам (т. Е. Начинаю счетчик слева и заканчиваю справа). Это все работает хорошо, и я доволен этим :-)
Моя новая проблема заключается в плеере. Очевидно, что теперь я перемещаю камеру, а не уровень, игрок остается позади, поскольку его позиция остается неизменной. Я подумал о двух решениях этой проблемы, во-первых, просто учитывать положение камеры при рисовании игрока. Т.е. в функции ничьей просто добавьте положение камеры в положение игрока. Второй - запустить новый спрайт для игрока, у которого нет трансформации. то есть завершить спрайт-пакет после рисования тайлов, а затем начать новый при рисовании игрока. Я знаю, что оба будут работать, но я не могу придумать, какие из них были бы лучше с точки зрения производительности / хорошего кодирования? Я не уверен, что влияет на производительность при запуске пакета дважды?
Ответы:
Преобразование матрицы камеры легко
Создать базовую камеру легко. Ниже вы познакомитесь с основами. Перемещение, вращение и масштабирование. Перемещение каждого 2-го спрайта не является большой проблемой, но если вы учитываете масштабирование или вращение, то действительно трудно применить его к каждому спрайту в отдельности.
Это позволяет легко конвертировать определения системы координат.
Переходить с экрана в мировое пространство просто. Это обычно используется для определения местоположения мыши в мире для выбора объектов.
Чтобы перейти от мира к экранному пространству, просто сделайте обратное.
Нет смысла использовать матрицу, за исключением небольшого обучения.
Легко получить видимую область
Вы можете просто преобразовать углы камер и получить их расположение в мировом пространстве. Минимальное максимальное значение x, y и вы можете получить прямоугольник вокруг видимого пространства. Очень полезно для отбраковки и оптимизации вызовов.
источник
Применение матрицы к вашему SpriteBatch преобразует весь вызов отрисовки одновременно. Это означает, что вам вообще не нужно использовать камеру в методе DrawTiles.
Это может стать намного проще, например:
Так что смысл использования матрицы в том, чтобы вам не приходилось об этом думать. Просто рисуйте вещи и перемещайте камеру самостоятельно.
Кроме того, ваш метод MoveCamera выглядит немного странно. Очень необычно иметь класс камеры, который принимает уровень как зависимость. Более типичная реализация будет выглядеть так:
Тогда в вашем методе обновления вы можете сделать что-то вроде этого:
В целом, я предлагаю сделать это простым. Получите это, работая самым простым способом, и основывайтесь на этом. Старайтесь не писать сильно оптимизированный код, пока не начнете работать с основами. Вы можете обнаружить, что рендеринг каждой плитки каждого кадра не так уж и плох.
РЕДАКТИРОВАТЬ: Для второй части вопроса.
Хотя это правда, что вы хотите сохранить низкий счетчик партий, наличие 2 или 3 не должно быть проблемой вообще. Так что если у вас есть веская причина для создания второй партии спрайтов, просто сделайте это.
Тем не менее, в этом случае, вероятно, нет веской причины использовать вторую партию спрайтов. Скорее всего, вы хотите нарисовать своего игрока точно так же, как вы рисуете плитки в том же пакете спрайтов с применением преобразования камеры.
Немного трудно понять, почему ваш игрок отстает, не взглянув на какой-либо код, но есть основания полагать, что если вы рисуете своего игрока в той же позиции, что и тайл, он / она появится в той же позиции с той же спрайт пакетный.
Например, если вы хотите, чтобы игрок появлялся на плитке 10, 10, вы можете сделать это:
Попытайтесь прийти в голову, думая о том, чтобы рисовать вещи там, где они есть, и камера буквально перемещает всю «сцену» в поле зрения. Это то, что делает ваше матричное преобразование.
источник