Уроки по SDL 2: Урок 15 Многопоточность и Тиллинг

от автора

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

Приступим к коду:

static int TestThread(void *ptr) {    SDL_Window *gWindow = SDL_CreateWindow("gamesBond",0,0,300,300,SDL_WINDOW_SHOWN); ;   SDL_Surface *imageThreadSurface = SDL_LoadBMP("hw.bmp");     int cnt;   SDL_Surface *windowSurface = SDL_GetWindowSurface(gWindow); SDL_BlitSurface(imageThreadSurface,NULL, windowSurface,NULL); SDL_UpdateWindowSurface( gWindow );     for (cnt = 0; cnt < 10; ++cnt) {         printf("Thread counter: %d\n", cnt);         SDL_Delay(50);     }        SDL_Delay(4000);     SDL_FreeSurface(windowSurface);     SDL_FreeSurface(imageThreadSurface);     SDL_DestroyWindow(gWindow);     return cnt; } 

Эта функция будет нашим вторым потоком, она создает окно(gWindow), подгружает изображения в(imageThreadSurface), подключаем windowSurface к нашему окну, и в него выводим изображение.

После этого выводим в консоль числа от 1 до 9, и добавляем 4 секунды ожидания,
и закрываем окно.

void writeMap(int *i,SDL_Renderer* gRenderer, SDL_Surface* mapSurface) {  int yMap = 0;int xMap = 0;  int xSize = 80; int ySize = 80;  SDL_Rect coubPositionRect = {xMap,yMap,xSize,ySize};  SDL_Rect coubColorRect = {xMap,yMap,xSize,ySize };   SDL_Texture* mapTexture = SDL_CreateTextureFromSurface(gRenderer,mapSurface);  SDL_RenderClear;   while (xMap < 640)   {     if ( *i == REDSQUARE ) {                coubColorRect.x = 0;        coubColorRect.y = 0;     }else if ( *i == GREENSQUARE ) {                    coubColorRect.y = 80;          coubColorRect.x = 0;     }else if ( *i == BLUESQUARE ) {                         coubColorRect.y = 160;         coubColorRect.x = 0;     }else if ( *i == BLACKLEFTMID ) {                  coubColorRect.y = 80;         coubColorRect.x = xSize;     }else if ( *i == BLACKLEFTTOP ) {          coubColorRect.y = 0;         coubColorRect.x = 80;      }else if ( *i == BLACKLEFTBOT ) {          coubColorRect.x = 80;         coubColorRect.y = 160;     }else if (*i == BLACKRIGHTTOP) {                  coubColorRect.x = 240;         coubColorRect.y = 0;         }else if (*i == BLACKRIGHTMID) {          coubColorRect.x = 240;         coubColorRect.y = 80;     }else if (*i == BLACKRIGHTBOT) {          coubColorRect.x = 240;         coubColorRect.y = 160;     }      coubPositionRect.x = xMap;     coubPositionRect.y = yMap;     SDL_RenderCopy(gRenderer,mapTexture,&coubColorRect,&coubPositionRect);      yMap+=ySize;     if (yMap>=480) {     xMap+=xSize;         yMap = 0;     }      i++;   }    SDL_RenderPresent(gRenderer);   return; } 

Из этого маленького изображения и массива чисел от 0 до 8, мы отрисуем полноценную карту, через функцию, описанную выше, хоть она и большая, в ней нет ничего сложного, она принимает массив, переменную отображения, и изображение, находит соответствие между числом и квадратом на картинке, и отрисовывает его последовательно.

int main(void) {    int mWidth = 640, mHeight = 480;     SDL_Init(SDL_INIT_VIDEO);   SDL_Window* window = SDL_CreateWindow("tilling",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,mWidth,mHeight,SDL_WINDOW_SHOWN);   SDL_Renderer* gRenderer = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED);    SDL_Surface* imageSurface = IMG_Load("tiles.png");   SDL_Texture* imageTexture = SDL_CreateTextureFromSurface(gRenderer,imageSurface);   SDL_Rect imageRect = {0,0,80,80};    SDL_Event e;   SDL_RenderCopy(gRenderer,imageTexture,&imageRect,&imageRect);   SDL_RenderPresent(gRenderer);    int quit = 0;   int *k; k =(int*)calloc(50,4);   int threadReturnValue;    readData(k); 

Стандартно задаем окно, подгружаем мини изображение, объявляем массив k.

И заполняем этот массив цифрами из файла readData(k), которые будут эквивалентом цвета квадратов на карте.

 writeMap( k, gRenderer, imageSurface);   free(k);

Отображаем в окне(window). нашу карту через функцию(writeMap)
освобождаем память массива k

  SDL_Thread *thread;   thread = SDL_CreateThread(TestThread,"testMultiThread",(void *)NULL);    SDL_WaitThread(thread, &threadReturnValue);

Создаем второй поток, SDL_CreateThread принимает три переменные, первая это функция(TestThread), вторая это имя потока, и третья данные подставляемые в функцию, в нашем случае это NULL.

Запускаем наш поток через SDL_WaitThread и результат функции записываем в переменную threadReturnValue

    SDL_RaiseWindow(window);    SDL_ShowWindow(window);      SDL_RenderPresent(gRenderer);   untilPressKey (quit, e); 

Первая функция SDL_RaiseWindow выводит окно поверх всех окон, вторая функция SDL_ShowWindow, показывает окно, если оно скрыто отображаем изображение и запускаем функцию выхода из приложения untilPressKey:

  SDL_FreeSurface(imageSurface);   SDL_DestroyTexture(imageTexture);    SDL_RenderClear(gRenderer);   SDL_DestroyWindow(window);   SDL_Quit(); 

предыдущие уроки 1-7
предыдущие уроки > 7

ссылка на файлы


ссылка на оригинал статьи https://habr.com/ru/articles/584846/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *