Anket tabanlı girdi üzerindeki tuş kombinasyonları


9

Bu nedenle, yoklamaya dayalı bir giriş sisteminiz olduğunu varsayın

void update()
{
    if( Keyboard[ 'A' ] )
        // A is down
}

3 ila 8 uzunluktaki tuş kombinasyonlarını tanımak istediğinizi varsayalım (aşağı, aşağı ileri, ileri, hado-ken için A gibi)

Yoklamalı girişte genel (kolayca değiştirilebilir / programlanabilir) tuş kombinasyonu giriş sistemini en iyi nasıl yaratırsınız ?

Yanıtlar:


7

Temel olarak yapamazsınız . Tuş kombinasyonları bir sipariş gerektirir ve bir sipariş olaylar gerektirir.

Yapabileceğiniz şey, her karenin temel durumlarını karşılaştırarak ve farklılıklardan hoc post-hoc keyup / keydown olayları oluşturarak yoklamayı olaylara dönüştürmektir. Bu kadar güvenilir değil, çünkü "yerel" olay sistemlerinin sağladığı zaman damgasını ve diğer çerçeve içi siparişini kaybedersiniz, ancak çerçeve başına en az bir anahtarı algılamanıza ve sipariş vermenize izin verir.

Bu sıralı etkinliklere sahip olduğunuzda, bunları hareket listelerinizle eşleştirmek ve doğru olanı yürütmek için sonlu durum makinesi veya başka bir araç kullanabilirsiniz.


Bu demek yanıltıcı biraz var olamaz olaylar olmadan bunu. Teknik olarak, olaylar bir koşul karşılandığında bir yöntemi veya yöntem listesini çağırmanın bir yoludur. Bu anlamda olaylara ihtiyacınız var. Ancak, bu açıklamaya uyan birçok programlama görevine olaylar (yanlış) kelimesini uygulayabilirim. Sorunu genellikle yaptığım şekilde çözen bir cevap ekledim, bu da çoğu programcının "olay" olarak düşünmeye meyilli olmadığını kullanmaktadır.
Olhovsky

2
Kodunuz tam olarak ne söylediğimi olaysız yapıyor, ancak uyarıları yok sayar - bu da çerçeve içi sıralamayı kaybedersiniz. Olayları örneğin Win32 ileti döngüsünden aldığınızda, bunları çerçeve başına bir glob'tan daha ayrıntılı bir düzende alırsınız. Deltaları kendiniz hesapladığınızda, bunu kaybedersiniz. Oyuncuların bir kombinasyonun birkaç parçasını tek bir kareye girebileceği bir dövüş oyunu için, bunların sıralı veya bozuk olup olmadığını bilmeniz gerekir.

Yeterince adil. 60hz'de anket yapmamız şartıyla, 60Hz yoklamanın sağladığı 16 ms'den daha az olan presleri (oyuncularımızın insan olduğunu varsayarak) ayırmak istediğimizden şüpheliyim.
Olhovsky

Yaparız. Yetenekli dövüş oyunu oyuncuları üç çerçeveden az bir hadouken / shoryuken çubuk komutuna girebilir, yani aralarında ayrım yapmalıyız.

O zaman 60hz'den daha sık anket yapmanız gerekir.
Olhovsky

3

Bunun bir yolu, geçerli ve önceki giriş durumlarını saklamak ve girişi her yokladığınızda bunları karşılaştırmaktır.

Basılabilen her anahtar için, anahtarın aşağı durumdan yukarı duruma geçtiği son kez zaman damgasına sahip bir nesneyi saklayın.

Bu nesneleri her ankette yaparak güncelleyin:

void update(){
    some_key_has_been_pressed = false;
    foreach(key in keys){
        if(previous_input[key].Down && current_input[key].Up){
            keys[key].up_timestamp = current_time();
        }

        if(current_input[key].Down){
            keys[key].down_timestamp = current_time();
            some_key_has_been_pressed = true;
        }
    }
}

Artık desenlerinize göre kombinasyonlarınızı eşleştirebilirsiniz keys.

Her bir açılan için bir birleşik nesne bulun ve her bir yoklamadaki her bir açılan nesne üzerinde update () öğesini çağırın.

Bir açılan nesnenin update () yöntemi, açılanla eşleşecek şekilde kalıp oluşturur ve açılan için gerekli tüm koşulların bu ankette karşılanıp karşılanmadığını kontrol eder. Yani kombo için şimdiye kadarki tüm tuş zaman damgaları sırayla ve komboyu kıracak başka bir tuşa bu kareye basılmadı. Karşılaşılan her koşul için, birleşik nesnede bir sayacı denetlenecek bir sonraki koşula yükseltin. Tüm koşullar bir birleşik girişte karşılandığında, birleşik girişin gerçekleştirmesi gereken yöntemi çağırın. Eğer some_key_has_been_pressed == trueancak combo için bir sonraki durumdur tuşuna basıldığında edilmedi, daha sonra 0 olarak combo en memnun durum sayacını sıfırlayın.

Yukarıdakiler benim tercih ettiğim yöntemdir, çünkü uygulanması basit, bakımı kolay, verimli ve oldukça modülerdir.

Ancak başka bir iyi yöntem için, C # ile yazılmış XNA giriş dizisi örneğine bakın ve mantık muhtemelen kullandığınız dile aktarılabilir.


İkinci if ifadesinde, if(current_input[key].down){anahtarın previous_inputdurumun açık olup olmadığını da kontrol etmek istemez miydiniz ? Yazıldığı gibi, tutulan bir anahtarın sürekli güncelleneceğini düşünüyorum down_timestamp.
webdevkit

Aşağı zaman damgasını sürekli güncellemek amaçlanan davranıştır. Bu, herhangi bir anahtarın up_timestamp ve down_timestamp'larını ne kadar süreyle tutulduğunu kontrol etmenizi sağlar. Sürekli bir tuşa basarsanız, up_timestamp değerini değiştirmezsiniz, bu nedenle (down_timestamp - up_timestamp) hala tutulduğu süreyi verir.
Olhovsky

açıklama için teşekkürler. Ben tersini düşünüyordum, burada up_timestamp - down_timestamp tutulan bir anahtarın süresi.
webdevkit

1

Son X tuşu olaylarının bir yığınını yapın, her tuş olayı için tuşa ve basın / bırakma süresine sahip bir nesne ekleyin, ardından yığının son üyelerinin özel bir kalıpla eşleşip eşleşmediğini ve bu tuşların kombinasyon olarak sayılır. Son olarak en eski nesneyi yığından kaldırın.


2
Alt nesneyi kaldırabileceğiniz bir yığın gerçekten bir yığın değildir;)
Olhovsky

Sıralı bir grup veri varlığı, bir liste doğru terim olabilir.
aaaaaaaaaaaa

deque;) O (1) enq / deq ftw.
michael.bartnett

3
Nesnelerin bir uca konulduğu ve diğer uçtan çıkarıldığı sıralı bir sıraya en uygun şekilde kuyruk adı verilir .

1
Bir halka arabelleği oluşturabilir (BufferLength> = en uzun komut) ve ona anahtarlar yazabilirsiniz (Position = Number MOD BufferLength). Hiçbir ekleme / çıkarma gerekmez
Kromster
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.