Отображение из std :: vector и обработка событий с использованием SDL?

0

Я пытаюсь создать собственную библиотеку приложений с SDL кроме академического проекта, и у меня возникла проблема.

В принципе, все работает нормально, компилируется, делает то, что я ожидаю от него, но... его очень медленно, первый элемент реагирует довольно быстро, другие элементы в наборе полностью не отвечают (мне нужно нажимать их 20 раз для чтобы реагировать, они работают очень медленно)

Ниже функции, которая рисует элементы из контейнера векторного типа, возврат 1 означает, что функция дескриптора столкнулась с непредвиденной ошибкой или пользователь X'ed из окна.

Любые советы о том, как это сделать быстрее?

void StoreDraw::setCamera(size_t input)
{
    rectangle.x = containerArray[input].elementLocX;
    rectangle.y = containerArray[input].elementLocY;
    rectangle.h = containerArray[input].elementPicture->h;
    rectangle.w = containerArray[input].elementPicture->w;
}

bool StoreDraw::vectorDraw()
{
    /* Draw FloatingElements */
    for(size_t i = 0; i < containerArray.size(); i++)
    {
        if(SDL_PollEvent(&event))//containerArray[i].event
        {
            if(event.type == SDL_MOUSEBUTTONDOWN)
            {
                 if(event.button.button == SDL_BUTTON_LEFT)
                 {
                    locationX = event.button.x;
                    locationY = event.button.y;
                    printf("X:%d\tY:%d\n", locationX, locationY);
                    if(!containerArray[i].handleEvent(locationX, locationY)){drawEnvironment();}
                }
            }
            if(event.type == SDL_QUIT)
            {
                return 1;
            }
        } 
    }
    SDL_Flip(screen);
    return 0;
}

bool StoreDraw::drawEnvironment()
{
    SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0,0,0));
    SDL_BlitSurface(background, NULL, screen, NULL);

    for(size_t i = 0; i < containerArray.size(); i++)
    {
        setCamera(i);
        SDL_BlitSurface(containerArray[i].elementPicture, NULL, screen, &rectangle);
    }

    SDL_Flip(screen);
}

bool FloatingElement::handleEvent(int x, int y)
{
    printf("Object responding.\n");
    if((x > elementLocX) && (x < (elementLocX + (elementPicture->w))) && (y > elementLocY) && (y < (elementLocY + (elementPicture->h))))
    {
        x = (x - (elementPicture->w)/2);
        y = (y - (elementPicture->h)/2);
        setLocation(x,y);
        printf("Object responding.\n");
        return 0;
    }
    return 1;
}
  • 0
    Вопрос недостаточно ясен. Можете ли вы добавить больше деталей? Также я бы предложил использовать SDL2, это намного быстрее.
  • 0
    Вы возвращаетесь, как только получаете событие. Как насчет отслеживания счетчика цикла и продолжения с того места, где вы остановились, вместо того, чтобы начинать с 0 каждый раз.
Показать ещё 2 комментария
Теги:
vector
sdl

1 ответ

0

Насколько я вижу, проблема в том, как часто вы проверяете события. Когда вы вызываете vectorDraw(), он опрашивает события и действует так, как предполагалось, но события заканчиваются и функция возвращается. Я думаю, что в коде должен быть основной цикл, который всегда проверяет события и вызывает функции, когда необходимо, в то время как vectorDraw() проверяет только местоположение щелчка и вызывает handleEvent() массива контейнеров.

Редактировать: Я думаю, что нашел проблему. Вот как вы сейчас это делаете:

bool StoreDraw::vectorDraw()
{
    /* Draw FloatingElements */
    for(size_t i = 0; i < containerArray.size(); i++)
    {
        if(SDL_PollEvent(&event))//containerArray[i].event
        {
            if(event.type == SDL_MOUSEBUTTONDOWN)
            {
                 if(event.button.button == SDL_BUTTON_LEFT)
                 {
                    // Check Events
                 }
            }
            if(event.type == SDL_QUIT)
            {
                return 1;
            }
        } 
    }
    SDL_Flip(screen);
    return 0;
}

int main() {
     while( ::quit == false ) {
            while(SDL_PollEvent(&event) == 1) {
                if( event.type != SDL_QUIT ) {
                if( event.type == SDL_MOUSEBUTTONDOWN) {
                storeDraw::vectorDraw();
                }
                } else {
                quit = true;
                    break;
                }
            }
        }
    }
}

Итак, что происходит: после того, как основной цикл опроса события, он вызывает vectorDraw() и vectorDraw() снова вызывает события. Таким образом, vectorDraw() не получает информацию о клике, который он назвал, поскольку он уже был опрошен в основном цикле. Без информации он не действует. Итак, чтобы решить проблему, вы можете изменить функции следующим образом:

bool StoreDraw::vectorDraw(SDL_Event event)
{
    /* Draw FloatingElements */
    for(size_t i = 0; i < containerArray.size(); i++)
    {
        // Check Events
    }
    SDL_Flip(screen);
    return 0;
}

int main() {
     while( ::quit == false ) {
            while(SDL_PollEvent(&event) == 1) {
                if( event.type != SDL_QUIT ) {
                if( event.type == SDL_MOUSEBUTTONDOWN) {
                        if(event.button.button == SDL_BUTTON_LEFT)
                        {
                    storeDraw::vectorDraw(event);
                        }
                }
                } else {
                quit = true;
                    break;
                }
            }
        }
    }
}

Теперь только основной цикл опроса событий и действует на них, если это возможно. И vectorDraw() больше не опросает их, действует только на них, если они соответствуют критериям (в этом случае в левой руке слева). Теперь проверка событий должна действовать по назначению.

  • 0
    Мое плохое, я не сказал это ясно, в главной функции есть главный цикл. Я думал, что это само за себя. Сначала я создаю объекты в главном классе, затем добавляю их к вектору и затем запускаю цикл, который длится очень долго, пока пользователь X не выйдет из окна. Основная функция после краткого процесса подготовки (настройка sdl и т. Д.) Будет затем постоянно запускать функцию vectorDraw.
  • 0
    Итак, я увидел ваш комментарий и провел несколько тестов с кодом, довольно похожим на ваш, и обнаружил вашу проблему: после нажатия основной цикл вызывает vectorDraw (), чтобы он мог получить местоположение вашего щелчка и действовать соответствующим образом, но щелчок Событие уже опрошено, поэтому vectorDraw () не может снова его опросить и будет действовать только в тех кликах, которые следуют быстро после. Чтобы устранить проблему, вместо создания событий опроса vectorDraw () вы должны передать ему событие, содержащее информацию о щелчках. Я отредактирую ответ, чтобы уточнить это.
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню