0

我在使用 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不真实?

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

4

3 回答 3

4

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

如果 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);
}
于 2013-08-09T03:55:13.587 回答
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

于 2013-08-08T11:14:14.470 回答
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);
    }
}
于 2013-08-09T08:21:32.443 回答