50119 (609936), страница 3

Файл №609936 50119 (Система координат канви) 3 страница50119 (609936) страница 32016-07-30СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 3)

Refresh; } }

void TCue->Draw()

{ int x1, y1, x2, y2, x3, y3;

Brush->Color = clYellow;

Pen->Color = clYellow;

Pen->Width = 4;

x1 = Trunc(ToBall->x+cos(Angle)*(ToBall->R+energy));

y1 = Trunc(ToBall->y+sin(Angle)*(ToBall->R+energy));

x2 = Trunc(ToBall->x+cos(Angle)*(ToBall->R+CueLength+energy));

y2 = Trunc(ToBall->y+sin(Angle)*(ToBall->R+CueLength+energy));

x3 = Trunc(ToBall->x-cos(Angle)*1000);

y3 = Trunc(ToBall->y-sin(Angle)*1000);

MoveTo(x1, y1);

LineTo(x2, y2);

Pen->Width = 1;

Brush->Color = clWhite;

Pen->Color = clWhite;

Ellipse(x1-2,y1-2,x1+2,y1+2);

if(ShowLine )

{ Pen->Style = psDash;

MoveTo(x1, y1);

LineTo(x3, y3);

Pen->Style = psSolid; } } }

void TBall->Stop;

{ dx = 0;

dy = 0;

stopped = true; }

bool TBall::InLose(){

int Number;

int i;

pLose lz;

boolean inLz;

Result = False;

if(! exist ) exit;

for( i = 0; i Lose->Count-1; i ++)

{ lz = BilliardTable->Lose->Items[i];

inLz = sqrt(sqr(x-lz->x)+sqr(y-lz->y)) R;

if(inLz )

{ Number = i;

Result = True;

inc(InLoses);

Exit; } } }

pBall TBall->CollisedWith();

{ int j;

pBall bb;

real d, delta, ddx, ddy;

Result = NULL;

if(! exist ) exit;

for( j = 0; j Ball->Count-1; j ++)

{ bb = BilliardTable->Ball->Items[j];

if(! bb->exist ) continue;

if(bb->ID == ID ) continue;

d = sqrt(sqr(x-bb->x)+sqr(y-bb->y));

if((d R) )

{ delta = (R+bb->R - d)/2 + 1;

ddx = (bb->x-x)/d;

ddy = (bb->y-y)/d;

x = x - ddx*delta;

y = y - ddy*delta;

bb->x = bb->x + ddx*delta;

bb->y = bb->y + ddy*delta;

Result = bb;

exit; } } }

//initial

int ballSize = 10; //розмір куль

int loseSize = ballSize + 5;

int MaxEnergy= 20; // сила максимального удару

int CueLength = 200; //довжина кия

float mu = 0.97;

float Step = 0.03; // переміщення

int PyramidHeight; //величина піраміди

float MovementLimit; // переміщення

bool BallsInMove=false;

int Player=0;

float CompAngle;

int CompMove;

float CalculateAngle;

int tick;

bool MustBeHitted;

int Balls;

int ballsIn;

TForm1 *Form1;

TCue *Cue=new TCue;

TBall *Ball=new TBall;

TBilliardTable *BilliardTable= new TBilliardTable;

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{}

void __fastcall TForm1::StopAll(){

{ int i;

TBall *b = new TBall;

{ for( i =0; iBall->Count-1; i ++)

{ //b=BilliardTable->Ball->Items[i];

b->dx = 0;

b->dy = 0; }

Cue->Visible = True; } }}

void ComputerMove(){

Cue->Visible = True;

CompAngle = CalculateAngle;

if(CompAngle > Cue->Angle)

CompMove = 1;

else CompMove = -1;}

void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,

TShiftState Shift)

