Копирование с обрезкой и листы спрайтов
Листы спрайтов это коллекции картинок, хранящиеся в одном файле изображения. Они полезны когда у вас есть большое количество изображений, но вы не хотите иметь дело с большим количеством файлов. Для того, чтоы получить индивидуальное изображение, вы должны быть в состоянии вырезать нужную часть при копировании. В этом уроке у нас есть лист спрайтов с четырьмя разными спрайтами с изображением точки на них. Далее мы рассмотрим как вырезать отдельные спрайты из листа.
//Поверхности
SDL_Surface *dots = NULL;
SDL_Surface *screen = NULL;
//Структура события
SDL_Event event;
//Части карты спрайтов для копирования
SDL_Rect clip[ 4 ];
Тут у нас несколько глобальных переменных. Поверхность экрана и структура для событий с которой мы недавно знакомились. Также у нас есть поверхность dots
, которая является листом спрайтов, содержащим четыре спрайта точек. Также там у нас есть массив из четырех SDL_Rect
. Они хранят смещения и измерения спрайтов с точками.
void apply_surface(
int x,
int y,
SDL_Surface* source,
SDL_Surface* destination,
SDL_Rect* clip = NULL
) {
//Смещение
SDL_Rect offset;
//Получить смещение
offset.x = x;
offset.y = y;
//Скопировать
SDL_BlitSurface( source, clip, destination, &offset );
}
Это наша функция копирования, но с небольшими корректировками.
Новый аргумент типа SDL_Rect
по имени clip
определяет прямоугольный кусок поверхности, который мы хотим скопировать. Значени аргумента по умолчанию устанавливается в NULL
, что означает, что
apply_surface( 0, 0, image, screen, NULL );
и
apply_surface( 0, 0, image, screen );
делают одно и тоже. Мы также изменяем способ вызова SDL_BlitSurface()
. Мы больше не устанавливаем второй аргумент в NULL
, теперь мы передаем туда аргумент clip
.
Теперь SDL_BlitSurface()
будет копировать область поверхности источника, определенную в прямоугольнике clip
. Если clip
равен NULL
, значит будет скопирована вся поверхность источника.
//Clip range for the top left
clip[ 0 ].x = 0;
clip[ 0 ].y = 0;
clip[ 0 ].w = 100;
clip[ 0 ].h = 100;
//Clip range for the top right
clip[ 1 ].x = 100;
clip[ 1 ].y = 0;
clip[ 1 ].w = 100;
clip[ 1 ].h = 100;
//Clip range for the bottom left
clip[ 2 ].x = 0;
clip[ 2 ].y = 100;
clip[ 2 ].w = 100;
clip[ 2 ].h = 100;
//Clip range for the bottom right
clip[ 3 ].x = 100;
clip[ 3 ].y = 100;
clip[ 3 ].w = 100;
clip[ 3 ].h = 100;
В функции main
после того, как все инициализировано и файлы загружены, мы устанавливаем координаты прямоугольников для вырезания. Мы собираемся взять этот спрайт:и установить прямоугольники для вырезания по определенным областям:Как-то так. Теперь мы готовы копировать отдельные спрайты с листа.
//Залить экран белым цветом
SDL_FillRect(
screen,
&screen->clip_rect,
SDL_MapRGB( screen->format, 0xFF, 0xFF, 0xFF )
);
Тут мы заполняем экран белым цветом, при помощи SDL_FillRect()
. SDL_FillRect()
принимает поверхность первым аргументом и заполняет область указанную во втором аргументе цветом, указанным в третьем. Область во втором аргументе это прямоугольник самой поверхности или, проще говоря, вся поверхность целиком.
//Скопировать поверхности на экран
apply_surface( 0, 0, dots, screen, &clip[ 0 ] );
apply_surface( 540, 0, dots, screen, &clip[ 1 ] );
apply_surface( 0, 380, dots, screen, &clip[ 2 ] );
apply_surface( 540, 380, dots, screen, &clip[ 3 ] );
//Обновить экран
if( SDL_Flip( screen ) == -1 ) {
return 1;
}