How to get smoother inputs in SDL?

Started by
1 comment, last by Kylotan 6 years, 9 months ago
Quote

I am making a Tetris clone using SDL. I have made a class for input, and in the past this has worked fine for me. But I do not think it is suited for what i am doing because all my inputs are laggy. The basic code is this:



int main(int argc, char* argv[]) {
	Input input;
	int game_timer = 2000;
	while(true){
	bool a;
	bool d;
	if(game_timer > 200){
		string event = input.check_event();
			if(event == "a_d"){
				a = true;
			}else if(event == "d_d"){
				d = true;
			}else if(event == "a_u"){
				a = false;
			}else if(event == "d_u"){
				d = false;
			}

		if(a == true){
			tet_left() //moves tetrimino  to the left
		}	
	
		if(d == true){
			tet_right() //Moves tetrimino to the right
		}

		move_tet_down() //Moves tetrimino down
		draw_tet() //Draws the tetrimino
		
		game_timer = 0;
	}

	game_timer++;

}

WIth my input class being:



string Input::check_event() {
	while (SDL_PollEvent(&event)) {
		if (event.type == SDL_KEYDOWN) {
			switch (event.key.keysym.sym) {
			case SDLK_a:
				return "a_d";
			case SDLK_d:
				return "d_d";
			case SDLK_e:
				return "space_d";
			case SDLK_RETURN:
				return "e_d";
			}
		} else if (event.type == SDL_KEYUP) {
			switch (event.key.keysym.sym) {
			case SDLK_a:
				return "a_u";
			case SDLK_d:
				return "d_u";
			case SDLK_e:
				return "e_u";
			}
		} else if (event.type == SDL_QUIT) {
			return "quit";
		}
	}

	return "nothing";
}

Please note this is example code. 

I believe the issue is that I am drawing the tetrimino after if moves, so it only appears so move to the side after it moves down. But drawing it right after the player moves the block doesnt help either so any ideas are appreciated. 

 

Advertisement

The problem is that you will only ever check for events every 200 steps, and then your input class will hang until it gets an event. If there's an event in the queue, it'll get handled immediately - but if there were 2 events in the queue, the next one won't get handled until 200 steps later... and so on.

Generally speaking you shouldn't wrap the event handling inside your Input class, because events can technically cover more than input. It should be handled as part of your main loop. I would advise you to change your system to use a more standard game loop, like the following, and then it should be easier to add the functionality you need.


// PSEUDOCODE
int main()
{
    while (true)
    {
        // First, handle all events
        SDL_Event event;
        while (SDL_Pollevent(&event))
        {
            Input.HandleEvent(event);
            if (event.type == SDL_QUIT) {
                return; // quit game
            }
        }

        // Now update your game, in case there are things
        // that Input can't or shouldn't change directly
        UpdateEverything();
        
        // Now draw everything in its latest state
        DrawEverything();
    }
}

For a deeper understanding, read this article: http://gameprogrammingpatterns.com/game-loop.html for a general overview of different game loops, and there's an SDL-specific example here: http://lazyfoo.net/articles/article04/index.php

 

This topic is closed to new replies.

Advertisement