Переміщення спрайту в 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, і ігровий об’єкт протягом певного періоду часу рухатиметься до цього місця.

Ну ... код працює, але він некрасивий, і об'єкти не рухаються безпосередньо до об'єкта (натомість це діагональний рух, за яким рухається одновісний рух). Я здогадуюсь, що я можу використовувати деякі математичні функції, але я, чесно кажучи, не знаю, з чого почати. Будь-які пропозиції?


3
Привіт гість. Що ви шукаєте - це нормалізація. Будь ласка , прочитайте відповіді на це питання: gamedev.stackexchange.com/questions/7540 / ... . Один пропонує код, який вам потрібен, другий пояснює, як це дуже добре працює.
Нотабене

Привіт, я переглянув посилання, і це було саме те, що мені потрібно. Дякую!
Метт

Відповіді:


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;
}

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

Нарешті, ви просто встановите властивість свого напрямку так:

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();

Зауважте також, що якщо довжина спрайту. Направлення (до нормалізації) менше деякого порогу, ваш спрайт прийшов.
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.
Нотабене

Я мав би прокоментувати, ви праві.
Дуглас Рей
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.