Я пытаюсь создать собственную библиотеку приложений с 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;
}
Насколько я вижу, проблема в том, как часто вы проверяете события. Когда вы вызываете 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() больше не опросает их, действует только на них, если они соответствуют критериям (в этом случае в левой руке слева). Теперь проверка событий должна действовать по назначению.