与MouseMotionEvent
相反,MouseWheelEvent
不提供鼠标位置(字段x
和y
用于水平和垂直滚动)。
SDL提供SDL_GetMouseState()
来检索当前鼠标位置,但它不在同一坐标系中表示:
SDL_Event event;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION: {
int x, y;
SDL_GetMouseState(&x, &y);
printf("event=(%d, %d) state=(%d, %d)\n",
event.motion.x, event.motion.y, x, y);
}
}
}
当我移动鼠标时,它会输出如下内容:
event=(700, 184) state=(479, 126)
event=(702, 175) state=(480, 120)
event=(706, 168) state=(485, 111)
看起来运动事件是相对于纹理或渲染器(在窗口中缩放和居中)表示的,而状态是相对于窗口表示的,以像素为单位。
有没有办法让当前鼠标状态与鼠标事件中填充的位置匹配?
我最终通过手动转换坐标:
void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int *y) {
SDL_Rect viewport;
float scale_x, scale_y;
SDL_RenderGetViewport(renderer, &viewport);
SDL_RenderGetScale(renderer, &scale_x, &scale_y);
*x = (int) (*x / scale_x) - viewport.x;
*y = (int) (*y / scale_y) - viewport.y;
}
我用这个函数来转换鼠标状态坐标:
SDL_Event event;
while (SDL_WaitEvent(&event)) {
switch (event.type) {
case SDL_MOUSEMOTION: {
int x, y;
SDL_GetMouseState(&x, &y);
convert_to_renderer_coordinates(&x, &y);
printf("event=(%d, %d) state=(%d, %d)\n",
event.motion.x, event.motion.y, x, y);
}
}
}
现在,他们匹配:
event=(1033, 14) state=(1033, 14)
event=(1034, 13) state=(1034, 13)
event=(1034, 11) state=(1036, 10) // this is racy, state already has a new position
event=(1036, 10) state=(1036, 10)
处理滚轮事件时(而不是生成滚轮事件时)捕获鼠标位置,因此它很活泼。但我认为使用当前的API无法做得更好。