Гра Більярд

Автор: Пользователь скрыл имя, 03 Апреля 2012 в 23:00, курсовая работа

Описание работы

Дана курсова робота є прикладом реалізації завдання про гру в більярд, написаної із застосуванням об'єктно-орієнтованого програмування на мові високого рівня С++.

Содержание

Вступ
1. Опис моделі більярду
2. Основні класи моделі
2.1. Клас CRect (прямокутник)
2.2. Клас CWall (стінка більярдного столу)
2.3. Клас CHole (луза більярдного столу)
2.4. Клас CBall (більярдна шкуля)
3. Реалізація динамічної поведінки моделі
Висновки
Список літератури

Работа содержит 1 файл

Курсова.doc

— 91.00 Кб (Скачать)


 

Міністерство освіти і науки молоді та спорту України

Закарпатський державний університет

 

Факультет інформаційних технологій

Кафедра програмного забезпечення систем

 

 

Реєстраційний №______

Дата ________________

 

 

 

 

 

 

КУРСОВА РОБОТА

з Об’єктно-орієнтовного програмування

 

Тема: Гра “Більярд”

 

 

 

 

 

Рекомендована до захисту

“____” ____________ 2012р.

Робота захищена

“____” ____________ 2012р.

з оцінкою

_______________________

Підписи членів комісії

Студента 2 курсу             

заочного відділення

Сочки В.В.

Науковий керівник

                                                                                                                  Стойкович О.Р.

 

 

 

Ужгород 2012р.


Зміст

Вступ……………………………………………………………………………….3

1. Опис моделі більярду…………………………………………………………..4

2. Основні класи моделі…………………………………………………………..5

2.1. Клас CRect (прямокутник)………………………………………………….6

2.2. Клас CWall (стінка більярдного столу)…………………………………….8

2.3. Клас CHole (луза більярдного столу)……………………………………..10

2.4. Клас CBall (більярдна шкуля)……………………………………………...13

3. Реалізація динамічної поведінки моделі…………………………………….19

Висновки…………………………………………………………………………23

Список літератури……………………………………………………………….24

 

 

 

 

 

 


Вступ

Дана курсова робота є прикладом реалізації завдання про гру в більярд, написаної із застосуванням об'єктно-орієнтованого програмування на мові високого рівня С++.

Мова програмування C++ була розроблена на основі мови С Бьярном Страуструпом.

Особливість мови С полягає в тому, що будучи мовою високого рівня, вона зберегла багато рис мови низького рівня. Мова С розташована десь між мовами дуже високого рівня і мовами низького рівня, і в цьому її сильні і одночасно слабкі сторони. Як і мова асемблера (мова низького рівня), мова програмування С може безпосередньо керувати пам'ятю комп'ютера. З іншого боку, С має риси мов високого рівня, тому програми на мові С читати і створювати легше, ніж програми на мові асемблера. Мова С є дуже зручним для написання системних програм, але в програмах на мові С для інших цілей часто важче розібратися, ніж в програмах, написаних на інших мовах. Мова С також має менше можливостей для автоматичної перевірки програм, ніж деякі інші мови високого рівня.

В даний час широкого поширення набули реалізації мови в системах Visual C + +, Borland C + + xx, Borland C + + Builder x та ін.

У даній роботі розглядається програма, що імітує рух куль з більярдного столу зі стінками і лузами. Щоб розібратися в цій програмі, треба вивчити лекції по ООП і знати основні методи роботи з бібліотекою OpenGL. OpenGL застосовується в дещо незвичному для ОС Windows виді: як бібліотека двовимірної графіки. Це дозволяє істотно зменшити результатний текст програми в порівнянні з варіантом програми, який для малювання користується функціями Windows API.

Основна увага при розробці програми "Більярд" приділяється створенню автономних агентів, що взаємодіють між собою для досягнення бажаного результату - імітації руху куль з більярдного столу.

1. ОПИС МОДЕЛІ БІЛЬЯРДУ

