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?


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();

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.