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

       

Гаснущее изображение


Этот эффект уже много лет пользуется популярностью у программистов, потому что получить его фантастически легко — для этого требуется всего несколько строк кода.

По существу мы медленно уменьшаем значение всех регистров цвета до тех пор, пока они не достигнут нуля. Как мы узнали в этой главе в разделе «Освещение ваших игр», лучше всего сохранять эквивалентный баланс цветов, для чего надо пропорционально увеличивать или уменьшать интенсивность каждого цвета. Однако в случае данного эффекта действие разворачивается так быстро, что цвета разобрать сложно, поэтому о цветовом балансе можно не беспокоиться.

Поэтому программа, приведенная в Листинге 7.9 просто уменьшает каждый компонент каждого цвета в пяти регистрах до тех пор, пока все три компонента — красный, зеленый и синий — не становятся равными нулю. На этом функция завершается.

Исчезновение Изображения

Этого замечательного эффекта можно достичь вообще одной строчкой. Я вам продемонстрирую ее через минуту.

Данный эффект достигается за счет образования черных дыр в пикселях изображения на экране. Все что надо сделать, это последовательно нанести на экран случайным образом тысячи черных точек. Так как экран содержит последнее изображение (комнаты, пейзажа или чего-нибудь еще), прорисовка этих черных точек приведет к тому, что создастся эффект растворения картинки в воздухе,

Здесь приведены две самые короткие строчки кода, которые мне удалось придумать:

for (index=0; index<=300000; index++)

Plot_Pixel_Fast(rand()%320, rand()%200, 0);

Этот код просто размещает 300000 черных пикселей по всему экрану. Почти наверняка такое большое количество пикселей разрушит все изображение на экране. (Мы могли бы рассчитать точное количество итераций, но это заняло бы лишнее время. Число 300000 выглядит вполне приемлемым.)

Этот эффект может быть использован для замены одного экрана другим, если в нем использовать не черные пиксели, а пиксели новой картинки, случайным образом выбирая их координаты Х и Y.

Оплывание изображения






Этот эффект появился в игре DOOM и быстро распространился по другим играм. Мой вариант не столь впечатляющий. Однако, этого и следовало ожидать, ведь я потратил на него всего 15 минут.

Таяние изображения осуществляется благодаря движению сверху вниз с разной скоростью 160 маленьких «червячков» под влиянием силы тяжести. И .Когда "червячки" движутся вниз, они поедают пиксели. Через некоторое время большинство из них достигает низа и растворение заканчивается. (Я подозреваю, Что и в DOOM использовалась подобная техника. Таким образом, каждая вертикальная лента масштабируется вместо простого стирания пикселей.)

Демонстрация смены экрана

Гаснущие, исчезающие и растворяющиеся изображения — все они выглядят неплохо. Здесь приведена программа, которая позволяет увидеть эти эффекты в действии.

Листинг 7.9. Эффекты экрана (SCREENFX.C).

// ВКЛЮЧАЕМЫЕ ФАЙЛЫ ////////////////////////////////////////

#include <io.h>

#include <conio.h>

#include <stdio.h>

#include <stdlib.h>

#include <dos.h>

#include <bios.h>

#include <fcntl.h>

#include <memory.h>

#include <malloc.h>

#include <math.h>

#include <string.h>

#include "graph0.h" // включаем нашу графическую библиотеку

// СТРУКТУРА.///////////////////////////////////////////////

typedef struct worm_typ

{

int у;       // текущая Y-координата "червячка"

int color;   // цвет "червячка"

int speed;   // скорость "червячка"

int counter; // счетчик

}, worm, *worm_ptr;

// ГЛОБАЛЬНЫЕ

ПЕРЕМЕННЫЕ

///////////////////////////////////

unsigned int far *clock = (unsigned int far *)0x0000046C;

// указатель на внутренний таймер 18.2 "тик"/с

pcx_picture screen_fx; // наш

тестовый экран

worm worms[320]; // используется при оплывании экрана              

//ФУНКЦИИ /////////////////////////////////////////////////      

void Timer(int clicks)

{

// эта функция использует внутренний таймер с частотой 18.2 "тик"/с



// 32- битовое значение этого таймера имеет адрес 0000:046Ch

unsigned int now;

// получим текущее время

now = *clock;

// Ожидаем до истечения указанного периода времени.

// Заметьте, что каждый "тик" имеет длительность примерно в 55 мс

while(abs(*clock - now) < clicks){}

} // конец Timer ////////////////////////////////////////////////////////////

void Fade_Lights (void)

