SDL2 «пропускает» кадры, когда мышь не двигается - PullRequest
0 голосов
/ 02 мая 2019

Я пытаюсь сделать анимацию с помощью SDL2. У SDL2 плохая производительность, и моя простая игра в шахматы работала со скоростью 10 кадров в секунду.

Я не хочу перерисовывать весь экран каждые кадры, это занимает много времени. Поэтому, чтобы оптимизировать свою игру, я решил написать код класса Animation (простой эффект постепенного появления / исчезновения), который перерисовывает только некоторую часть экрана в каждом кадре (в основном, перерисовывает выбранную часть)


void myGame::sdlLoop() {
    SDL_Event events;
    bool quit = false;


    while (!quit) {
        bool redraw = false; //We assume we don't want to redraw everything (yet)
        while (SDL_PollEvent(&events)) {
            switch (events.key.keysym.scancode) {
                ....

            }
            if(redraw) draw(); // Only redraw whole screen IF NEEDED
            else drawAnimations(); // Better use that for better performance
        }
    }
}

void myGame::drawAnimations(){

    int i = 0;
    while(i < arr.size()){
        ....
        drawThingsAtCertainsPixels(now_time, animation_start_time, animation_duration); //Basicly a simple fade effect, something like
                     //pixelColor = color1 * advancement + color2 * (1 - advancement) 
    }


    // Show the window
    SDL_RenderPresent( m_renderer );
}

Пока все хорошо, но я заметил странное поведение. Анимация "отрывистая", большинство кадров пропущено Я закончил тем, что все мои затухания были незаконченными, потому что последний кадр пропущен. Но , когда я постоянно перемещаю мышь, все идет как надо, и ни один кадр не сбрасывается

Я думаю, что это связано с тем, что SDL хочет оптимизировать производительность, и работает только на 100% скорости, когда происходит что-то важное (пользователь вводит вещи или взаимодействует с окнами).

Знаете ли вы, почему это происходит, и как это исправить? Я имею в виду, как заставить SDL2 вычислять каждый кадр, даже если я не двигаю мышь.

1 Ответ

0 голосов
/ 02 мая 2019

Я чувствую себя немного виноватым за то, что нашел решение сразу после публикации этого вопроса (но клянусь, я много рвал на себе волосы)

Решение довольно простое

while (!quit) {
    bool redraw = false; //We assume we don't want to redraw everything (yet)
    while (SDL_PollEvent(&events)) {
        switch (events.key.keysym.scancode) {
            ....
        }
        if(redraw) draw(); // Only redraw whole screen IF NEEDED
        else drawAnimation(); // Better use that for better performance
    }
}

Просто переместите функцию drawAnimations () немного ниже, время от времени (SDL_PollEvent (& events)) {

while (!quit) {
    bool redraw = false; //We assume we don't want to redraw everything (yet)
    while (SDL_PollEvent(&events)) {
        switch (events.key.keysym.scancode) {
            ....
        }
    }
    if(redraw) draw(); // Only redraw whole screen IF NEEDED
    else drawAnimation(); // Better use that for better performance
}

...