It’s fine to do one “action” per frame, but try to think of the mouse motion events as a sequence; the motion events are telling you a story of where the mouse has been, not just the start point and the end point for the frame. Even worse, somewhere buried in that story there was a click and a release, and where the click happened and where it was released change the meaning of the story.
What I mean is that there’s a lot of information that needs to be polled and then ignored, especially for a turn-based program. A single action will likely consist of many events. You can’t really just grab the first event and flush the rest because you would capture only a fragment of the whole story. You need to sift through and purposefully grab the important relevant information.
Here’s an example where I’m showing hover state and mouse-down states of a grid. Even though I am polling all possible events in the event loop, I am only processing the events that are important to the program.
#include <SDL2/SDL.h>
int main()
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window * win = SDL_CreateWindow("Title", 10, 10, 500, 500, SDL_WINDOW_SHOWN);
SDL_Renderer * screen = SDL_CreateRenderer(win, -1, SDL_RENDERER_PRESENTVSYNC);
SDL_Rect cell = {0, 0, 32, 32};
SDL_Point mousePos;
bool mouseDown = false;
bool showTile = false;
bool run = true;
while(run)
{
SDL_Event ev;
while(SDL_PollEvent(&ev))
{
switch(ev.type)
{
case SDL_MOUSEMOTION:
// this will run multiple times per frame
// but I only care where the end points are per frame.
// So I'll just over-write the variable.
// In this case, mousePos represents the end state of the mouse.
mousePos = {ev.motion.x, ev.motion.y};
break;
case SDL_MOUSEBUTTONDOWN:
mouseDown = true;
break;
case SDL_MOUSEBUTTONUP:
mouseDown = false;
break;
case SDL_QUIT:
run = false;
break;
}
}
// Update section, check state of the mouse and act on that data
if(!SDL_PointInRect(&mousePos, &cell))
{
// the mouse has moved far enough to initiate an action.
cell.x = mousePos.x - (mousePos.x % cell.w);
cell.y = mousePos.y - (mousePos.y % cell.h);
}
showTile = false;
if(mouseDown)
{
// show tile is my example of an "action" (sorry it's not an impressive action)
showTile = true;
}
// drawing section
SDL_SetRenderDrawColor(screen, 120, 10, 20, 255);
SDL_RenderClear(screen);
SDL_SetRenderDrawColor(screen, 200, 200, 200, 255);
SDL_RenderDrawRect(screen, &cell);
if(showTile)
{
SDL_RenderFillRect(screen, &cell);
}
SDL_RenderPresent(screen);
}
SDL_Quit();
}