2010-09-18 16 views
5

Mi piacerebbe sapere come posso rilevare la pressione di un tasto o il rilascio di un tasto in un ciclo while in SDL. Ora, so che puoi ottenere gli eventi con SDL come OnKeyPressed, OnKeyReleased, OnKeyHit, ecc., Ma voglio sapere come creare funzioni come 'KeyPressed' che restituisce un valore booleano, invece di essere un evento. Esempio:Input in SDL (tasto premuto)

while not KeyHit(KEY_ESC) 
{ 
//Code here 
} 

risposta

11

So che hai già selezionato una risposta .. ma qui c'è un codice reale di come lo faccio normalmente con un array. :)

prima definire questo da qualche parte.

bool KEYS[322]; // 322 is the number of SDLK_DOWN events 

for(int i = 0; i < 322; i++) { // init them all to false 
    KEYS[i] = false; 
} 

SDL_EnableKeyRepeat(0,0); // you can configure this how you want, but it makes it nice for when you want to register a key continuously being held down 

Poi più tardi, creare una funzione di tastiera(), che registrerà l'input da tastiera

void keyboard() { 
     // message processing loop 
     SDL_Event event; 
     while (SDL_PollEvent(&event)) { 
      // check for messages 
      switch (event.type) { 
       // exit if the window is closed 
      case SDL_QUIT: 
       game_state = 0; // set game state to done,(do what you want here) 
       break; 
       // check for keypresses 
      case SDL_KEYDOWN: 
       KEYS[event.key.keysym.sym] = true; 
       break; 
      case SDL_KEYUP: 
       KEYS[event.key.keysym.sym] = false; 
       break; 
      default: 
       break; 
      } 
     } // end of message processing 
} 

Poi, quando in realtà si desidera utilizzare l'input da tastiera cioè una funzione handleInput(), potrebbe essere simile questo:

void handleInput() { 
    if(KEYS[SDLK_LEFT]) { // move left 
     if(player->x - player->speed >= 0) { 
      player->x -= player->speed; 
     } 
    } 
    if(KEYS[SDLK_RIGHT]) { // move right 
     if(player->x + player->speed <= screen->w) { 
      player->x += player->speed; 
     } 
    } 
    if(KEYS[SDLK_UP]) { // move up 
     if(player->y - player->speed >= 0) { 
      player->y -= player->speed; 
     } 
    } 
    if(KEYS[SDLK_DOWN]) { // move down 
     if(player->y + player->speed <= screen->h) { 
      player->y += player->speed; 
     } 
    } 
    if(KEYS[SDLK_s]) { // shoot 
     if(SDL_GetTicks() - player->lastShot > player->shotDelay) { 
      shootbeam(player->beam); 
     } 
    } 
    if(KEYS[SDLK_q]) { 
     if(player->beam == PLAYER_BEAM_CHARGE) { 
      player->beam = PLAYER_BEAM_NORMAL; 
     } else { 
      player->beam = PLAYER_BEAM_CHARGE; 
     } 
    } 
    if(KEYS[SDLK_r]) { 
     reset(); 
    } 

    if(KEYS[SDLK_ESCAPE]) { 
     gamestate = 0; 
    } 
} 

E naturalmente si può facilmente fare quello che hai intenzione di fare

while(KEYS[SDLK_s]) { 
    // do something 
    keyboard(); // don't forget to redetect which keys are being pressed! 
} 

** Versione aggiornata sul mio sito web: ** Per il bene di non inviare un sacco di codice sorgente, è possibile visualizzare una classe tastiera SDL completa in C++ che supporta

  1. singolo ingresso chiave
  2. simultanea chiave Combos (Keys tutti premuti in qualsiasi ordine)
  3. sequenziale chiave Combonations (Keys tutti premuti in un ordine specifico)

http://kennycason.com/posts/2009-09-20-sdl-simple-space-shooter-game-demo-part-i.html (se avete problemi, fatemelo sapere)

0

È necessario disporre di 2 tabelle di valori booleani per le chiavi. Una tabella, in cui si impostano le chiavi vero o falso in base agli eventi keydown/keyup SDL e un altro, che si inizializza con false. Quando controlli keyPressed, devi solo confrontare la seconda chiave della tabella con la prima chiave della tabella, e se diversa, se la seconda chiave della tabella è falsa, allora è stata premuta, altrimenti è stata rilasciata. Successivamente, si esegue la seconda tabella [chiave]: = non secondaTabella [chiave]. Lavori!

+0

Perché grazie mille, non so come apprezzare il tuo aiuto! – deluvas

0

Ho avuto questo problema in LuaJIT con FFI, questo è come ho risolto:

globale: codice

KEYS = {} 

Evento:

ev = ffi.new("SDL_Event[1]") 
function event() 
    while sdl.SDL_PollEvent(ev) ~= 0 do 
     local e = ev[0] 
     local etype = e.type 
     if etype == sdl.SDL_QUIT then 
      return false -- quit 
      -- os.exit() -- prevents interactive mode 
     elseif etype == sdl.SDL_KEYDOWN then 
      if e.key.keysym.sym == sdl.SDLK_ESCAPE then 
       return false -- quit 
       -- os.exit() 
      end 
      print("Pressed: ", e.key.keysym.scancode, "\n") 
      KEYS[tonumber(e.key.keysym.sym)] = true 
      -- print("Pressed: ", (e.key.keysym.sym == sdl.SDLK_w), "\n"); 
     elseif etype == sdl.SDL_KEYUP then 
      KEYS[tonumber(e.key.keysym.sym)] = false 
     elseif etype == sdl.SDL_VIDEORESIZE then 
      -- print("video resize W:".. e.resize.w .. " H:" .. e.resize.h) 
      width = e.resize.w 
      height = e.resize.h 
      onResize() 
     end 
    end 
    return true -- everything ok 
end 

funzione Update:

if KEYS[sdl.SDLK_w] == true then 
    rot = rot + 1 
end 

più tempo ho sprecato su questo:

KEYS[tonumber(e.key.keysym.sym)] = false 

Poiché FFI restituisce un oggetto DatiC, che è stato utilizzato come il tasto matrice, ma ha bisogno il numero intero.

Problemi correlati