Програма відображує на екрані вікно,в якому в виді прямокутника зображений більярдний стіл. В його 4-х кутах знаходяться лузи. На столі розташовані 15 синіх куль і 1 біла куля(рис.5.1).

Клацанням лівої кнопки миші в довільній точці столу користувач імітує удар києм по білій кулі,повідомляючи їй деяку початкову швидкість в напрямі курсору миші. Рухома куля пружно відбивається від стінок та інших куль. При рухові по столу кулі втрачають енергію за рахунок тертя і з часом зупиняються. При попаданні в лузу сині кулі видаляються зі столу,а біла куля поміщається в початкову позицію(рис.5.1).
 

Рис. 5.1. Зображення більярдного столу з 4-ма кутовими лузами.

 

 

 


2. ОСНОВНІ КЛАСИ МОДЕЛІ

Основними класами в даній задачі є стінки,лузи и кулі. Об’єктам цих класів приписана деяка екранна область і вони вміють показувати себе всередині цієї області. Будемо називати ці об’єкти  графічними об’єктами. Графічні об’єкти кожного типу зберігаються  в програмі у вигляді зв’язкових списків. Для цього в кожному класі є покажчик на наступний об’єкт списку.

Розміщення посилань всередині об’єктів для об’єднання цих об’єктів в деякий абстрактний тип даних (наприклад,зв’язковий список) вважається поганим стилем програмування. Краще відділити реалізацію АТД від об’єктів,які в ньому зберігаються. Але рішення цієї задачі містить деякі нетривіальні аспекти, які ускладнили б розглянуту програму.

Приймемо спрощене припущення, що всі графічні об’єкти займають прямокутну область. Звичайно, для круглих об’єктів (наприклад, куль і луз) це невірно. Але облік форми об’єктів значно б ускладнив програму. Голові цілі в її вивченні – розгляд способу, за допомогою якого об’єкти наділяються  власною поведінкою і як організована взаємодія об’єктів. Кожен графічний об’єкт не тільки вміє зображати себе, але і може взаємодіяти з іншими об’єктами моделі більярду.

 

 


2.1 Клас CRect (прямокутник)

Клас СRect є допоміжним класом,який призначений для збергання координат прямокутника і виконання деяких операцій з цими координатами. Операції з координатами прямокутників застосовуються при реалізації поведінки графіних об’єктів. Далі наведено об’яву класу,в якому більша частина функцій-членів зроблені вбудованими.

class CRect {

    public :

// Конструктори

CRect()

{ x1 = y1 = x2 = y2 = 0; }

CRect( int nx1, int ny1, int nx2, int ny2 )

{ x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2; }

// Ініціалізація координат прямокутника

void SetRect( int left, int top, int right, int bottom )

{ x1 = left; y1 = top; x2 = right; y2 = bottom; }

// Зміщення прямокутника

void OffsetRect( int dx, int dy )

{ x1 += dx; y1 += dy; x2 += dx; y2 += dy; }

// Отримання координат центру прямокутника

void CenterPoint( int* x, int* y )

{ *x = (x1 + x2)/2; *y = (y1 + y2)/2; }

// Перевірка на збіг координат кутів прямкутника

bool IsRectEmpty()

{ return ( x1 == x2 && y1 == y2 ); }

// Отримання ширини прямкутника

int Width()      { return x2 - x1 + 1; }

// Отримання висоти прямокутника

int Height()     { return y2 - y1 + 1; }

// Функція обчислює перетин об’екту з прямокутником another

CRect IntersectRect( CRect& another );

// Нормалізація координат прямокутника

void NormalizeRect();

// Загальнодоступні атрибути

int x1, y1, x2, y2;

};

Атрибути прямокутника (координати) зроблені загальнодоступним ,так як цей клас дуже простий,не має власної поведінки і нема значної небезпеки від несанкціованої зміни координат.

Будемо називати прямокутник нормалізованим, якщо його координати (х1, у1) і (х2, у2) відповідають лівому верхньому і правому нижньому куту. Таке впорядкування координат спрощує розрахунок перетину прямокутників. Ця операція виконується функцією-членом IntersectRect() і потрібна для відстежування зштовхувань графічних об’єктів.


