Vektörleri kullanarak bir hareketli grafiği XNA / C # içinde taşıma


9

Şu anda C # dili ile XNA oyun geliştirme arıyorum.

İki sınıf var: ana oyun işleyicisi ve bir "sprite" sınıfı. Aşağıda, konuyu yeterince açıkladığını umduğum bazı temel sözde kodlar verilmiştir.

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

Temel olarak: kullanıcı oyun penceresinde bir yeri tıkladığında, farenin x ve y koordinatları alınır ve oyun nesnesi bir süre boyunca o konuma doğru hareket eder.

Şey ... kod çalışıyor, ama çirkin ve nesneler doğrudan nesneye doğru hareket etmiyor (bunun yerine çapraz hareket, ardından tek eksenli hareket). Sanırım kullanabileceğim bazı matematiksel fonksiyonlar var, ama dürüstçe nereden başlayacağımı bilmiyorum. Herhangi bir öneri?


3
Merhaba misafir. Aradığın şey normalleşme. Lütfen bu sorunun yanıtlarını okuyun: gamedev.stackexchange.com/questions/7540/… . Biri ihtiyacınız olan kodu sunar, ikincisi nasıl çok güzel çalıştığını açıklar.
Notabene

Merhaba, bağlantıya baktım ve tam da ihtiyacım olan şey buydu. Teşekkür ederim!
Matt

Yanıtlar:


12

Sorununuzu doğru bir şekilde anlarsam, sadece hareketli grafik sınıfınızda taşımak istediğiniz yönü temsil eden Vector2 yönüne sahip olmalısınız. Bunun gibi:

public Vector2 Direction { get; set; }

Bu, nereye gitmek istediğinizi gösteren normalleştirilmiş vektördür (1 uzunluğu olduğu anlamına gelir).

Ardından, hareketli grafiğin ne kadar hızlı gitmesi gerektiğini söyleyen bir Speed ​​float özelliği ekleyin.

public float Speed { get; set; }

Ayrıca bir UpdateSprite işlevi eklemeniz gerekir, bu yüzden neden Sprite sınıfınıza koymuyorsunuz?

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

Bu hareketli grafiğin hareket etmesini sağlamak için konumunu güncelleyecektir (hareketli grafiğin yavaş bilgisayarlarda da düzgün hareket etmesi için delta saniye ile çarpacaksınız).

Son olarak, yön özelliğinizi şöyle ayarlayın:

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

Sprite uzunluğunun (normalizasyondan önce) bir eşikten daha az olması durumunda, hareketli grafiğinizin geldiğine dikkat edin.
TreDubZedd

Tam olarak, yazımı düzenlemek üzereydim, ama sanırım yapmayacağım. Hareketli grafiğinizin hedefi sürekli aramasını istemiyorsanız, hedefe yeterince yakın olduğunda Yönü Vector2.Zero değerine ayarlayın.
Jesse Emond

Çok iyi bir cevap ... ve ayrıca bana gameTime'ın (spriteları daha yavaş bilgisayarlarda uygun bir hızda hareket ettirmek için), yani bir taşlı iki kuşun öğretildi. Bu cevabı kabul edilen olarak işaretleyeceğim.
Matt

:) Bu arada ben normalde sınıf dışında sürekli normalleştirmek zorunda önlemek için, normalleştirme sprite sınıfımın içine (güncelleme işlevi içinde) koymak istiyorum. Ayrıca, vektörün uzunluğunun 0'a eşit olmadığından emin olmalısınız, aksi takdirde 0 istisnasına bölünürsünüz. Güvenli olması için normalleştirmeden önce Direction.LengthSquared ()> 0 olup olmadığını kontrol edin (pahalı kare işlevini hesaplamak zorunda kalmamanız için uzunluk kare;)).
Jesse Emond

Diyelim ki normalleştirme fonksiyonu olmayan farklı bir IDE kullanıyoruz, Normalize denklemi ne olurdu?
Spooklar

2

Google normalizasyonu ... Ben de bu konuda biraz kayboldum, ancak bunun sorununuzu çözmeye yardımcı olacağından eminim. Eminim başka biri cevabımı detaylandırabilir veya çürütebilir

Edit: Bu daha iyi cevap verebilir, özür dilerim

Ben şahsen her zaman bu tür sorunlara yardımcı olmak için bu blog yayınına bakıyorum: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-1/

Sıfırdan başlar ve oyun geliştirme ile ilgilidir.


3
Haklısın, normalleşmedir. Ancak önceki sorularda iyi bir cevap bulmaya çalışmak her zaman daha iyidir. Eğer cevap veriyorsanız, sadece google'ı işaret etmekle kalmayıp, kodu veya yararlı olabileceğini düşündüğünüz her şeyi çok az açıklamak veya paylaşmak her zaman daha iyidir.
Notabene

Yorum yapmalıydım, haklısın.
Douglas Rae
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.