{{ int cur;

TBall *b= new TBall;

TBilliardTable *BilliardTable= new TBilliardTable;

{ if(BallsInMove) exit;

if(! Cue->Visible ) exit;

if(Player == 1 ) exit;// нельзя управлять во время хода компьютера!

// cur = Cue->ToBall->ID;

if(Key == VK_DOWN)

Cue->Angle = Cue->Angle - Step;

if(Key == VK_UP)

Cue->Angle = Cue->Angle + Step;

if(Key == VK_RIGHT )

{ cur = (cur + 1) % Ball->count;

//b = Ball->Items[cur];

}while( b->exists);

if(Key == VK_LEFT )

do{ cur = (cur - 1 + Ball->count) % Ball->count;

// b = Ball->Items[cur];

}while( b->exists);

if(Key == 32 ) if (Cue->Visible) Cue->Hit();

if(Key == 13 ) ComputerMove();

if (Key = 13) StopAll();

// Cue->ToBall = Ball->Items[cur]; } }}

void __fastcall TForm1::Timer1Timer(TObject *Sender)

{{ int cur, i, num;

TBall *b, *b2 = new TBall;

boolean allstopped;

TLose *lz = new TLose;

float d;

char* Mess;

{ tick++;

/* while( Cue.Angle > 6.28 do

Cue.Angle := Cue.angle - 6.28;

while( Cue.Angle < 0 do

Cue.Angle := Cue.angle + 6.28;

*/ if (CompMove != 0 && Player == 1)

{ Cue->Angle = Cue->Angle + Step*CompMove;

if(abs(CompAngle-Cue->Angle) <= Step)

{ CompMove = 0;

Cue->Angle = CompAngle;

MustBeHitted = True; } }

if(Player == 0 ) MustBeHitted = False;

if(MustBeHitted )

if(Cue->energy > MaxEnergy/2 )

{ Cue->Hit();

MustBeHitted = False; } for(int i =0; i count-1; i++)

{ // b = Ball->Items[i];

if(!b->exists ) continue;

if(b->InLose(num) )

{ b->Stop();

b->exists = False;

Balls--;

ballsIn++;

//lz = BilliardTable->Lose->Items[num];

lz->ballsInside++;

//PlayerN[Player]->balls++;

if(Balls == 1 )

{ GameStatus->gsGameOver();

Timer1->Enabled = False; }

cur = Cue->ToBall->ID;

do{

cur = (cur + 1) % Ball->Count;

b = Ball->Items[cur];

}while( b->exist);

Cue->ToBall = b; }

b->dx = b->dx*mu;

b->dy = b->dy*mu;

if((b->x+b->dx > BilliardTable->Right-b->R)

|| (b->x+b->dx Left+b->R)

b->dx = -b->dx * mu;

b->x = b->x + b->dx;

if((b->y+b->dy > BilliardTable->Bottom-b->R)

|| (b->y+b->dy Top+b->R)

b->dy = -b->dy * mu;

b->y = b->y + b->dy;

b2 = b->collisedWith;

b->outFrom(b2);

d = sqrt(sqr(b->dx)+sqr(b->dy));

if(d < MovementLimit )

{ b->Stop; }

Cue->energy = Trunc(MaxEnergy/2*cos(tick/5)+MaxEnergy/2)+1; }

allstopped = True;

for( i = 0; i Count - 1; i ++)

{ b = Ball->Items[i];

allstopped = (b->dx == 0) && (b->dy == 0) && allstopped; }

if(allstopped && MovedLater )

{ Cue->visible = True;

if(ballsIn == 0

then Player = 1 - Player;

if(Player == 1 ) ComputerMove;

ballsIn = 0; }

MovedLater = !allstopped;

BallsInMove = !allStopped;

Draw; } }}

void __fastcall TForm1::FormKeyPress(TObject *Sender, char &Key)

{ if(BallsInMove ) exit;

if(Key in ["i", "I"] )

{ ShowID = ! ShowID; }

if(Player == 1 ) exit;// нельзя управлять во время хода компьютера!

if(Key in ["h", "H"] then ComputerMove;// help me!}

void __fastcall TForm1::FormDestroy(TObject *Sender)

{ INI = TIniFile->Create(ExtractFilePath(ParamStr(0))+"\settings.ini");

INI->Writeint ("Phisics", "ballSize", ballSize);

INI->Writeint ("Phisics", "PocketSize", loseSize);

INI->Writeint ("Phisics", "MaxEnergy", MaxEnergy);

INI->Writeint ("Phisics", "CueLength", CueLength);

INI->Writeint ("Phisics", "PyramidHeight", PyramidHeight);

INI->WriteFloat("Phisics", "Friction", mu);

INI->WriteFloat("Phisics", "AngleStep", Step);

INI->WriteFloat("Phisics", "MovementLimit", MovementLimit);

INI->Writeint ("Phisics", "TimeInterval", Timer1->Interval);}

void __fastcall TForm1::Button1Click(TObject *Sender)

{ int i, j;

pBall b;

pLose luza;

boolean unique, inrect;

randomize;

Player = 0;

CompMove = 0;

Timer1->Enabled = True;

with Image1->Canvas do

{ Brush->Color = clWhite;

Pen->Color = clBlack;

Rectangle(0, 0, Width, Height); }

BilliardTable->Ball->Clear;

BilliardTable->Lose->Clear;

balls = -1;

new(b);

inc(balls);

b->x = BilliardTable->Width / 4 + BilliardTable->Left;

b->y = BilliardTable->Height / 2 + BilliardTable->Top;

b->R = ballSize;//Random(20)+10;

b->col = clLtGray;//Random(clWhite);

b->dx = Random*2-1;

b->dy = Random*2-1;

b->ID = 0;

b->exist = True;

BilliardTable->Ball->Add(b);

PlayerN[0]->balls = 0;

PlayerN[1]->balls = 0;

GameStatus = gsGame;

loses = -1;

for( j = 0; j <=1; j ++)

for( i = -1; i <=1; i ++)

{ new(luza);

inc(loses);

luza->x = BilliardTable->Left + (BilliardTable->Width / 2)*(i+1);

luza->y = BilliardTable->Top + (BilliardTable->Height / 2)*(j*2);

luza->R = loseSize;

if(abs(i)==1 )

{ luza->x = trunc(luza->x - i*luza->R*sqrt(2)/2);

luza->y = trunc(luza->y -(j*2-1)*luza->R*sqrt(2)/2); }

luza->ballsInside = 0;

BilliardTable->Lose->Add(luza); }

for( j = 1; j <=PyramidHeight; j ++)

for( i = 1; i <=j; i ++)

{ new(b);

inc(balls);

b->R = ballSize; //Random(20)+10;

b->col = clLtGray; //Random(clWhite);//clLtGray;

b->dx = Random*2-1;

b->dy = Random*2-1;

b->ID = balls;

b->exist = True;

if(j % 2 != 0

then b->y = -((j-1) / 2)*2*b->R+(i-1)*2*b->R + H / 2

else b->y = -((j-1) / 2)*2*b->R+(i-1)*2*b->R - b->R + H / 2;

b->y = b->y + dh;

b->x = (j-1)*2*b->R + 3 * BilliardTable->Width / 4 + dw + LoseSize;

BilliardTable->Ball->Add(b); }

inc(Balls);

BilliardTable->Cue->ToBall = BilliardTable->Ball->Items[0];

BilliardTable->Cue->angle = 180*Pi/180;

BilliardTable->Cue->visible = False;

StopAll;

void __fastcall TForm1::FormCreate(TObject *Sender)

{ INI = TIniFile->Create(ExtractFilePath(ParamStr(0))+"\settings.ini");

ballSize = INI->Readint ("Phisics", "ballSize", 10);

loseSize = INI->Readint ("Phisics", "PocketSize", ballSize + 5);

MaxEnergy = INI->Readint ("Phisics", "MaxEnergy", 20);

CueLength = INI->Readint ("Phisics", "CueLength", 200);

PyramidHeight = INI->Readint ("Phisics", "PyramidHeight", 5);

mu = INI->ReadFloat("Phisics", "Friction", 0.97);

Step = INI->ReadFloat("Phisics", "AngleStep", 0.03);

MovementLimit = INI->ReadFloat("Phisics", "MovementLimit", 0.01);

Timer1->Interval = INI->Readint ("Phisics", "TimeInterval", 20);

Width = Screen->Width-4;

Height = Screen->Height-4;

Panel1->Width = ClientWidth;

Panel1->Height = ClientHeight;

Image1->Width = ClientWidth;

Image1->Height = ClientHeight;

dw = (Image1->Width - W) / 2;

dh = (Image1->Height - H) / 2;

BilliardTable = TBilliardTable->Create;

BilliardTable->Ball = TList->Create;

BilliardTable->Lose = TList->Create;

BilliardTable->Cue = TCue->Create;

Left = dw + loseSize;

Top = dh + loseSize;

Width = W - LoseSize*2;

Height = H - LoseSize*2;

Right = Left + Width;

Bottom = Top + Height;

Player = 0;

Button1Click(Sender);}


2.2 Опис гри


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

Сила удару залежить від відстані в даний момент кия від битка (див. Додаток Б).

Управління:

Курсори:

вгору-вниз - обертання кия

вліво-управо - перемикання з однієї кулі на іншій

"пропуск" - удар києм

"H", "h" - підказка для людини (як на його місці зробив би хід чоловік)

"I", "i" - включення/виключення нумерації куль

"S", "s" - включення/виключення лінії прицілювання

Опис файлу конфігурації settings.ini:

ballsize=10 - розмір куль

Pocketsize=20 - розмір лузи

Maxenergy=20 - максимальна сила удару

Cuelength=200 - довжина кия

Friction=0,97 - коефіцієнт тертя (строго менше 1)

Pyramidheight=5 - кількість рівнів в піраміді з кулями

Anglestep=0,03 - крок повороту кия навколо кулі

Movementlimit=0,1 - межа вектора швидкості, після якого рух кулі вважається припиненим.

Timeinterval=20 - час між кадрами перемальовування (у мілісекундах)

Висновок

Використання методів Canvas для відображення графіки в проектах C++Builder допомогло реалізувати поставлену задачу. Але цей метод від малювання графіки на формі об’єктів є досить не практичний і тому важливо кожного разу перемалювати всю сцену з її об’єктами, а коли ми маємо анімацію то перемалювання сцени має ще й відбуватись непомітно для ока користувача, хоча цього часом буває досить важко добитись, особливо коли багато анімацій відбувається одночасно для декількох обєктів, що збільшує час виводу певного зображення на екран.

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

Програма широко використовує фізичні закони, для моделювання гри в середовищі C++Builder.


Використана література


  1. С++ для начинающих Липпман 2003г 332 стр.

  2. Введение в язык С++ Бьярн Страустрап, 1995 г. ; Книга по Си; уроки Visual C++ 2004г, 560 стр.

  3. http://forums.delphi.com/ab_cplus/start

  4. Программирование на языке СИ Ю.Ю.Громов, С.И.Татаренко 1998г 545 стр.;

  5. Applied C++: Practical Techniques for Building Better Software Авторы: Philip Romanik, Amy Muntz 2003г. 470 стр.

  6. C++ Unleashed Автор: Jesse Liberty 2005г. 396 p.

Характеристики

Тип файла
Документ
Размер
367,34 Kb
Тип материала
Учебное заведение
Неизвестно

Список файлов курсовой работы

Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
7026
Авторов
на СтудИзбе
260
Средний доход
с одного платного файла
Обучение Подробнее