2.2 Клас CWall (стінка більярдного столу)

Клас СWall оголошується наступним чином:

class CWall {

   public:

CWall ( int left, int top, int right, int bottom,

double cf, CWall* pNextWall );

// Малюнок стінки

void Draw();

// Оповіщення тсінки про те, що в неї попала куля

void HitBy( CBall* pBall );

CRect GetRegion()              { return region; }

CWall* GetLink()               { return pLink; }

   private:

CWall* pLink;

CRect region;                      // Екранні координати стінки

double convertFactor;          // Значення, з якого віднімається

                                             // напрямок вдарившої кулі, щоб

                                             // вийшло зеркальне відображення

};

 

Атрибут  pLink служить для організації зв'язного списку об'єктів CWall. Значення цього атрибуту, а також координати області для малювання стінки і параметр відскоку ініціалізуються в конструкторі:

 

CWall::CWall( int left, int top, int right, int bottom,

double cf, CWall* pNextWall )

{

convertFactor = cf;

region.SetRect( left, top, right, bottom );

pLink = pNextWall;

}

 

Стінка малюється на екрані як суцільний зелений прямокутник. Це робиться за допомогую функцій OpenGL:

 

void CWall::Draw()

{

glColor3ub( 0, 255, 0 );

glRecti( region.x1, region.y1, region.x2, region.y2 );

}

 

Коли в стінку вдаряється куля, то напрям її руху змінюється у відповідності із значенням атрибуту convertFactor. Для горизонтальних стінок convertFactor=0, а для вертикальних convertFactor=Pi. В результаті куля зеркально відображується від стінки :

 

void CWall::HitBy( CBall* pBall )

{             

pBall->SetDirection( convertFactor - pBall->GetDirection() );

}


2.3 Клас CHole (луза більярдного столу)

Нижче приведено оголошення класу CHole:

class CHole {

   public:

CHole (int x, int y, CHole * pNextHole);

/ / Малювання лузи

void Draw ();

/ / Повідомлення лузи про те, що в неї потрапила куля

void HitBy (CBall * pBall);

CRect GetRegion ()      {return region;}

CHole * GetLink ()      {return pLink;}

   private:

CHole * pLink;            / / Покажчик на наступну лузу для утворення

                                    / / зв'язного списку

CRect region;             / / Екранні координати області лузи

};

 

Конструктор і функція-член для малювання лузи влаштовані дуже просто:

CHole :: CHole (int x, int y, CHole * pNextHole)

{

/ / Прямокутник для лузи з центром в точці (x, y)

region.SetRect (x - 5, y - 5, x + 5, y + 5);

pLink = pNextHole;

}

void CHole :: Draw ()

{

/ / Луза малюється у вигляді жовтого кола, вписаного в область            region

glColor3ub (255, 255, 0);

glPointSize ((float) region.Width ());

glEnable (GL_POINT_SMOOTH);

glBegin (GL_POINTS);

int cx, cy;

region.CenterPoint (& cx, & cy);

glVertex2i (cx, cy);

glEnd ();

glDisable (GL_POINT_SMOOTH);

}

 

При попаданні кулі в лузу можливі два варіанти. Якщо куля виявляється білою, то вона повертається на вихідну позицію. В інших випадках куля зупиняється і малюється за межами столу в рядку, призначеної для відображення вибитих куль.

 

void CHole :: HitBy (CBall * pBall)

{

/ / Енергія кулі обнуляється

pBall-> SetEnergy (0.0);

if (pBall-> IsCue ())

pBall-> SetCenter (50, 108);

else

{

pBall-> SetCenter (10 + saveRack * 15, 250);

saveRack + +; / / Збільшення глобального лічильника забитих куль

}

}


2.4 Клас CBall (більярдна шкуля)

Останнім графічним об'єктом є куля, яка визначається наступним описом класу:

class CBall {

