C语言 在SDL中将鼠标位置设置为(0,0)

bvn4nwqk  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(83)

我的目标是在窗口中间有一个红色的方块,当我按下它时,只要我按住鼠标按钮,它就应该给予我鼠标的位置。当我释放鼠标按钮时,它不应该再给予我坐标。问题是在我的代码中,它给了我正确的位置,但随后说鼠标位置是(0,0)可能有300次。然后它再次给我正确的更新位置,然后300次(0,0)。输出可能如下所示:

Mouse press detected!
Mouse position is (0, 0)
Mouse position is (0, 0)
Mouse position is (0, 0)
Mouse position is (0, 0)

字符串
...

Mouse position is (0, 0)
Mouse position is (0, 0)
Mouse position is (391, 207)
Mouse released!


这是一个点击鼠标按钮。这是为什么?下面是我的代码:

#include <stdio.h>
#include <SDL.h>

#define WIDTH 760
#define HEIGHT 480

void moveRectangle(SDL_Event myEvent, SDL_Rect* pButton, SDL_Renderer* pRenderer) {

  if (myEvent.motion.x >= 330 && myEvent.motion.x <= 430 && myEvent.motion.y >= 190 && 
     myEvent.motion.y <= 290) {
     while (myEvent.type != SDL_MOUSEBUTTONUP) {
        SDL_PollEvent(&myEvent);
        printf("Mouse position is (%d, %d)\n", myEvent.motion.x, myEvent.motion.y);
     }
    printf("Mouse released!\n");
  }
} 

int main(int argc, char** args) {

   int running = 1;

   SDL_Window* window;
   SDL_Rect myButton;
   SDL_Renderer* myRenderer;
   SDL_Event event;

   myButton.x = 330;
   myButton.y = 190;
   myButton.w = 100;
   myButton.h = 100;

   SDL_Init(SDL_INIT_VIDEO);

   window = SDL_CreateWindow("Events", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 
   WIDTH, HEIGHT, 0);
   myRenderer = SDL_CreateRenderer(window, -1, 0);

   SDL_SetRenderDrawColor(myRenderer, 255, 0, 0, 0);
   SDL_RenderFillRect(myRenderer, &myButton);

   SDL_RenderPresent(myRenderer);

   while (running) {
      SDL_PollEvent(&event);
       switch (event.type) {
          case SDL_MOUSEBUTTONDOWN: printf("Mouse press detected!\n"); 
                moveRectangle(event, &myButton, myRenderer); break;
          case SDL_MOUSEBUTTONUP: printf("Mouse release detected!\n"); break;
          case SDL_MOUSEMOTION: printf("Mouse movement detected!\n"); break;
          case SDL_QUIT: printf("Exiting...\n"); running = 0;  break;
       }
    }

   SDL_DestroyRenderer(myRenderer);
   SDL_Quit();

   return 0;
}

xcitsw88

xcitsw881#

当在您定义的区域内按下鼠标按钮时,程序将进入moveRectangle并停留在那里,直到释放鼠标按钮。在这里,您调用了SDL_PollEvent,但没有检查返回的事件类型,因此访问myEvent.motion可能是未定义的行为。此外,您没有检查SDL_PollEvent的返回值,该返回值告诉您是否发生了事件。解决这两个问题,您的代码应该可以正常工作:

void moveRectangle(SDL_Event myEvent, SDL_Rect* pButton, SDL_Renderer* pRenderer) {
    if (!(myEvent.motion.x >= 330 && myEvent.motion.x <= 430 && myEvent.motion.y >= 190 && myEvent.motion.y <= 290)) {
        return;
    }

    while (myEvent.type != SDL_MOUSEBUTTONUP) {
        if (SDL_PollEvent(&myEvent) && myEvent.type == SDL_MOUSEMOTION) {
            printf("Mouse position is (%d, %d)\n", myEvent.motion.x, myEvent.motion.y);
        }
    }
    printf("Mouse released!\n");
}

字符串
然而,拥有另一个事件循环并不是一个特别好的主意。例如,在该函数中无法正确退出程序,因为您不再响应SDL_QUIT事件。
我不需要输入一个单独的函数来执行任何您需要的操作(阅读函数的名称,我假设您希望能够拖动一个矩形),我只需要设置一个标志来指示用户在矩形内按下了鼠标按钮,并且尚未释放它。就像这样:

int draggingRectangle = 0;
while (running) {
    if (SDL_PollEvent(&event)) {
        switch (event.type) {
        case SDL_MOUSEBUTTONDOWN:
            printf("Mouse press detected!\n"); 
            draggingRectangle = (
                myEvent.motion.x >= 330 &&
                myEvent.motion.x <= 430 &&
                myEvent.motion.y >= 190 &&
                myEvent.motion.y <= 290
            );
            break;
        case SDL_MOUSEBUTTONUP:
            printf("Mouse release detected!\n");
            draggingRectangle = 0;
            break;
        case SDL_MOUSEMOTION:
            printf("Mouse movement detected!\n");
            if (draggingRectangle) {
                printf("Mouse position is (%d, %d)\n", myEvent.motion.x, myEvent.motion.y);
            }
            break;
        case SDL_QUIT:
            printf("Exiting...\n");
            running = 0;
            break;
        }
    }
}

相关问题