Tuşa basmanın başlangıcındaki gecikmeyi kaldırma


11

Basit bir oyun yapıyorum ve karşılaştığım sorunlardan biri sürekli bir tuşa basarken can sıkıcı bir gecikme.

Temel olarak, örneğin (çok uzun bir süre) tuşuna bastığımda, Upnesnem 1 birim yukarı hareket edecek, hareket etmeyecek (yaklaşık 1 saniye) ve sonra sürekli olarak 1 birim yukarı (herhangi bir gecikme olmadan) hareket edecek.

Şu anda, nesneyi (SDL2) taşımak için bunu kullanın:

while (SDL_PollEvent(&event))
{
    switch (event.type)
    {
    case SDL_KEYDOWN:
        switch (event.key.keysym.sym)
        {
        case SDLK_UP:
            //Move object 1 unit up
            break;
        //Other unrelated things omitted
        }
        break;
    //Omitted other cases
    }
}

Sahip olmak istediğim gecikmeyi kaldırmak, böylece nesne hemen Upçok hızlı hareket edebilir . Bunu yapmanın bir yolu var mı?

Yanıtlar:


19

Aşağı açılan olayların tetiklenmesini bekleyerek, büyük olasılıkla işletim sisteminin denetlediği (ve hangi kullanıcıların kendilerini belirtebileceği) önemli olay yineleme hızına merhamet edersiniz.

Bunun yerine, aramak isteyebilirsiniz SDL_GetKeyboardStateoyun güncelleme döngü üstünde (gerçekleşen güncelleme parçası her karesini, olsun veya olmasın bir olay gelip vardır) klavyenin durumunu elde etmek ve yukarı olmadığını görmek için kontrol herhangi bir kare sırasında tuşu basılı olsun veya olmasın.


Pencere mesajlarını dinlemek daha iyi olmaz mıydı? Yoklama kullanarak bazen çok kısa tuş basışlarını özlüyorum ve kare hızı düşük olduğunda bu sorun daha da kötüleşiyor.
Roy T.

@RoyT. Gerçekten oyununuza ve anahtarla tetiklemek istediğiniz eylem türüne bağlıdır. Tuşa basma bir kerelik bir şeyse, "Bir eylem" tuşu gibi, bir iletişim kutusunu kapatırsa, bir mesaj kuyruğu doğru yaklaşımdır - atomik bir olay dinlemek istiyorsunuz. - Öte yandan, anahtar durumu "taşıma" tuşu gibi devam eden bir durumu temsil ediyorsa, mantık genellikle while key UP is down move 30 units per second- ve saniyede yalnızca anahtar aşağı ve yukarı arasında ölçülebilir bir zamanınız olduğunda genellikle mantıklıdır - genellikle birden fazla kare.
Falco

@RoyT. Ayrıca mesajları dinleyebilir (ve bunları kendi klavye durum dizinizi güncellemek için kullanabilirsiniz); Sadeliği için bu yaklaşımı önermeyi seçtim. Yine de kesinlikle başka bir cevap yazabilirsiniz. Önemli olan, anahtarın sürekli olarak kapalı olup olmadığını kontrol etmek için OS mesajlarına güvenmekten kaçınmaktır , çünkü sizi OS anahtarı tekrarlama oranına bağlar.

Ve çerçeveye göre demek istiyorsun oyun kene, video karesi değil, değil mi? Çünkü render döngüsünde plebs ve oyun mantığı kodlamıyoruz. :-)
corsiKa

@JoshPetrie Tamamen katılıyorum, sadece bir 'basın' yerine 'tıklamayı' kontrol etmeniz gerekiyorsa bu küçük uyarıyı belirtmek istedim. :)
Roy T.

10

Alternatif bir yol (Josh'un yaklaşımı da harika!) Bir boolean kurmak SDL_KEYDOWNve muhtemelen tüm tekrarlanan önemli olayları görmezden gelmek olacaktır. Bunu repeatanahtar etkinliğin üyesini kontrol ederek yapabilirsiniz .

O zaman kendi zamanlayıcıyı uygulayabilirsin, bu da süslü bir şey olmak zorunda değildir ve anahtar tekrarını kendin uygulayabilirsin. Eylemi doğrudan zamanlayıcıdan tetikleyebilir, hatta bir SDL_KEYDOWNetkinlik oluşturabilir ve çözümleri birleştirebilirsiniz.

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.