Программирование игр для Windows. Советы профессионала


Спрайты - часть 5


Если пиксель

// "непрозрачный" - выводим его на экран.

if ((data=work_sprite[work_offset+x])) video_buffer[offset+xj = data;

} // конец вывода строки

// перейти к следующему ряду пикселей в видеобуфере

//в буфере

спрайта

offset      += SCREEN_WIDTH;

work_offset += SPRITE_WIDTH;

} // коней вывода спрайта

} // конец функции

Эта функция работает примерно так же, как и Plot_Pixel_Fast из Листинга 5.5. Сначала вычисляется стартовый адрес расположения спрайта, а затем все его байты строка за строкой переписываются в видеобуфер.

Следует учесть, что здесь потребуется некоторая оптимизация. Почему бы не использовать функцию memcpy, чтобы копировать всю строку разом (а всего 24 строки)? Однако этого сделать нельзя, так как при выводе спрайта нам необходимо применить технику, использующую "прозрачные" пиксели. Что это дает? Взгляните на рисунок 5.12.

 

Спрайт слева выведен вместе с фоном, а при рисовании правого спрайта использовалась техника «прозрачных» пикселей. При этом пиксели с цветом фона (черный, имеющий код 0) пропускались, а прорисовывались только данные непосредственного изображения. Это и создает эффект «прозрачности» фона.

Следующая функция, которую я собираюсь вам предложить, будет сохранять фон перед тем, как мы выведем спрайт на экран. Помните, когда мы что-то записываем в видеобуфер, данные или образ, находящийся там, обязательно теряются. Поэтому мы и должны сохранять фон под спрайтом прежде чем поместим его в видеобуфер, чтобы позже восстановить прежний вид экрана. Код в Листинге 5.14 именно это и делает.

Листинг 5.14. Сохранение фона под спрайтом.

void Behind_Sprite(sprite_ptr sprite)

{ // функция сохраняет область видеопамяти, в которую будет

// выводиться

спрайт

char far *work_back;

in work_offset=0,offset,y;

// создаем альтернативный указатель для ускорения доступа

work_back = sprite->background;

// вычисляем смещение в видеобуфере

offset = (sprite->y << 8) + (sprite->y << 6) + sprite->x;


for (y=0; y<SPRITE_HEIGHT; y++)

{

// копируем строку видеопамяти в буфер

_fmemcpy((char far *)&work_back[work_offset], (char far *)&video_buffer[offset], SPRITE_WIDTH);

// переходим к следующей строке

offset    += SCREEN_WIDTH;

work_offset += SPRITE_WIDTH;

} // конец цикла for

} // конец функции

Функция Behind_Sprite считывает матрицу размером 24х24, где должен находится спрайт. Данные после считывания находятся в поле background структуры спрайта. Это поле является указателем на область памяти, где находится спрайт.

Собственно, это все, что нам нужно для создания и перемещения маленьких образов по экрану. Для анимации мы должны изменять поле curr_frame в структуре спрайта, перед тем, как его начать рисовать. Мы обсудим процесс анимации в этой главе, но, я думаю, вы и сами догадываетесь, как это сделать: надо стереть спрайт, передвинуть его, снова нарисовать и т. д. Вот и все.




Начало  Назад  Вперед