Реализовать алгоритм имитации пламени. Для вычисления цвета текущего пиксела использовать усредненное значение цветов окружающих пикселей. Реализация алгоритма сводится к выводу на экран текущего кадра пламени хранящемся в массиве. Каждый элемент данного массива формируется следующим образом: берется сумма всех окружающих его элементов и делится на их количество (в приведенном ниже примере, количество точек равно четырем, но при их росте пропорционально увеличивается качество цвета точки). Также, ввиду формирования массива снизу вверх, усреднение суммы дает нужное нам затухание. Как результат мы получаем точку пламени на экране. Порядок действий: #include <stdio.h> #include <conio.h> #include <dos.h> #include <time.h> #include <stdlib.h> #define GROWING // небольшое возгорание #define MAX_GROW 150 #define VGA_SCREEN 0xa000 #define VIDEO_INT 0x10 #define VGA_MODE 0x13 // 320x200, 256 цветов #define TEXT_MODE 0x03 #define DAC_WRITE_INDEX 0x03c8 #define DAC_DATA_REG 0x03c9 #define ESC_KEY 27 #define PALETTE_SIZE 256*3 #define V_WIDTH 80 // 80*4=320 #define V_HEIGHT 50 // 50*4=200 #define BUF_HEIGHT 80 #define BUF_WIDTH 80 unsigned char far *screen; // указатель на экран(320x200) int buf[BUF_HEIGHT][BUF_WIDTH]; // буфер // палитра char palette[PALETTE_SIZE]={ 0, 0, 0, 0, 0, 24, 0, 0, 24, 0, 0, 28, 0, 0, 32, 0, 0, 32, 0, 0, 36, 0, 0, 40, 8, 0, 40, 16, 0, 36, 24, 0, 36, 32, 0, 32, 40, 0, 28, 48, 0, 28, 56, 0, 24, 64, 0, 20, 72, 0, 20, 80, 0, 16, 88, 0, 16, 96, 0, 12, 104, 0, 8,112, 0, 8,120, 0, 4,128, 0, 0, 128, 0, 0,132, 0, 0,136, 0, 0,140, 0, 0, 144, 0, 0,144, 0, 0,148, 0, 0,152, 0, 0, 156, 0, 0,160, 0, 0,160, 0, 0,164, 0, 0, 168, 0, 0,172, 0, 0,176, 0, 0,180, 0, 0, 184, 4, 0,188, 4, 0,192, 8, 0,196, 8, 0, 200, 12, 0,204, 12, 0,208, 16, 0,212, 16, 0, 216, 20, 0,220, 20, 0,224, 24, 0,228, 24, 0, 232, 28, 0,236, 28, 0,240, 32, 0,244, 32, 0, 252, 36, 0,252, 36, 0,252, 40, 0,252, 40, 0, 252, 44, 0,252, 44, 0,252, 48, 0,252, 48, 0, 252, 52, 0,252, 52, 0,252, 56, 0,252, 56, 0, 252, 60, 0,252, 60, 0,252, 64, 0,252, 64, 0, 252, 68, 0,252, 68, 0,252, 72, 0,252, 72, 0, 252, 76, 0,252, 76, 0,252, 80, 0,252, 80, 0, 252, 84, 0,252, 84, 0,252, 88, 0,252, 88, 0, 252, 92, 0,252, 96, 0,252, 96, 0,252,100, 0, 252, 100, 0,252, 104, 0,252,104, 0,252,108, 0, 252, 108, 0,252, 112, 0,252,112, 0,252,116, 0, 252, 116, 0,252, 120, 0,252,120, 0,252,124, 0, 252, 124, 0,252, 128, 0,252,128, 0,252,132, 0, 252, 132, 0,252, 136, 0,252, 136, 0,252, 140, 0, 252, 140, 0,252, 144, 0,252, 144, 0,252, 148, 0, 252, 152, 0,252, 152, 0,252, 156, 0,252, 156, 0, 252, 160, 0,252, 160, 0,252, 164, 0,252, 164, 0, 252, 168, 0,252, 168, 0,252, 172, 0,252, 172, 0, 252, 176, 0,252, 176, 0,252, 180, 0,252, 180, 0, 252, 184, 0,252, 184, 0,252, 188, 0,252, 188, 0, 252, 192, 0,252, 192, 0,252, 196, 0,252, 196, 0, 252, 200, 0,252, 200, 0,252, 204, 0,252, 208, 0, 252, 208, 0,252, 208, 0,252, 208, 0,252, 208, 0, 252, 212, 0,252, 212, 0,252, 212, 0,252, 212, 0, 252, 216, 0,252, 216, 0,252, 216, 0,252, 216, 0, 252, 216, 0,252, 220, 0,252, 220, 0,252, 220, 0, 252, 220, 0,252, 224, 0,252, 224, 0,252, 224, 0, 252, 224, 0,252, 228, 0,252, 228, 0,252, 228, 0, 252, 228, 0,252, 228, 0,252, 232, 0,252, 232, 0, 252, 232, 0,252, 232, 0,252, 236, 0,252, 236, 0, 252, 236, 0,252, 236, 0,252, 240, 0,252, 240, 0, 252, 240, 0,252, 240, 0,252, 240, 0,252, 244, 0, 252, 244, 0,252, 244, 0,252, 244, 0,252, 248, 0, 252, 248, 0,252, 248, 0,252, 248, 0,252, 252, 0, 252, 252, 4,252, 252, 8,252, 252, 12,252, 252, 16, 252, 252, 20,252, 252, 24,252, 252, 28,252, 252, 32, 252, 252, 36,252, 252, 40,252, 252, 40,252, 252, 44, 252, 252, 48,252, 252, 52,252, 252, 56,252, 252, 60, 252, 252, 64,252, 252, 68,252, 252, 72,252, 252, 76, 252, 252, 80,252, 252, 84,252, 252, 84,252, 252, 88, 252, 252, 92,252, 252, 96,252, 252, 100,252, 252, 104, 252, 252, 108,252, 252, 112,252, 252, 116,252, 252, 120, 252, 252, 124,252, 252, 124,252, 252, 128,252, 252, 132, 252, 252, 136,252, 252, 140,252, 252, 144,252, 252, 148, 252, 252, 152,252, 252, 156,252, 252, 160,252, 252, 164, 252, 252, 168,252, 252, 168,252, 252, 172,252, 252, 176, 252, 252, 180,252, 252, 184,252, 252, 188,252, 252, 192, 252, 252, 196,252, 252, 200,252, 252, 204,252, 252, 208, 252, 252, 208,252, 252, 212,252, 252, 216,252, 252, 220, 252, 252, 224,252, 252, 228,252, 252, 232,252, 252, 236, 252, 252, 240,252, 252, 244,252, 252, 248,252, 252, 252 }; void set_mode (int mode); void set_palette (); void init_buf (); // инициализируем буфер void init_buf () { int i=0, j=0; for (; i<BUF_HEIGHT; i++) for (; j<BUF_WIDTH; j++) buf[i][j]=0; } // загружаем палитру void set_palette () { int i; outportb(DAC_WRITE_INDEX, 0); for (i=0; i<PALETTE_SIZE; i++) { palette[i] = palette[i] >> 2; outportb(DAC_DATA_REG, palette[i]); } } // выставляем графический режим void set_mode (int mode) { union REGS regs; regs.x.ax = mode; int86(VIDEO_INT, ®s, ®s); } // огонь... int main () { int i,j,k,l; int d=0,g=0; double v=1; char key = ' '; set_mode(VGA_MODE); set_palette(); randomize(); time_t t; srand((unsigned)time(&t)); init_buf(); // ESC для выхода... while (key != ESC_KEY) { // Преобразовываем буфер(кадр) for(i=1;i<BUF_HEIGHT;i++) for(j=0;j<BUF_WIDTH;j++) { if (j==0) buf[i-1][j]=(buf[i][j]+buf[i-1][BUF_WIDTH-1]+buf[i][j+1]+buf[i+1][j]) / 4; else if (j==(BUF_WIDTH-1)) buf[i-1][j]=(buf[i][j]+buf[i][j-1]+buf[i+1][0]+buf[i+1][j]) / 4; else buf[i-1][j]=(buf[i][j]+buf[i][j-1]+buf[i][j+1]+buf[i+1][j]) / 4; if (buf[i][j] > 11) buf[i][j]= buf[i][j] - 12; else if(buf[i][j] > 3) buf[i][j]= buf[i][j] - 4; else { if(buf[i][j] > 0) buf[i][j]--; if(buf[i][j] > 0) buf[i][j]--; if(buf[i][j] > 0) buf[i][j]--; } } // Новая нижняя граница d=0; for (j=0; j<BUF_WIDTH; j++) { if (random(10) < 5) d = random(2) * 256; buf[BUF_HEIGHT -2][j] = d+g; buf[BUF_HEIGHT -1][j] = d; } #ifdef GROWING g+=int(v); if (g>MAX_GROW) v=-random(2); else if (g==0) v=+random(2); #endif // Выводим текущий кадр на экран... screen = (char far *)MK_FP(VGA_SCREEN, 0); for (i=0; i<V_HEIGHT; i++) for (k=0; k<4; k++) for (j=0; j<V_WIDTH; j++) for (l=0; l<4; l++) { *screen = (unsigned char)buf[i][j]; screen++; } if (kbhit()) key = getch(); } set_mode(TEXT_MODE); return 0; }
Ключевые слова:
огонь пламя эффекты
|
|||||||