Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Листинг 7.11. Трехмерный астероид (AFIELD.С)// ВКЛЮЧАЕМЫЕ ФАЙЛЫ //////////////////////////////////////// #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" // включаем нашу графическую библиотеку // ОПРЕДЕЛЕНИЯ///////////////////////////////////////////// #define NUM_STARS 30 // СТРУКТУРЫ /////////////////////////////////////////////// typedef struct star_typ { int x,y; // позиция звезды int vel; // скорость звезды по координате х int color; // цвет звезды } star,*star_ptr; // ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ /////////////////////////////////// star stars[NUM_STARS]; // звездное поле sprite object; pcx_picture ast_cells; // функции /////////////////////////////////////////// void Star_Field(void) { static int star_first=1; // Эта функция создает трехмерное звездное поле int index; // проверяем, следует ли нам создать звездное поле, //то есть первый ли раз вызвана функция if (star_first) { // обнуляем флаг первого вызова star_first=0; // инициализируем все звезды for (index=0; index<NUM STARS; index++) { // инициализируем для каждой звезды позицию, скорость и цвет stars[index].х = rand()%320; stars[index].у = rand()%180; // определяем плоскость звезды switch(rand()%3){ case 0: // плоскость 1 - самая далекая { // установка скорости и цвета stars[index].vel = 2; stars[index].color.= 8; } break; case 1: // плоскость 2 - среднее расстояние { stars[index].vel = 4; stars[index].color = 7; ) break; case 2://плоскость 3 - самая близкая { stars[index].vel = 6; stars[index].color = 15; } break; } // конец оператора switch } // конец цикла //конец оператора if else { // это не первый вызов, поэтому делаем рутинную работу - // стираем, двигаем, рисуем for (index=0; index<NUM_STARS; index++) { if ((stars[index].x+=stars[index].vel) >=320) stars[index].x = 0; // рисуем Plot_Pixel_Fast_D(stars[index].x,stars[index].y, stars[index].color); } // конец цикла } // конец оператора else } // конец Star_Field //////////////////////////////////////////////////////////// void Scale_Sprite(sprite_ptr sprite,float scale) { // эта функция масштабирует спрайт, рассчитывая число дублирования // исходных пикселей, необходимое для получения требуемого размера char far *work_sprite; int work_offset=0,offset,x,у; unsigned char data; float y_scale_index,x_scale_step,y_scale_step,x_scale_index; // берем первый пиксель исходного изображения y_scale_index = 0; // рассчитываем дробный шаг y_scale_step = sprite_height/scale; x_scale_step = sprite_width /scale; // для простоты даем указателю на спрайт новое имя work_sprite = sprite->frames[sprite->curr_frame]; // расчет смещения спрайта в видеобуфере offset = (sprite->y << 8) + (sprite->y << 6) + sprite->x; // построчно масштабируем спрайт for (у=0; y<(int) (scale); у++) { // копируем следующую строчку в буфер экрана x_scale_index=0; for (x=0; x<(int)scale; x++) { // проверка на прозрачность пикселя //(то есть равен ли он 0), если нет - прорисовываем пиксель if ((data=work_sprite[work_offset+(int)x_scale_index])) double_buffer[offset+x] = data; x_scale_index+=(x_scale_step); } // конец цикла по X //используя дробный шаг приращения определяем // следующий пиксель исходного изображения у_scale_index+=y_scale_step; // переходим к следующей строке видеобуфера //и растрового буфера спрайта offset += SCREEN_WIDTH; work_offset = sprite_width*(int)(y_scale_index); } // конец цикла по Y } // конец Scale Sprite //////////////////////////////////////////////////////////// void Clear_Double_Buffer(void) { // эта функция очищает дублирующий буфер // несколько грубо, зато работает _fmemset(double_buffer, 0, SCREEN_WIDTH * SCREEN_HEIGHT + 1); } // конец Clear_Double_Buffer // ОСНОВНАЯ ПРОГРАММА /////////////////////////////////////// void main(void) { int index, done=0,dx=5,dy=4,ds=4; float scale=5; // установка видеорежима 320х200х256 Set_Mode(VGA256); // установка размера спрайта sprite_width = sprite_height = 47; // инициализация файла PCX, который содержит // мультипликационные кадры PCX_Init((pcx_picture_ptr)&ast_cells); // загрузка файла PCX, который содержит мультипликационные кадры PCX_Load("asteroid.рсх", (pcx_picture_ptr)&ast_cells,1); // резервируем память под дублирующий буфер Init_Double_Buffer(); Sprite_Init((sprite_ptr)&object,0,0,0,0,0,0); // загрузка кадров вращающегося астероида PCX_Grap_Bitmap((pcx_picture_ptr)&ast_cells, (sprite_ptr)&object,0,0,0); PCX_Grap_Bitmap ((pcx_picture_ptr) &ast_cells, (sprite_ptr)&object,1,1,0}; PCX_Grap_Bitmap((pcx_picture_ptr)&ast_cells, (sprite_ptr)&object,2,2,0); PCX_Grap_Bitmap((pcx_picture_ptr)&ast_cells, (sprite_ptr)&object,3,3,0); PCX_Grap_Bitmap ((pcx_picture_ptr) &ast_cells, (sprite_ptr)&object,4,4,0); PCX_Grap_Bitmap((pcx_picture_ptr)&ast_cells, (sprite_ptr)&object,5,5,0); PCX_Grap_Bitmap((pcx_picture_ptr)&ast_cells, (sprite_ptr)&object,6,0,1); PCX_Grap_Bitmap({pcx_picture_ptr)&ast_cells, (sprite_ptr)&object,1,1,1); // позиционирование объекта в центре экрана object.curr_frame =0; object.x = 160-(sprite width>>1); object.у = 100-(sprite_height>>1); // очистка дублирующего буфера Clear_Double_Buffer(); // вывол масштабированного спрайта Scale_Sprite((sprite_ptr)&object,scale); Show_Double_Buffer(double_buffer); // главный цикл while (!kbhit()) { // масштабируем астероид scale+=ds; // не слишком ли велик или мал астероид? if (scale>100 |1 scale < 5) { ds=-ds; scale+=ds; } // конец if // перемещаем астероид object.x+=dx; object.y+=dy; // коснулся ли астероид края экрана? if ((object.x + scale) > 310 || object.x < 10) { dx=-dx; object.x+=dx; } // конец if if ((object.у + scale) > 190 || object.у < 10) { dy=-dy; object.y+=dy; } // конец if // поворот астероида на 45 градусов if (++object.curr_frame==8) object.curr_frame=0; // очистка дублирующего буфера Clear_Double_Buffer(); // прорисовка звезд Star_Field(); // масштабируем спрайт и выводим его в дублирующий буфер Scale_Sprite((sprite_ptr)&object,scale); // выводим дублирующий буфер на экран Show_Double_Buffer (double_buffer); } // конец оператора while // удаляем файл PCX PCX_Delete ((pcx_picture_ptr) &ast_cells); // возврат в текстовый режим Set_Mode (TEXT_MODE); } // конец функции main Итог В этой главе мы затронули много тем, относящихся к серьезной работе с растровой графикой и специальными визуальными эффектами, но, самое главное, мы впервые в этой книге начали разговор о том, как сделать так, чтобы игрок получил от вашей игры удовольствие. Я думаю, многие программисты уже забыли, что это такое, променяв его на мегабайты оцифрованного звука и графики. Поэтому не будем забывать об удовольствии!
|