【问题标题】:SDL - Why moving the mouse changes button state?SDL - 为什么移动鼠标会改变按钮状态?
【发布时间】:2013-08-09 16:40:29
【问题描述】:

我在使用 Simple Directmedia Layer 库时遇到问题。以下代码在按下鼠标按钮时在屏幕上绘制一个块:

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 不真实?

如何同时使用两者(即按下按钮时继续绘图)?

【问题讨论】:

    标签: c sdl


    【解决方案1】:

    您的代码的问题是您调用了两次SDL_PollEvent(记录在here)。如文档中所述:

    如果 event 不为 NULL,则从队列中删除下一个事件并 存储在 event 指向的 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);
    }
    

    【讨论】:

      【解决方案2】:

      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

      【讨论】:

      • 感谢您的回复。我不明白为什么它会影响结构的其他部分。您能否提供一个在按下鼠标时绘制块的代码示例?我更新了代码。
      【解决方案3】:

      感谢 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);
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2022-01-09
        • 1970-01-01
        • 1970-01-01
        • 2018-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-06
        相关资源
        最近更新 更多