Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 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

Итог

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

Поэтому не будем забывать об удовольствии!



Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.014 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал