· ··--──══[ COOLer issue #1 ]══─---·· ·
ЭФФЕКТ: BLOWS by GELTORN/STORM




                 -=========ЭФФЕКТ: BLOWS=========-


Авторское отступление: Слово "blow" можно перевести как "раздувание"
(применительно  к огню). Я бы назвал этот эффект "Will-o'-the-wisp",
то  есть  "блуждающие огоньки", так как это название больше подходит
для этого эффекта.

Установим палитру так:   0   ->   63
                       черный   зеленый

  Наши  блуждающие  огоньки  -  обыкновенные  спрайты,  точнее, один
спрайт  размером  256x256. Назовем массив, в котором будет храниться
этот  спрайт,  blow.  Как выглядит блуждающий огонек, надеюсь, знают
все.

Формула по которой мы будем рисовать наш огонек выглядит так:
color=max_radius^2/(radius^2+max_radius),
где max_radius - это требуемый радиус огонька, radius - радиус
текущей точки.

  Сущность  этой формулы: смягченная обратная зависимость яркости от
радиуса,  квадраты  радиусов  используются из-за того, что вычислить
квадрат  радиуса  текущей точки намного легче, чем просто радиус (не
надо  извлекать  корень).  Максимальное  значение  цвета ограниченно
числом 63.

Процедура инициализации будет выглядеть так:

...
void initblow()
{
  long c;
  for(long y=0;y<256;y++)
    for(long x=0;x<256;x++)
    {
      c=(16384/((x-128)*(x-128)+(y-128)*(y-128)+128));
      if(c>63) c=63;
      blow[x+(y<<8)]=c;
    }
}
...

  Выводя спрайт на экран, мы обязательно столкнемся с необходимостью
clliping`a, то есть, отсечения кусков спрайта, вылезающих за границы
экрана.  Эта  проблема  решается  довольно  просто. Допустим, что мы
начинаем выводить спрайт на экран с точки, координаты которой dx,dy.
Тогда процедура вывода спрайта будет выглядеть так:

...
void drawblow(long dx,long dy)
{
  long c,s;
  long minx=0;
  if(dx<0) minx=-dx;
  long miny=0;
  if(dy<0) miny=-dy;
  long maxx=320-dx;
  if(maxx>255) maxx=255;
  long maxy=200-dy;
  if(maxy>255) maxy=255;
  for(long y=miny;y<maxy;y++)
    for(long x=minx;x<maxx;x++)
    {
      s=(x+dx)+((y+dy)<<6)+((y+dy)<<8);
      c=screen[s]+blow[x+(y<<8)];
      if(c>63) c=63;
      screen[s]=c;
    }
}
...

  Идея  эффекта  заключается  в том, что при выводе точки спрайта на
экран  мы  суммируем  цвет  точки  экрана  и  спрайта,  и  результат
записываем  в  экранную  точку.  Естественно,  если  сумма  > 63, то
результат  должен  быть  равен  63,  иначе  мы  вылезем  за  границу
используемой   части   палитры.  Собственно  сам  эффект  получается
автоматически,  самое  сложным  было  выдумать формулу по которой мы
рисуем наш Will-o'-the-wisp.

Bye...
                                                  ---(Geltorn/Storm)


