Przenoszenie duszka w XNA / C #, przy użyciu wektorów

9

Obecnie zajmuję się tworzeniem gier XNA w języku C #.

Mam dwie klasy: główny moduł obsługi gry i klasę „sprite”. Poniżej znajduje się podstawowy pseudo-kod, który - mam nadzieję - odpowiednio opisuje problem.

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

Zasadniczo: gdy użytkownik kliknie gdzieś w oknie gry, współrzędne xiy myszy są pobierane, a obiekt gry przesuwa się w tym miejscu w pewnym okresie czasu.

Cóż ... kod działa, ale jest brzydki, a obiekty nie poruszają się bezpośrednio w kierunku obiektu (zamiast tego jest to ruch ukośny, a następnie ruch jednoosiowy). Domyślam się, że jest kilka funkcji matematycznych, których mogę użyć, ale szczerze mówiąc, nie mam pojęcia, od czego zacząć. Jakieś sugestie?

Matt
źródło
3
Witaj gościu. To, czego szukasz, to normalizacja. Przeczytaj odpowiedzi na to pytanie: gamedev.stackexchange.com/questions/7540/… . Jeden oferuje kod, którego potrzebujesz, drugi wyjaśnia, jak to działa bardzo ładnie.
Notabene
Witam, spojrzałem na link i to było dokładnie to, czego potrzebowałem. Dziękuję Ci!
Matt

Odpowiedzi:

12

Jeśli dobrze rozumiem twój problem, powinieneś po prostu mieć kierunek Vector2 reprezentujący kierunek, w którym chcesz się poruszać w swojej klasie duszka. Lubię to:

public Vector2 Direction { get; set; }

Jest to znormalizowany wektor (co oznacza, że ​​ma długość 1) wskazujący dokąd chcesz iść.

Następnie dodaj właściwość Speed ​​float, która mówi, jak szybko powinien iść duszek.

public float Speed { get; set; }

Musisz także dodać funkcję UpdateSprite, więc dlaczego nie umieścić jej w klasie Sprite?

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

Spowoduje to zaktualizowanie pozycji duszka, aby go poruszyć (mnożymy przez delta sekund, aby duszek poruszał się również poprawnie na wolnych komputerach).

Na koniec ustaw swoją właściwość kierunku w następujący sposób:

sprite.Direction = location - sprite.Position;
sprite.Direction.Normalize();
Jesse Emond
źródło
Zauważ też, że jeśli długość sprite.Direction (przed normalizacją) jest mniejsza niż pewien próg, twój sprite przybył.
TreDubZedd
Właśnie miałem edytować swój post, ale chyba nie zrobię tego. Jeśli nie chcesz, aby duszek ciągle szukał celu, po prostu ustaw Kierunek na Vector2.Zero, gdy będzie wystarczająco blisko celu.
Jesse Emond
Bardzo dobra odpowiedź ... a także nauczyłeś mnie korzystania z gameTime (do poruszania duszków z odpowiednią prędkością na wolniejszych komputerach), więc dwa ptaki z jednym kamieniem. Oznaczę tę odpowiedź jako zaakceptowaną.
Matt
:) Nawiasem mówiąc, osobiście lubię umieszczać normalizację w mojej klasie duszka (wewnątrz mojej funkcji aktualizacji), aby uniknąć konieczności ciągłej normalizacji poza klasą. Należy również upewnić się, że długość wektora nie jest równa 0, w przeciwnym razie otrzymasz wyjątek dzielenia przez 0. Po prostu sprawdź, czy Direction.LengthSquared ()> 0 przed normalizacją, aby była bezpieczna (długość podniesiona do kwadratu, abyś nie musiał obliczać tej drogiej funkcji kwadratowej;)).
Jesse Emond
Powiedzmy, że używamy innego IDE, które nie miało funkcji normalizacji, jakie byłoby równanie Normalizuj?
Spooks
2

Normalizacja Google ... Jestem też trochę zagubiony, ale jestem pewien, że pomoże to rozwiązać Twój problem. Jestem pewien, że ktoś inny może opracować lub obalić moją odpowiedź

Edycja: Mogę odpowiedzieć na to lepiej, przepraszam

Osobiście zawsze szukam tego postu na blogu, aby pomóc w rozwiązywaniu tego rodzaju problemów: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Zaczyna się od zera i ma znaczenie dla rozwoju gry.

Douglas Rae
źródło
3
Masz rację, to jest normalizacja. Ale zawsze lepiej jest znaleźć dobrą odpowiedź na poprzednie pytania. A jeśli odpowiadasz, zawsze lepiej jest mało wyjaśniać lub udostępniać kod lub cokolwiek, co uważasz, że może być przydatne, nie tylko wskazywać na google.
Notabene
Powinienem był skomentować, masz rację.
Douglas Rae