Читайте также:
|
|
void Draw_Sprite_Clip(sprite_ptr sprite)
{
// Эта функция рисует спрайт на экране и отсекает области,
// выходящий за границы экрана. Функция написана в
// демонстрационных целях.
char far *work_sprite;
int work_offset=0,offset,x_off,x,y,xs,ys,xe,ye, clip_width, clip_heigth;
unsigned char data;
// Получить указатель на спрайт
xs=sprite->x;
ys=sprite->y;
// Расчет координат прямоугольника, описывающего спрайт
xe=xs+sprite_width-1;
ye=ys+sprite_height-1;
// Проверка полной невидимости спрайта
// (то есть лежит ли он полностью за пределами экрана)
if((xs>=SCREEN_WIDTH) || (ys>==SCREEN HEIGHT) | |
(xs<=(-sprite_width))||(ys<=(-sprite_height)))
{
return;
} // конец оператора if
// Спрайт частично видим, следовательно, необходимо
// рассчитать рисуемую область
// Отсечение по координате Х
if(xs<0)
xs=0;
else
if(xe>=SCREEN_WIDTH) xe=SCREEN_WIDTH-l;
//Отсечение по координате Y
if(ys<0)
уs=0;
else
if(ye>=SCREEN_HEIGHT) ye=SCREEN_HEIGHT-1;
// Расчет новой высоты и ширины
clip_width=xe-xs+l;
clip height=ye-ys+l;
// Расчет рабочего смещения на основе нового начального
// значения координаты Y
work_offset=(sprite->y-ys)*sprite_width;
x_off=(xs-sprite->x);
// Построение усеченного спрайта
// Для упрощения дадим указателю на спрайт новое имя
work_sprite = sprite->frames[sprite->curr_frame];
// Расчет смещения,спрайта в видеобуфере
offset = (ys<< 8) + (ys<< 6) + sprite->xs;
for (y=0; y<clip_height; y++)
{
// Копируем следующую строку в видеобуфер
for (х=0; x<clip_width; x++)
(
// Проверка пикселя на "прозрачность" (то есть на 0);
// если пиксель "непрозрачный" - рисуем
if ((data=work_sprite[work_offset+x+x_off]))
double_buffer[offset+x+x_off] = data;
} // конец цикла по X
// Переход к следующей строке в видеобуфере
// и в растровом буфере спрайта
offset += SCREEN_WIDTH;
work_offset += sprite_width;
} // конец цикла по У
} // конец функции
Как и к двум первым листингам этой главы, к Листингу 7.3 надо относиться достаточно скептически. Эта программа, конечно, делает то, что ей и положено, однако не учитывает при этом контекста. А контекст — это все! Например, в вашей игре все картинки могут располагаться посередине. Тогда в отсечении у вас просто отпадет необходимость. Возможно, ваш объект всегда будет двигаться по горизонтали, в этом случае не потребуется выполнять вертикальное отсечение и вы сможете провести оптимизацию части предварительной обработки. Иными словами, всегда пытайтесь создавать ваши функции для конкретной ситуации и для определенной игры. В данном случае передо мной стояла несколько иная задача — объяснить вам суть проблемы. Если вы поняли идею, то, потратив определенное время и силы, найдете свое правильное решение.
Контроль столкновения спрайтов
Часто бывает нужно проверить, не произошло ли в нашей игре столкновение двух или более спрайтов. Контроль столкновения между спрайтами не сложнее контроля столкновений между астероидом и кораблем. Эту тему мы обсуждали в четвертой главе. Чтобы выяснить это, достаточно посмотреть, имеются ли общие точки хотя бы у одной из четырех границ спрайта с другой областью. Алгоритм 7.2 исполняет подобный тест.
Дата добавления: 2015-07-12; просмотров: 107 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Алгоритм 7.1. Тест видимости объекта. | | | Алгоритм 7.2. Тест столкновения спрайтов. |