Ir ao conteúdo
  • Cadastre-se
Cambalinho

RESOLVIDO C++11 - como verificar 1 array de teclas se estão pressionadas ou nao?

Recommended Posts

eu estou a construir 1 funçao para fazer 1 combinaçao de teclas e esta a funcionar... mas agora estou actualizar para poder pressionar 2 ou mais teclas ao mesmo tempo.

tive de alterar a funçao que verifica se as teclas estão pressionadas:

enum AllKeyState{    Nokey,    All,    Some};AllKeyState AreAllKeysPressed2(const std::vector<int> &keys){    int state = 0x8000;    AllKeyState allkeys=Nokey;    for (int key=0; key<keys.size()-1; key++)    {        if(GetAsyncKeyState(keys[key]) & 0x8000)        {            allkeys=All;        }        else        {            if(allkeys==All)            {                return Some;            }            else            {                return Nokey;            }        }    }    return All;}

esta funçao testa se alguma tecla do vector keys esta precionada. se todas tiverem pressionadas, eu recebo All, se algumas eu recebo Some, se nenhuma tecla estiver pressionada, eu recebo Nokey.

mas estou a receber os resultados incorrectos :(

alguem me pode explicar o que fiz mal no for?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Faça a comparação das duas teclas ao mesmo tempo.

 

Exemplo:

if ( GetAsyncKeyState( VK_RIGHT ) & GetAsyncKeyState( VK_LEFT )  & 0x8000 )

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Faça a comparação das duas teclas ao mesmo tempo.

 

Exemplo:

if ( GetAsyncKeyState( VK_RIGHT ) & GetAsyncKeyState( VK_LEFT )  & 0x8000 )

mas estou com 1 problema, por isso é que estou com dificuldade: qual é a probabilidade, no segundo conjunto, o utilizador pressionar 2 teclas ao mesmo tempo de imediato?

se é que me entendes

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi.

Cara, manjo muito pouco de C++, mas vamos lá...

 

Fiz um teste pra ver se a biblioteca validava as 3 teclas simultâneas, e o resultado foi que a leitura é sequencial:

void AreAllKeysPressed2(void){    while (true)        for ( int x = 0; x < 128; x++ )            for ( int y = 0; y < 128; y++ )                for ( int z = 0; z < 128; z++ )                    if ( ( x != y ) && ( y != z ) && ( z != x ) )                        if ( GetAsyncKeyState(x) & GetAsyncKeyState(y) & GetAsyncKeyState(z) & 0x8000 )                            std::cout << "All" << std::endl;                        else                            if ( (GetAsyncKeyState(x) & GetAsyncKeyState(y) & 0x8000) || \                                (GetAsyncKeyState(y) & GetAsyncKeyState(z) & 0x8000) || \                                (GetAsyncKeyState(z) & GetAsyncKeyState(x) & 0x8000)  \                                )                                    std::cout << "Some" << std::endl;}

Em nenhum momento ocorreu a leitura das 3 teclas simultâneas. Isso demonstra que a leitura sequencial prevalece sobre a paralela.

 

Acredito que, para fazer o que você deseja, de maneira mais confiável, apenas usando threads.

 

Sucessos aí!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Aquele keys.size()-1 na condição do for não devia ser só keys.size()?

 

Em todo caso, reescrevi a função aqui:

enum AllKeyState{    Nokey,    All,    Some};AllKeyState AreAllKeysPressed2(const std::vector<int> &keys){    int state = 0x8000;    int pressed = 0;    int keysSize = keys.size(); // estava com -1 aqui    AllKeyState keyState;       for (int key=0; key<keysSize; key++) {        if(GetAsyncKeyState(keys[key]) & 0x8000) {            pressed++;        }        if (pressed > 0 && key + 1 != pressed) {            // se pelo menos uma tecla já foi pressionada e o número de teclas testadas for diferente das pressionadas, pode sair pois nem todas foram pressionadas (Some)            break;        }        // nos casos de nenhuma e todas, só testando todas do vetor para ter certeza, então vamos em frente...    }    // calcula o resultado e retorna    keyState = pressed == 0 ? Nokey : pressed == keysSize ? All : Some;    return keyState;}
  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

 

Aquele keys.size()-1 na condição do for não devia ser só keys.size()?

 

Em todo caso, reescrevi a função aqui:

enum AllKeyState{    Nokey,    All,    Some};AllKeyState AreAllKeysPressed2(const std::vector<int> &keys){    int state = 0x8000;    int pressed = 0;    int keysSize = keys.size(); // estava com -1 aqui    AllKeyState keyState;       for (int key=0; key<keysSize; key++) {        if(GetAsyncKeyState(keys[key]) & 0x8000) {            pressed++;        }        if (pressed > 0 && key + 1 != pressed) {            // se pelo menos uma tecla já foi pressionada e o número de teclas testadas for diferente das pressionadas, pode sair pois nem todas foram pressionadas (Some)            break;        }        // nos casos de nenhuma e todas, só testando todas do vetor para ter certeza, então vamos em frente...    }    // calcula o resultado e retorna    keyState = pressed == 0 ? Nokey : pressed == keysSize ? All : Some;    return keyState;}

muito obrigado, mas ja resolvi:

    //test if a key\combination keys is pressed    bool AreAllKeysPressed(const std::vector<int> &keys)    {                   int state = 0x8000;                  for (int key : keys)                  {                       state &= GetAsyncKeyState(key);                   }                  return (state) != 0;    }    bool CombineKeys(std::vector<std::vector<int>> const &keys)    {              static bool PreviousKeyPressed=false;              static DWORD StartTimer = GetTickCount();              static DWORD AllKeysTimer = 0;              static int i=0;              //test if the 1st key was pressed              if((AreAllKeysPressed(keys[0])==true) && PreviousKeyPressed==false)              {                          i=0;                          PreviousKeyPressed=true;                          StartTimer = GetTickCount();                          AllKeysTimer=0;                          i++;              }             //if the last combination have only 1 key             else if((i==(int)keys.size()-1) && (AreAllKeysPressed(keys[(int)keys.size()-1])==true) && PreviousKeyPressed==true && keys[(int)keys.size()-1].size()==1)             {                            PreviousKeyPressed=false;                           StartTimer = 0;                          AllKeysTimer=0;                          i=0;                           return true;             }             //testing if the keys are pressed in same time             //but you only have 1 second for that             else if(GetTickCount() - AllKeysTimer <= 500 && PreviousKeyPressed==true)              {                        if(AreAllKeysPressed(keys[i])==true && i!=(int)keys.size()-1)                        {                                    PreviousKeyPressed=true;                                    StartTimer = GetTickCount();                                    AllKeysTimer=0;                                    i++;                        }                       else if(AreAllKeysPressed(keys[(int)keys.size()-1])==true && i==(int)keys.size()-1)                       {                               PreviousKeyPressed=false;                              StartTimer = 0;                              AllKeysTimer=0;                              i=0;                              return true;                       }             }            //test if the StartTimer have 2 seconds           else if ((GetTickCount() - StartTimer >= 2000))//now i put the timer here            {                          StartTimer =0;                         AllKeysTimer=0;                        PreviousKeyPressed=false;                         i=0;          }          //test if the last key was pressed          else if((i==(int)keys.size()-1) && (AreAllKeysPressed(keys[(int)keys.size()-1])==true) && PreviousKeyPressed==true)          {                         StartTimer=0;                        AllKeysTimer=GetTickCount();          }          //test if the next key was pressed         else if((AreAllKeysPressed(keys[i])==true) && PreviousKeyPressed==true)        {                          PreviousKeyPressed=true;                         StartTimer = GetTickCount();                         AllKeysTimer=0;                          i++;         }         else if((AreAllKeysPressed(keys[i])==false) && PreviousKeyPressed==true)        {                  AllKeysTimer=GetTickCount();        }        else       {                         PreviousKeyPressed=false;                       StartTimer = GetTickCount();                       AllKeysTimer=0;                       i=0;        }        return false;  } #define CombinationKeys(...) CombineKeys({__VA_ARGS__})

e eis exemplos:

if(CombinationKeys({'A','S'},{'W'},{'R','T'}, {'O','P'})==true)            MessageBox(NULL,"hi", "hello",MB_OK);if(CombinationKeys({'A','S'},{'W'},{'R'}, {'O','P'})==true)            MessageBox(NULL,"hi", "hello",MB_OK);if(CombinationKeys({'A'},{'W'},{'R'}, {'O'})==true)            MessageBox(NULL,"hi", "hello",MB_OK);if(CombinationKeys({'A'},{'W'},{'R','T'}, {'O','P'})==true)            MessageBox(NULL,"hi", "hello",MB_OK);

esta muito porreiro, espero que gostem ;)

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×