2013-08-08 2 views
0

У меня проблема с библиотекой Simple Directmedia Layer. Следующий код рисует блок на экране при нажатии кнопки мыши:SDL - Зачем нужно перемещать состояние кнопки мыши?

SDL_Event event; 
while(running){ 
    while(SDL_PollEvent(&event)){ 
     while(event.button.state == SDL_PRESSED){ 

      SDL_PollEvent(&event); 

      //where to draw     
      boxRect.x = event.motion.x; 
      boxRect.y = event.motion.y; 

      //Draw to screen 
      SDL_FillRect(display,&boxRect,boxColor); 
      SDL_Flip(display); 
     } 
     // ... 
    } 
    // ... 
} 

Он работает отлично, пока я не перемещаю мышь, почему перемещая мышь делаешь event.button.state неверны?

Как я могу работать с обоими одновременно (т. Е. Продолжать рисовать при нажатии кнопки)?

ответ

3

Проблема с кодом является то, что вы звоните SDL_PollEvent (документированный here) дважды. Как сказано в документации:

Если событие не NULL, то следующее событие удаляется из очереди и хранится в структуре SDL_Event указывает событие.

Перегруппировка кода немного, как избавиться от второго SDL_PollEvent, создавая правильный поток для нажатия, перемещения, освобождения и извлечения рендеринга из входной накачки должны дать вам что-то вроде этого:

SDL_Event Event; 
while(running) 
{ 
    while(SDL_PollEvent(&Event)) 
    { 
     switch(Event.type) 
     { 
      // Handle your drawing with a simple state machine: 
      case SDL_MOUSEBUTTONDOWN: 
      { 
       if(Event.button.button == SDL_BUTTON_LEFT) 
       { 
        if(stateMachine == Released) 
        { 
         // ... begin drawing 
         stateMachine = Dragging 
        } 
       } 
       break; 
      } 
      case SDL_MOUSEMOTION: 
      { 
       if(stateMachine == Dragging) 
       { 
        // ... update the extends of your rect 
       } 
      } 
      case SDL_MOUSEBUTTONUP: 
      { 
       if(Event.button.button == SDL_BUTTON_LEFT) 
       { 
        if(stateMachine != Released) 
        { 
         // ... finalize drawing... add the rect to a list? flush it? 
         stateMachine = Released; 
        } 
       } 
      } 
      case SDL_QUIT: 
      { 
       running = false; 
       break; 
      } 
     } 
    } 

    // Outside of your event pumping, update the graphics 
    SDL_FillRect(display,&boxRect,boxColor); 
    SDL_Flip(display); 
} 
0

event.button.state - немного маска. Он объявлен как char, который может содержать восемь бит, представляющих различные состояния кнопок.

typedef struct{ 
    Uint8 type; 
    Uint8 state; 
    Uint16 x, y; 
    Sint16 xrel, yrel; 
} SDL_MouseMotionEvent; 

Больше информации здесь,

http://www.libsdl.org/docs/html/sdlgetmousestate.html http://www.libsdl.org/docs/html/sdlmousemotionevent.html

+0

Спасибо, что ответили. Я не понимаю, почему это влияет на другие части структуры. Не могли бы вы привести пример кода, который бы нарисовал блок, пока мышь нажата? Я обновил код. – 2013Asker

0

Благодаря ответу emartel, он работает, как ожидалось, вот код:

SDL_Event event; 
int drawing = 0; 

while(running){ 
    while(SDL_PollEvent(&event)){ 
     switch(event.type){ 

      //starts drawing when any mouse button is pressed 
      case SDL_MOUSEBUTTONDOWN: 
       drawing = 1; 
       boxRect.x = event.button.x; 
       boxRect.y = event.button.y; 
      break; 


      //keeps drawing while no button is released 
      case SDL_MOUSEMOTION: 
       if(drawing == 1){ 
        boxRect.x = event.motion.x; 
        boxRect.y = event.motion.y; 
       } 
      break; 


      //stops drawing when any button is released 
      case SDL_MOUSEBUTTONUP: 
       drawing = 0; 
      break; 


      case SDL_QUIT: 
       running = 0; 
      break; 

     } 

    } 

    //draws to screen 
    if(drawing == 1){ 
     SDL_FillRect(display,&boxRect,boxColor); 
     SDL_Flip(display); 
    } 
} 
Смежные вопросы