В этом уроке мы научимся запускать программу в несколько потоков, создавать полноценные уровни из мини изображения, так же научимся открывать несколько окон, скрывать и выводить вперед.
Приступим к коду:
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();
ссылка на оригинал статьи https://habr.com/ru/articles/584846/
Добавить комментарий