{ // эта функция гасит свет, медленно уменьшая значения цветов

// во всех цветовых регистрах

int index,pal_reg;

RGB_color color,color_1,color_2,color_3;

for (index=0; index<30; index++)

{

for (pal_reg=l; pal_reg<255; pal_reg++)

{

// получить затемняемый цвет

Get_Palette_Register(pal_reg,(RGB_color_ptr)&color) ;

if (color.red > 5) color.red-=3;

else

color.red = 0;

if (color.green > 5) color.green-=3;

else

color.green = 0;

if (color.blue  > 5) color.blue-=3;

else

color.blue = 0;

// уменьшить интенсивность цвета

Set_Palette_Register(pal_reg,(RGB_color_ptr)&color) ;

} // конец внутреннего цикла

// немного подождем

Timer(2);

} // конец внешнего цикла } // конец Fade_Lights

///////////////////////////////////////////////////////////

void Disolve(void)

{

// "растворение" экрана рисованием биллиона черных пикселей

unsigned long index;

for (index=0; index<=300000; index++, Plot_Pixel_Fast(rand()%320, rand()%200, 0));

} // конец Disolve

//////////////////////////////////////////////////////////

void Melt(void)

{

// Функция "оплавляет" экран, двигая маленьких "червячков"

// с разной скоростью вниз по экрану. Эти "червячки" меняют

// на своем пути цвет пикселей.

int index,ticks=0;

// инициализация "червячков"

for (index=0; index<160; index++)

{

worms[index].color   = Get_Pixel(index,0);

worms[index].speed   = 3 + rand()%9;

worms[index].у       =0;

worms[index].counter = 0;

// прорисовка "червячка"

Plot Pixel_Fast((index<<1), 0, (char) worms [index].color);



Plot_Pixel_Fast((index<<1), 1, (char) worms [index].color);

Plot_Pixel_Fast((index<<1), 2, (char) worms [index].color) ;

Plot_Pixel_Fast((index<<1) + l,0, (char) worms [index].color) ;

Plot_Pixel_Fast((index<<1) + 1,1, (char) worms [index].color) ;

Plot_Pixel_Fast((index<<1) + 1,2, (char) worms [index].color);

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

// плавим экран

while(++ticks<1800)

{

// работа "червячков"

for (index=0; index<320; index++)

{

// пора подвинуть "червячка"

if (++worms[index].counter == worms[index].speed)

{

// обнуляем счетчик

worms[index].counter = 0;

worms[index].color = Get_Pixel(index,worms[index],y+4);

// достиг "червячок" низа экрана?

if (worms[index].у < 193)

{ Plot_Pixel_Fast ((index<<1), worms [index] .y, 0) ;

Plot Pixel Fast ((index<<3.),worms [index] .y+1,

(char)worms[index].color);

Plot_Pixel_Fast ( (index<<1) ,worms [index] .y+2,

(char)worms[index].color);

Plot Pixel Fast ((index<<1),worms [index] .y+3,

(char)worms[index].color) ;

Plot Pixel Fast ( (index<<1) +1,worms [index] .y, 0) ;

Plot_Pixel_Fast( (index<<1)+1,worms [index] .y+1,

(char)worms[index].color);

Plot Pixel Fast ( (index<<1)+l,worms [index] .y+2,

(char)worms[index].color);

Plot_Pixel_Fast ( (index<<1)+1,worms [index] .y+3,

(char)worms[index].color);

worms[index].y++;

} // конец оператора if

} // конец оператора if

} // конец цикла // ускоряем плавление

if (!(ticks % 500))

{

for (index=0; index<160; index++) worms[index].speed--;

} // конец оператора if

} // конец оператора while

} // конец Melt

// ОСНОВНАЯ ПРОГРАММА //////////////////////////////////////

void main(void)

(

int index,

done=0,

sel;

// установка видеорежима 320х200х256

Set_Mode(VGA256);

PCX_lnit((pcx_picture_ptr)&screen_fx) ;

PCX_Load("war.pcx", (pcx_picture_ptr)&screen_fx,1);

PCX_Show_Buffer((pcx_picture_ptr) &screen_fx);

PCX_Delete((pcx_picture_ptr)&screen_fx);

_settextposition(22,0);

printf('1 - Fade Lights.\n2 - Disolve.\n3 - Meltdown.");

// какой эффект хочет увидеть игрок? switch(getch())

{

case '1': // гаснущий экран {

Fade_Lights();

} break;

case '2': // растворяющийся экран {

Disolve();

} break;                  

case '3': // оплывающий экран {

Melt(};

} break;

} //конец оператора switch

// возврат в текстовый режим

Set_Mode(TEXT_MODE) ;

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


Содержание раздела