на тему рефераты Информационно-образоательный портал
Рефераты, курсовые, дипломы, научные работы,
на тему рефераты
на тему рефераты
МЕНЮ|
на тему рефераты
поиск
Система координат канви
p align="left">Canvas->Brush->Color = clGreen;

Canvas->Rectangle(BilliardTable->Left, BilliardTable->Top, BilliardTable->Right, BilliardTable->Bottom);

Canvas->Pen->Color = clYellow;

Canvas->Pen->Color = clBlack;

Canvas->Ellipse(BilliardTable->Left + (3 * BilliardTable->Width / 4)-2,

BilliardTable->Top + (BilliardTable->Height / 2)-2,

BilliardTable->Left + (3 * BilliardTable->Width / 4)+2,

BilliardTable->Top + (BilliardTable->Height / 2)+2);

Canvas->Brush->Color = $336699;

Canvas->Font->Color = clYellow;

Canvas->Font->Style = [];

if(Player == 0

then WhoIsIt = "Игрок";

if(Player == 1

then WhoIsIt = "Компьютер";

Canvas->TextOut(BilliardTable->Left+30, dh + 1,

"Ход: "+WhoIsIt+"а");

Canvas->TextOut(BilliardTable->Left+30, BilliardTable->Bottom,

"В лузах:"+IntToStr(InLoses));

if(Player == 0 ) Canvas->Font->Style = [fsBold];

Canvas->TextOut(BilliardTable->Right-150, BilliardTable->Bottom,

"Игрок:"+IntToStr(PlayerN[0]->balls));

Canvas->Font->Style = [];

if(Player == 1 ) Canvas->Font->Style = [fsBold];

Canvas->TextOut(BilliardTable->Right-150, dh + 1,

"Компьютер:"+IntToStr(PlayerN[1]->balls));

Canvas->Brush->Color = clBlack;

Canvas->Font->Color = clYellow;

Canvas->Font->Style = [fsBold];

Canvas->Font->Style = [];

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

{ lz = Lose->Items[i];

lz->Draw; }

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

{ b = Ball->Items[i];

if(b->exist ) b->Draw; }

if(Cue->visible ) Cue->Draw; }

gsGameOver:

{ }

case } // case;break;; }

void TLose::Draw()

{ with Form1->Image1->Canvas do

{ Brush->Color = clBlack;

Pen->Color = clYellow;

Ellipse(Trunc(x-r), Trunc(y-r),

Trunc(x+r), Trunc(y+r));

Font->Color = clWhite;

TextOut(x-4,y-8, IntToStr(ballsInside)); } }

void TBall::Draw()

{ with Form1->Image1->Canvas do

{ Brush->Color = col;

Pen->Color = col;//clBlack;

Ellipse(Trunc(x-r), Trunc(y-r),

Trunc(x+r), Trunc(y+r));

Brush->Color = clWhite;

Pen->Color = clWhite;

Ellipse(Trunc(x-r*sqrt(2)/2*0.5-2), Trunc(y-r*sqrt(2)/2*0.5-2),

Trunc(x-r*sqrt(2)/2*0.5+2), Trunc(y-r*sqrt(2)/2*0.5+2));

Brush->Color = col;

Font->Color = clWhite - col;

if(ShowID )

{ TextOut(Trunc(x-4), Trunc(y-8), IntToStr(ID)); }

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 <=BilliardTable->Lose->Count-1; i ++)

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

inLz = sqrt(sqr(x-lz->x)+sqr(y-lz->y)) <== lz->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 <=BilliardTable->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 + bb->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; i<=BilliardTable->Ball->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 <=Ball->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 < BilliardTable->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 < BilliardTable->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 <=Ball->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.

Страницы: 1, 2, 3



© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент.