Bir karakter nasıl atlanır?


44

Şu anda Direct # 9.0 kullanarak C # ile oyun yapıyorum. Oyunun yeni versiyonu Eşek Kong NES. Neredeyse her şeyi tamamladım, ancak Mario'nun atlamasının fiziği ile ilgili problem yaşıyorum. Y ve X koordinasyonları için beyan ettiğim değişkenler var.

Bunu yapmanın basit bir yöntemi olup olmadığını merak ediyordum. Bir cevap için yüksek ve düşük aradım, ancak bulduğum cevaplar alakasız / veya XNA gibi farklı bir programlama dili kullanıyor.

Şu anda W tuşuna basılıp basılmadığını kontrol etmek için ayarlanmış bir bool değişkeni var, sonra onu atlamak için herhangi bir kodu tetikleyeceğim. Gibi dolaşıyordum.

  if (jump == true)
    {

        Playerypos -=  vel;
        Playerxpos +=  vel;
    }

Hangi işe yaramadı ki. Bir cevap için yüksek ve düşük aradım ve eğer birisi beni basit bir çözüme doğru yöne işaret edebiliyorsa çaresizim. Bu harika olurdu. Herhangi bir cevap için çok takdir etmek.


5
Farklı bir programlama dili kullanarak cevaplar bir sorun teşkil etmemelidir. Algoritma, özel bir uygulama değil, ilgilenilen şeydir ... sadece bir şeyi anlamadan kopyalayıp yapıştırmayı ummadığınız sürece, kesinlikle umarız olmadığınızı umarız! Algoritmaları diğer programlama dillerinden okuyabilmek ve uyarlayabilmek, sahip olmak için çok iyi bir beceridir.
ccxvii

Yanıtlar:


84

Her şeyden önce, XNA da C # kullanır, bu yüzden aynı programlama dilidir. Altta yatan API DirectX'ten farklılıklar gösterse de, bunun atlama ile ilgisi yoktur, bu nedenle aynı dersler veya cevaplar burada da uygulanmalıdır. Ayrıca, bunu birçok faktöre bağlı olarak uygulamak için sayısız yol vardır. Aşağıda anlatacağım şey, olasılıklardan sadece bir tanesi.

Temel Fizik Gereksinimleri

Öncelikle güncelleme döngüsünde bazı temel fizik değişkenleri ve hesaplamaları gerekir. Özellikle, tanımlanmış konum, hız ve yerçekimine ihtiyacınız var ve güncelleme döngünüz buna aşağı yukarı benzer bir şey yapıyor olmalı (çarpışma tespiti ve cevap basitliği için ihmal edilmeli):

float positionX, positionY;     // Position of the character
float velocityX, velocityY;     // Velocity of the character
float gravity = 0.5f;           // How strong is gravity

void Update(float time)
{
    positionX += velocityX * time;      // Apply horizontal velocity to X position
    positionY += velocityY * time;      // Apply vertical velocity to X position
    velocityY += gravity * time;        // Apply gravity to vertical velocity
}

Sabit Yükseklik Atlama

Şimdi, her zaman aynı yüksekliğe sahip bir sıçrama uygulamanın en kolay yolu, tuşa ne kadar basarsanız basılmaksızın, dikey hızı bir kez değiştirmek. Bu, karakterin yükselmeye başlamasına neden olurken, yerçekimi otomatik olarak onu aşağıya çekmekle ilgilenir:

void OnJumpKeyPressed()
{
    velocityY = -12.0f;   // Give a vertical boost to the players velocity to start jump
}

Önemli Karakteriniz yerde değilse bir sıçrama başlatmak istemezsiniz, bu nedenle bunun için bir kontrol eklemeniz gerekir.

Değişken Yükseklik Atlama

Ancak Mario ve Sonic gibi oyunlar, atlama yüksekliğinin düğmeye ne kadar uzun basacağınıza bağlı olarak değişken bir zıplamaya sahip. Bu durumda her iki basarak işlemek gerekir ve atlama tuşu bırakmadan. Gibi bir şey ekleyebilirsiniz:

void OnJumpKeyReleased()
{
    if(velocityY < -6.0f)       // If character is still ascending in the jump
        velocityY = -6.0f;      // Limit the speed of ascent
}

Yukarıdaki koddaki tüm bu değerlerin (örneğin 0.5, -12.0fveya gibi sayılar -6.0f) ince ayarlanması, zıplama hissinizi, ne kadar yüksek atladığı, zıplama düğmesini bıraktıktan sonra bile ne kadar momentum tuttuğu, ne kadar hızlı düştüğü, vb. .

Önemli Bu fonksiyonları her kareye çağırmayın. Tuşa basıldığında veya bırakıldığında yalnızca bir kez arayın. Aksi halde karakterin zıplamak yerine uçacak.

Çalışma örneği

Tarayıcınızı burada deneyebileceğiniz, yukarıda açıklanan tekniklerin hızlı bir örneğini hazırladım (atlamak için fare düğmesine basın, atlamanın yüksekliğini kontrol etmek için ortada bırakın). JS'de ama daha önce de belirttiğim gibi, bu durumda dil konu dışı.

http://jsfiddle.net/LyM87/


11
Birkaç gün önce yazılmış bu şaşırtıcı makaleyi, bu konuyla ilgili bilgilerle paylaşma şansı da alabilir: 2D platform uygulayıcıları . Ve ayrıca bu: Sonic Jumping .
David Gouveia

2
Makale, cevabınızda yaptığınızdan farklı bir atlama yapmanın farklı bir yolunu açıklamaktadır. Yerçekimini bastırmak veya düğmeyi basılı tutarken dürtü eklemeye devam etmek için çağırır. Genelde David'in cevabında söylediklerini yaparım, ancak makalenin yöntemlerinden herhangi biri hakkında düşünceleriniz var mı?
Jeff

@Jeff Bu da dikkatimi çekti ve bu yüzden bunu uygulamanın birden fazla yolu olduğunu söylemiştim. İlk makalede, aynı sorunu ele almanın iki yolu daha açıklanırken, tarif ettiğim yol ikinci maddeye dayanmaktadır. Birbirlerini nasıl karşılaştırdıklarını bilmiyorum, ancak uygulanması çok kolay. Sonunda, bu yöntemi seçtim çünkü açıklamak daha kolaydı ve bir zamanlayıcı eklemeyi ya da çok sayıda azalan büyüklük darbesiyle uğraşmayı gerektirmiyordu.
David Gouveia

Cevap, belirli bir oyuna ve kaç tane animasyon yapmak istediğinize bağlı olarak değişebilir. Metroid sabit bir hız atlaması kullanır: / iniş, ancak dorukta pürüzsüz ve "kavisli" görünmesi için yüksek kaliteli animasyon çalışmaları ile maskeler. Diğer pek çok platformcu, iyi çalışması için daha fazla çalışma gerektiren değişken hızlı sıçramalar kullanır.
Sean Middleditch

1
Bu 5 yıl sonra çok yardımcı oldu :) ve bu keman şey çok güzel - JS öğrenmeliyim!
Akışkanlık

1

Fizikteki gibi. Sadece şu anda bastırdığınız jump keyve karakterin olduğu yerde yukarı doğru hız (itme denir) ekler, ancak karakteri her zaman yerçekimine göre düşürür.

Karakterin her atlayışında zıplamasını istemiyorsanız, zemine vurduğunda - çünkü tutuyorsunuz jump key- jump key is being pressedsonradan jump keysalıverdiğiniz ve sonra ayarlanan değişkeni ekleyin . pseudocode:

if jump being key pressed == false && jump key just pressed
   add y velocity 
   jump being key pressed = true

if jump key released
   jump being key pressed = false

decrease velocity by gravity
check for collisions // to not penetrate ground ...

Yolunu kullandıysam:

if jump key not pressed
     jump height = 0            // imaginary height donkey would travel without gravity

if jump key pressed
     // going up
     if jump height < maximal height donkey might jump
         jump height += 5
         donkey.y    += 5        // 
     // going down
     else if jump height < 2 * maximal height donkey might jump
         jump height += 5
         donkey.y    -= 5

Nasıl donkey.ydeğişecek senin hayal gücünle. Hızı küçülmeli, daha iyi görünmesi için eşek havadadır.

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.