   public:

CBall (int x, int y, bool fc, CBall * pNextBall);

/ / Малювання кулі в поточному положенні

void Draw ();

/ / Зміна положення кулі в припущенні, що з моменту

/ / попередньї зміни пройшов одиничний проміжок часу

void Update ();

/ / Повідомлення кулі про те, що в неї потрапила інша куля

void HitBy (CBall * pBall);

/ / Розрахунок кута між віссю OX і напрямком від центру кулі до точки,

/ / зміщеної від центру кулі на (dx, dy)

double HitAngle (double dx, double dy);

/ / Функції-члени для доступу до змінних класу

void SetEnergy (double v)                      {energy = v;}

void SetCenter (int newx, int newy);

void SetDirection (double newDir)        {direction = newDir;};

CRect GetRegion ()                                {return region;}

CBall * GetLink ()                                {return pLink;}

double GetEnergy ()                             {return energy;}

void GetCenter (int * x, int * y);

double GetDirection ()                         {return direction;}

bool IsCue ()                                        {return fCue;}

   private:

CBall * pLink;                  / / Покажчик на наступну кулю зв'язного списку

CRect region;                  / / Екранна область, в яку вписана куля

double direction ;           / / Напрямок руху кулі (кут в радіанах

                                        / / відносно осі OX)

double energy;              / / Енергія кулі

bool fCue;                     / / Ознака білої кулі

};

 

Специфічними для кулі атрибутами є direction (напрям руху), energy (кінетична енергія кулі) і прапор fCue, що дорівнює true для єдиної в моделі білої кулі. Кулі ініціалізувалися координатами центру (подібно лузам), ознакою білої кулі і покажчиком на наступну кулю в списку. Енергія і напрям кулі спочатку дорівнюють нулю.

CBall :: CBall (int x, int y, bool fc, CBall * pNextBall)

{

SetCenter (x, y);

SetDirection (0);

SetEnergy (0.0);

pLink = pNextBall;

fCue = fc;

}

 

На екрані куля малюється у вигляді кола білого або синього кольору. Відображення виконує функція-член Draw ().

void CBall :: Draw ()

{

if (IsCue ())

glColor3ub (255, 255, 255);        / / Білий колір

else

glColor3ub (0, 0, 255);               / / Синій колір

glPointSize ((float) region.Width ());

glEnable (GL_POINT_SMOOTH);

glBegin (GL_POINTS);

int cx, cy;

region.CenterPoint (& cx, & cy);

glVertex2i (cx, cy);

glEnd ();

glDisable (GL_POINT_SMOOTH);

}

 

Функція-член Update () використовується для зміни положення кулі через одиничний проміжок часу, що пройшов з моменту попереднього виклику цієї функції. Якщо куля володіє достатньою енергією, то вона переміщується і потім провіряє, чи не зачепила вона інший об'єкт. Якщо хоча б одна куля на столі зрушилася, то глобальна змінна-прапор fBallMoved встановлюється рівною true. Якщо куля зачепила інший об'єкт, то куля повідомляє про це об'єкту. Повідомлення бувають трьох типів: вони відповідають ударам по лузі, стінці й іншій кулі.

void CBall :: Update ()

{

/ / Для руху у кулі повинна бути деяка кінетична енергія

if (energy <= 0.5)

return;

fBallMoved = true;

/ / На кожному кроці енергія кулі зменшується за рахунок тертя

energy - = 0.05;

/ / Зміщення кулі обчислюється з урахуванням квадратичної залежності

/ / кінетичної енергії від швидкості. Константа 2.0 обрана для

/ / забезпечення більш-менш реалістичного руху куль

int dx = (int) (2.0 * sqrt (energy) * cos (direction));

int dy = (int) (2.0 * sqrt (energy) * sin (direction));

region.OffsetRect (dx, dy);

 

/ / Перевірка на потрапляння в лузу

CHole * hptr = listOfHoles;

while (hptr)

{

CRect is = region.IntersectRect (hptr-> GetRegion ());

if (! is.IsRectEmpty ())

Информация о работе Гра Більярд