Перемещение спрайта в XNA / C # с использованием векторов

9

В настоящее время я изучаю разработку игр для XNA на языке C #.

У меня есть два класса: основной обработчик игры и класс «спрайт». Ниже приведен базовый псевдокод, который, я надеюсь, адекватно описывает проблему.

Game.cs

class game {
  sprite the_sprite;
  void update(time) {
    var mouse = mouse.state
    if(mouse.clicked) { this.the_sprite.moveTo(mouse.x, mouse.y) }
    this.the_sprite.update(time)
    base.update(time)
  }
}

Sprite.cs

class sprite {
  vector2 location;
  vector2 move_to;
  void moveTo(x, y) { this.move_to = new vector2(x, y) }
  void update(time) {
    if(this.location.x > this.move_to.x /* (or less than) */) {
      // adjust location.x
    }
    if(this.location.y > this.move_to.y /* (or greater than) */) {
      // adjust location.y
    }
  }
}

В основном: когда пользователь щелкает где-то в окне игры, берутся координаты мыши x и y, и игровой объект перемещается к этому месту в течение определенного периода времени.

Ну ... код работает, но он уродлив, и объекты не двигаются прямо к объекту (вместо этого это диагональное движение, сопровождаемое движением по одной оси). Я предполагаю, что есть некоторые математические функции, которые я могу использовать, но я, честно говоря, понятия не имею, с чего начать. Какие-либо предложения?

Matt
источник
3
Привет гость. То, что вы ищете, это нормализация. Пожалуйста, прочитайте ответы на этот вопрос: gamedev.stackexchange.com/questions/7540/… . Один предлагает код, который вам нужен, второй объясняет, как он работает очень хорошо.
Notabene
Здравствуйте, я посмотрел на ссылку, и это было именно то, что мне нужно. Спасибо!
Мэтт

Ответы:

12

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

public Vector2 Direction { get; set; }

Это нормализованный вектор (что означает, что он имеет длину 1), показывающий, куда вы хотите перейти.

Затем добавьте свойство Speed ​​float, которое говорит, как быстро должен работать спрайт.

public float Speed { get; set; }

Вам также необходимо добавить функцию UpdateSprite, так почему бы не поместить ее в свой класс Sprite?

public Update(GameTime gameTime)
{
   Position += Direction * Speed * gameTime.ElapsedGameTime.TotalSeconds;
}

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

Наконец, вы просто устанавливаете свойство direction так:

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();
Джесси Эмонд
источник
Также обратите внимание, что если длина sprite.Direction (до нормализации) меньше некоторого порога, ваш спрайт прибыл.
TreDubZedd
Точно, я собирался редактировать свой пост, но я думаю, что не буду. Если вы не хотите, чтобы ваш спрайт постоянно искал цель, просто установите Направление на Vector2.Zero, когда оно достаточно близко к цели.
Джесси Эмонд
Очень хороший ответ ... и вы также научили меня использовать gameTime (для перемещения спрайтов с соответствующей скоростью на медленных компьютерах), поэтому две птицы одним камнем. Я отмечу этот ответ как принятый.
Мэтт
:) Кстати, мне лично нравится помещать нормализацию в мой класс спрайтов (внутри моей функции обновления), чтобы избежать необходимости постоянно нормализовать ее вне класса. Вы также должны убедиться, что длина вектора не равна 0, иначе вы получите исключение деления на 0. Просто проверьте, если Direction.LengthSquared ()> 0, прежде чем нормализовать его, чтобы он был безопасным (квадрат длины, чтобы вам не приходилось вычислять эту дорогую квадратную функцию;)).
Джесси Эмонд
Допустим, мы используем другую среду IDE, в которой не было функции нормализации, что будет уравнением нормализации?
Призраки
2

Нормализация Google ... Я тоже немного растерялся, но уверен, что это поможет решить вашу проблему. Кто-то еще может уточнить или опровергнуть мой ответ, я уверен

Изменить: я мог бы ответить на этот вопрос лучше, извинения

Я лично всегда обращаюсь к этому сообщению в блоге, чтобы помочь с этими типами проблем: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Он начинается с нуля и имеет отношение к разработке игр.

Дуглас Рей
источник
3
Вы правы, это нормализация. Но всегда лучше попытаться найти хороший ответ в предыдущих вопросах. И если вы отвечаете, всегда лучше немного объяснить или поделиться кодом или чем-то, что, по вашему мнению, может быть полезным, а не просто указывать на Google.
Notabene
Я должен был прокомментировать, вы правы.
Дуглас Рей