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

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

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

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

Комментарии (0)