p align="left">Почніть новий проект, помістіть на нього компонент Image і кнопку з написом «Намалювати», в обробник події OnClick якою запишіть код, аналогічний приведеному вище, але що конкретизує функцію: #define Pi 3.14159 float X, Y; // координати функції int РХ, PY; // координати пикселов for (РХ = 0: РХ <- Imagel->Width; PX++) {//X - координата, відповідна пикселу з координатою РХ X = РХ * 4 * Pi / imagel->Width; Y = sin(X); //PY - координата пиксела, відповідна координаті У PY = Imagel->Height - (Y+1) * Imagel->Height / 2; //Устанавливается чорний колір вибраного пиксела Imagel->Canvas->Pixels(PX][PY] = clBlack; } 1.3 Збереження конфігурації в файлах ini |Файли .ini - це текстові файли, призначені для зберігання інформації про настройки різних програм. Інформація у файлі логічно групується в розділи, кожен з яких починається оператором заголовка, поміщеним в квадратні дужки. Наприклад [Desktop|]. У рядках, наступних за заголовком, міститься інформація, що відноситься до даного розділу, у формі: <ключ>=<значення> [dBASE| Files|] Driver32=C|:\WINDOWS\SYSTEM\odbcjt32.dll Файли .ini, як правило, зберігаються в каталозі Windows|, який можна знайти за допомогою функції GetWindowsDirectory|. У C++Builder| роботу з файлами .ini найпростіше здійснювати за допомогою створення в програмі об'єкту типу TIniFile|. Цей тип описаний в модулі inifiles|, який треба підключати до програми оператором uses| (автоматично це не робиться). При створенні об'єкту типу TlniFile| в нього передається ім'я файлу .ini, з яким він зв'язується. Файл повинен існувати до створення об'єкту. Для запису значень ключів існує багато методів: WriteString|, WriteInteger|, WriteFloat|, |і ін. Кожен з них записує значення відповідного типу. Оголошення всіх цих методів дуже схожі. Наприклад: void| fastcall| WriteString| (const| AnsiString| Section| const| AnsiString| Ident|, const| AnsiString| Value|); void| fastcall| Writelnteger| (const| AnsiString| Section| const| AnsiString| Ident|, int| Value|); У всіх оголошеннях Section| - розділ файлу, Ident| - ключ цього розділу, Value| - значення ключа. Якщо відповідний розділ або ключ відсутній у файлі, він автоматично створюється. Є аналогічні методи читання: ReadString|, Readlnteger|, ReadFloat|, ReadBool| і ін. Наприклад: AnsiString| fastcall| ReadString| (const| AnsiString| Section| const| AnsiString| Ident|, const| AnsiString| Default|); int| fastcall| Readlnteger| (const| AnsiString| Section| const| AnsiString| Ident|, int| Default|); Методи повертають значення ключа| розділу Section|. Параметр Default| визначає значення, що повертається у випадку, якщо у файлі не вказано значення відповідного ключа. Перевірити наявність значення ключа можна методом ValueExists|, в який передаються імена розділу і ключа. Метод DeleteKey| видаляє з файлу значення вказаного ключа у вказаному розділі. Перевірити наявність у файлі необхідного розділу можна методом SectionExists|. Метод EraseSection| видаляє з файлу вказаний розділ разом зі всіма його ключами. Є ще ряд методів, які ви можете подивитися у вбудованій довідці C++Builder|. Подивимося на прикладі, як все це можна використовувати для установки програми, запам'ятовування її настройоки і для видалення програми. Зробіть просте тестову програму. Перенесіть на форму три кнопки Button| і діалог FontDialog|. Перша кнопка (назвіть її BInst| і задайте напис Install|) імітуватиме установку програми. Точніше, не саму установку, оскільки копіювати файли з загрузочної дискети ми не будемо, а тільки створення файлу .ini у каталозі Windows|. Друга кнопка (назвіть її BUnlnst| і задайте напис Unlnstall|) імітуватиме видалення програми. Тут ми не видалятимемо саму програму з диска, а тільки видалимо з каталога Windows| наш файл, а третя кнопка (назвіть її BFont| і задайте напис Font|) дозволятиме змінювати ім'я шрифту, використовуваного у формі, і забезпечить запам'ятовування цього шрифту у файлі .ini, щоб надалі при запуску програми можна було читати цю настройку і задавати її формі. Розділ 2. Практична частина 2.1 Код гри #include <vcl.h> #pragma hdrstop #include "UBilliard.h" #include <math.h> #include "inifiles.hpp" #pragma package(smart_init) #pragma resource "*.dfm" // розмір столу int const w = 600; int const h = 300; class TGameStatus { protected: char* gsStatus; public: void gsBegin(){ gsStatus="qsBegin"; } void gsGame(){ gsStatus="gsGame"; } void gsGameOver(){ gsStatus="gsGameOver"; }}; TGameStatus *GameStatus = new TGameStatus; struct TPlayer{ int balls; }; class TLose{ public: int x,y; int ballsInside; int R; void Draw();}; class TBall { public: float x,y, dx,dy; int R; bool exists, stopped ; int col,ID,count; TList *Items; void Draw(); void Stop(); bool InLose(int &Number); void outFrom(TBall b); TBall CollisedWith(); ~TBall();}; class TCue { public: bool Visible; TBall ToBall; float Angle, energy; void draw(); void Hit();}; void TCue::Hit(){ TBall *ToBall; ToBall->dx =-cos(Angle)*energy; ToBall->dy = -sin(Angle)*energy; ToBall->stopped = False; Visible = False;} class TBilliardTable{ public: int Width, Height, Left, Right, Top, Bottom; TList* Ball; TList* Lose; TCue Cue; void Draw();}; float GetAngToXY( pBall b ;float hitX, hitY){ float dx, dy, d; dx = b->x - hitX; dy = b->y - hitY; d = sqrt(dx*dx+dy*dy); if(dy>0) Result = arccos(dx/d); else Result = -arccos(dx/d); } void TBall::outFrom(pBall:b){ { AB, aa, bb, V1, V2, aPrXx, aPrXy, aPrYx, aPrYy, aPrX, aPrY, bPrXx, bPrXy, bPrYx, bPrYy, bPrX, bPrY, alfaA, betaA, gammaA, Extended alfaB, betaB, gammaB; if(b == NULL ) exit; AB = sqrt(sqr(x-b->x)+sqr(y-b->y)); V1 = sqrt(dx*dx+dy*dy); V2 = sqrt(b->dx*b->dx+b->dy*b->dy); aPrXx = 0; aPrXy = 0; bPrXx = 0; bPrXy = 0; ////////-ball #1- if(V1>0 ) { if((b->y-y)>0 alfaA = arccos((b->x-x)/AB); else alfaA = -arccos((b->x-x)/AB); if(dy>0 then gammaA = arccos(dx/V1) else gammaA = -arccos(dx/V1); betaA = gammaA-alfaA; aPrX = V1*cos(betaA); aPrY = V1*sin(betaA); aPrXx = aPrX*cos(alfaA); aPrXy = aPrX*sin(alfaA); aPrYx = aPrY*sin(alfaA); aPrYy = aPrY*cos(alfaA); } //////////////-ball #2- if(V2>0 ) { if((y-b->y)>0 then alfaB = arccos((x-b->x)/AB); //=alfaA+pi else alfaB = -arccos((x-b->x)/AB); if(b->dy>0) then gammaB = arccos(b->dx/V2); else gammaB = -arccos(b->dx/V2); betaB = gammaB-alfaB; bPrX = V2*cos(betaB); bPrY = V2*sin(betaB); bPrXx = bPrX*cos(alfaB); bPrXy = bPrX*sin(alfaB); bPrYx = bPrY*sin(alfaB); bPrYy = bPrY*cos(alfaB); } dx = ((dx - 2*aPrXx) + bPrXx)*mu; // = mu*(bPrXx - aPrXx) dy = ((dy - 2*aPrXy) + bPrXy)*mu; // = mu*(bPrXy - aPrXy) b->dx = ((b->dx - 2*bPrXx) + aPrXx)*mu; // = mu*(aPrXx - bPrXx) b->dy = ((b->dy - 2*bPrXy) + aPrXy)*mu; // = mu*(aPrXy - bPrXy)} void InitSound(){ pcm->wFormatTag = WAVE_FORMAT_PCM; pcm->nChannels = 1; pcm->nSamplesPerSec = 44100; pcm->nAvgBytesPerSec = 2*44100; pcm->nBlockAlign = 2; pcm->wBitsPerSample = 16; pcm->cbSize = 0; WaveOut = 0; open_status = waveOutOpen(&WaveOut, 0, &pcm, Form1->Handle, 0, callback_Window)} float CalCulateAngle(){ { int i, j; pLose ToLz, lz; pBall nearestBall, Bl, b; float hitX, hitY; minAng, a2Lz, minD, float dx, dy, a, minDist, d; minDist = 1.7e+308; minD = minDist; with BilliardTable do { for( j = 0; j <=Lose->Count-1; j ++) for( i = 0; i <=Ball->Count-1; i ++) { lz = Lose->Items[j]; b = Ball->Items[i]; if(! b->exist ) continue; d = sqrt(sqr(b->x-lz->x)+sqr(b->y-lz->y)); if(d < minDist ) { minDist = d; ToLz = lz; Bl = b; } } if((Bl == NULL) ) exit; dx = Bl->x - ToLz->x; dy = Bl->y - ToLz->y; d = sqrt(dx*dx+dy*dy); if((dy)>0 a2Lz = arccos(dx/d); else a2Lz = -arccos(dx/d); hitX = Bl->x + cos(a2Lz)*Bl->R; hitY = Bl->y + sin(a2Lz)*Bl->R; minAng = 1.7e+308; for( i = 0; i <=Ball->Count-1; i ++) { b = Ball->Items[i]; if((b->ID == Bl->ID) || (not b->exist) continue; a = GetAngToXY(b, hitX, hitY); if(abs(a2Lz-a) < minAng ) { minAng = abs(a2Lz-a); nearestBall = b; Result = a; } } for( i := 0 to Ball.Count-1 do begin b := Ball.Items[i]; if (b.ID = Bl.ID) or (not b.exist) continue; d := sqrt(sqr(b.x-Bl.x)+sqr(b.y-Bl.y)); if d < minD then begin minD := d; nearestBall := b; end; end; dx := Bl.x - ToLz.x; dy := Bl.y - ToLz.y; d := sqrt(dx*dx+dy*dy); if (dy)>0 a2Lz := arccos(dx/d) else a2Lz := -arccos(dx/d); hitX := Bl.x + cos(a2Lz)*Bl.R; hitY := Bl.y + sin(a2Lz)*Bl.R; dx := nearestBall.x - hitX; dy := nearestBall.y - hitY; d := sqrt(dx*dx+dy*dy); if (dy)>0 then a := arccos(dx/d) else a := -arccos(dx/d); Result := a;} void ComputerMove(){ Cue->visible = True; CompAngle = CalculateAngle; if(CompAngle > Cue->angle) CompMove = 1; else CompMove = -1;} void TBilliardTable::Draw(){ { int i; pBall *b; pLose *lz; char* WhoIsIt; Canvas->Brush->Color = clBlack; Canvas->Pen->Color = clBlack; Canvas->Rectangle(0,0,Width, Height); Canvas->Brush->Color = $336699; Canvas->Pen->Color = clYellow; Canvas->Rectangle(BilliardTable->Left - LoseSize, BilliardTable->Top - LoseSize, BilliardTable->Right + LoseSize, BilliardTable->Bottom + LoseSize);
Страницы: 1, 2, 3
|