SDL - 为什么移动鼠标更改按钮状态?

时间:2013-08-08 11:03:28

标签: c sdl

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

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

3 个答案:

答案 0 :(得分:3)

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

  

如果event不为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);
}

答案 1 :(得分:0)

event.button.state有点掩饰。它被声明为char,它可以容纳8位代表按钮的不同状态。

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

答案 2 :(得分: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);
    }
}