Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы / ООП.Builder / Lab3C++.doc
Скачиваний:
17
Добавлен:
17.04.2013
Размер:
284.67 Кб
Скачать

13

МГИЭТ(ТУ)

Кафедра ВТ

факультет МПиТК

Лабораторная работа №3

«Классы и их элементы»

(компилятор «Borland C++ Builder»)

Составил: ст.пр. Тельминов О.А.

10/2001 г.

Цель работы:изучить работу с классами и графикой в средеWindows.

Теоретическая часть: программирование классов

Пример программы: Использованы понятия С++: классы, исключения и компоненты C++Builder:TImage,TTimer, обработчик мыши.

Рис. П1 В процессе работы можно управлять наклоном отрезка (клавиатура или кнопки на форме) и скоростью мяча.

Рис. П2. После падения мяч можно перемещать мышью по горизонтали

Программа состоит из одной формы Form1 (файлыunit1.h–заголовочный,unit1.cpp–реализация функций,unit1.dfm–внешний вид формы) и одного модуля созданного командойFile|New|Unitи переименованного при сохранении вBall(файлыball.hиball.cpp).

Начнем рассмотрение с файла ball.h.

/

защита от повторного

использования модуля

/-----------------------------------------------------------------#ifndef BallH

#define BallH

//-----------------------------------------------------------------#endif

class CBall

{

данные для частного использования внутри класса: координаты мяча и указатель на компонент Image– изображение

private:

int x,y;

TImage* Img;

public:

Прототипы всех функций класса для манипуляций с мячом.

Функция-конструктор CBallвызывается автоматически при создании объекта этого класса.

В результате класс будет иметь указатель на изображения для вывода на экран.

void MoveDeltaXY(int dx, int dy);

void MoveToY(int Y);

void MoveToX(int X);

void Hide();

void IncX(int dx){x=x+dx;};

int GetX(){return x;}

int GetY(){return y;}

CBall (TImage* _Img);

};

c

Класс для управления отрезком.

Задаются угол наклона, начальные, конечные, центральная точки, длина и указатель на изображение для вывода.

lass CSupport

{

private:

double angle;

int x1,y1, x2,y2,

xc,yc,len2;

TImage* Img;

double AngleToRad() {return (angle*3.1415) / 180.0;};

Функции, описанные в разделе public, доступны внутри и вне класса.

Данные и функции, описанные в разделе private– только внутри класса.

public:

void Rotate(double dA);

void Hide();

int Naklon(){return 2*(angle>0)-1;}

int ComputeBallY(int x);

CSupport (TImage* _Img);

};

Далее рассмотрим реализацию функций классов CBall, Csupport. (ball.cpp)

//--------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include <math.h>

#include "Ball.h"

//--------------------------------------------------

#pragma package(smart_init)

Полученный в конструкторе класса указатель на изображения используется для рисования мяча.

Свойство Canvasимеет вложенные свойства линий обводки (Pen), заливки (Brush), функции рисования эллипса (Ellipse) и др.

Перед именем каждой функции указан идентификатор класса, к которому она относится (CBall::)

CBall::CBall(TImage* _Img)

{

x=220;

y=0;

Img=_Img;

}

void CBall::Hide()

{

//стираем старое положение

Img->Canvas->Pen->Color = clWhite;

Img->Canvas->Brush->Color = clWhite;

Img->Canvas->Ellipse(x-10, y-10, x+10, y+10);

}

void CBall::MoveDeltaXY(int dx, int dy)

{

x+=dx;

y+=dy;

//рисуем в новом положении

Img->Canvas->Pen->Color = clBlue;

Img->Canvas->Brush->Color = clBlue;

Img->Canvas->Ellipse(x-10, y-10, x+10, y+10);

Img->Canvas->Pen->Color = clWhite;

Img->Canvas->Brush->Color = clWhite;

Img->Canvas->Ellipse(x-2-3, y-2-3, x+2-3, y+2-3);

}

void CBall::MoveToY(int Y)

{

y=Y;

MoveDeltaXY(0,0);

}

void CBall::MoveToX(int X)

{

x=X;

MoveDeltaXY(0,0);

}

CSupport::CSupport(TImage* _Img)

{

Img=_Img;

xc=(Img->Width) /2;

yc=(Img->Height)/2;

x1=x2=xc;

y1=y2=yc;

len2= 100;

angle=3;

Rotate(0);

}

void CSupport::Hide()

{

Img->Canvas->Pen->Width=3;

Img->Canvas->Pen->Color = clWhite;

Img->Canvas->MoveTo(x1,y1);

Img->Canvas->LineTo(x2,y2);

Img->Canvas->Pen->Width=1;

}

void CSupport::Rotate(double dA)

{

angle=angle+dA;

float alp = AngleToRad();

x1=xc-len2*cos(alp);

Функция вычисляет такое положение мяча по Y, чтобы он находился на отрезке. В качестве входного параметра используется координатаX.

y1=yc-len2*sin(alp);

x2=xc+len2*cos(alp);

y2=yc+len2*sin(alp);

Img->Canvas->Pen->Width=3;

Img->Canvas->Pen->Color = clRed;

Img->Canvas->Brush->Color = clRed;

Важно отметить, что при выходе Xза пределы краев отрезка происходитвыброс исключения(throw) в виде целого числа.

В дальнейшем оно будет поймано и обработано.

С помощью механизма исключений происходит взаимодействие классов.

Img->Canvas->MoveTo(x1,y1);

Img->Canvas->LineTo(x2,y2);

Img->Canvas->Pen->Width=1;

}

int CSupport::ComputeBallY(int x)

{

if ((x<x1) || (x>x2)) throw Naklon();

return yc+(y1-yc)*(xc-x)/(xc-x1);

}

Таким образом, рассмотрено описание и реализация классов для управления мячом и направляющим отрезком на изображении.

Перейдем к форме Form1 и работе с указанными классами. Ниже приведен листингunit1.h.

//------------------------------------------------------------------

#ifndef Unit1H

#define Unit1H

//------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

//----------------------------------------------------------------

#include "ball.h"

#include <ComCtrls.hpp>

class TForm1 : public TForm

{

__published: // IDE-managed Components

TImage *Image1;

TButton *Button2;

TButton *Button3;

TTimer *Timer1;

TLabel *Label2;

TTrackBar *TrackBar1;

TLabel *Label1;

TLabel *Label3;

void __fastcall FormDestroy(TObject *Sender);

void __fastcall Button2Click(TObject *Sender);

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

void __fastcall Timer1Timer(TObject *Sender);

void __fastcall Image1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y);

void __fastcall Image1MouseMove(TObject *Sender, TShiftState Shift,

int X, int Y);

void __fastcall Image1MouseUp(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y);

void __fastcall TrackBar1Change(TObject *Sender);

private: // User declarations

CBall* Ball;

CSupport* Doska;

int DirMoving;

bool MouseDn;

public: // User declarations

__fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------

#endif

Важно отметить следующие особенности:

  • работа с изображением (Image1);

  • анализ нажатых клавиш на клавиатуре (FormKeyPress);

  • использование компонента (Timer);

  • работа с мышью (…Mouse…);

  • применение бегунка (TrackBar1);

  • указатели на объекты CBall* Ball, CSupport* Doska инициализируются в конструкторе формыTForm1 и уничтожаются при высвобождении ресурсов формыFormDestroy;

Листинг unit1.cpp

//-------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include <math.h>

#include "Unit1.h"

//-------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//-------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

Form1->KeyPreview = true;

Timer1->Interval=100;

Image1->Canvas->Brush->Color = clWhite;

Image1->Canvas->FillRect(Rect(0, 0, Image1->Width, Image1->Height));

Ball = new CBall(Image1);

Doska = new CSupport(Image1);

DirMoving=true;

try

{

Ball->Hide();

Doska->Hide();

Ball->MoveToY(Doska->ComputeBallY(Ball->GetX()));

Фукнция ComputeBallYможет выбросить исключение (см. выше), поэтому она заключена в блокtry{}. Операторcatchпредназначен для обработки исключений (в данном случаеint). Действительно, при падении мяча выбрасывается исключение целого типа и обрабатывается в этомcatch.

Doska->Rotate(0);

}

catch (int d)

{

DirMoving=0;

}

}

//-------------------------------------------------------------------

void __fastcall TForm1::FormDestroy(TObject *Sender)

{

delete Ball;

delete Doska;

}

//-------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Снова блок try–catchдля обработки возможного падения мяча.

В этой функции происходит поворот отрезка на угол с дискретом 5 градусов.

// if (!DirMoving) return;

try

{

Ball->Hide();

Doska->Hide();

if (((TButton*) Sender)->Caption=="Left") Doska->Rotate(-5);

else Doska->Rotate(+5);

Ball->MoveToY(Doska->ComputeBallY(Ball->GetX()));

}

catch (int d)

{

Ball->MoveDeltaXY(0,0);

Doska->Rotate(0);

DirMoving=0;

}

}

//-------------------------------------------------------------------

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

{

if (Key=='a') Button2Click((TObject *)Button2);

if (Key=='s') Button2Click((TObject *)Button3);

}

Обработка нажатий на клавиатуру. Важно, чтобы KeyPreview = true;

//-------------------------------------------------------------------

void __fastcall TForm1::Timer1Timer(TObject *Sender)

{

Эта функция вызывается каждые Timer1->Intervalмиллисекунд при условии, чтоTimer1->Enabled=true.

Здесь использована для перемещения мяча по горизонтали.

Timer1->Enabled=DirMoving;

try

{

Ball->Hide();

Doska->Hide();

Doska->Rotate(0);

Ball->IncX((Doska->Naklon())*15*DirMoving);

Ball->MoveToY(Doska->ComputeBallY(Ball->GetX()));

}

catch (int d)

{

Doska->Rotate(0);

Ball->MoveToY(Image1->Height-11);

DirMoving=0;

Label2->Caption="Мяч-мышью по горизонтали";

}

}

//-------------------------------------------------------------

void __fastcall TForm1::Image1MouseDown(TObject *Sender,

TMouseButton Button, TShiftState Shift, int X, int Y)

{

Обработчик события опускания вниз кнопки мыши

if (abs(Ball->GetX() - X)<10)

if (!DirMoving)//признак того, что мяч упал

MouseDn=true;

}

//-----------------------------------------------------------------

v

Обработчик события перемещения мыши. Факт, что кнопка мыши нажата или отпущена в явном виде отсутствует, поэтому используем свой флаг MouseDn, который описан в классеTForm1, проинициализирован в конструктореForm1 нулевым значением.

В функции Image1MouseDownон устанавливается, вImage1MouseMoveпроверяется, а вImage1MouseUp– сбрасывается.

oid __fastcall TForm1::Image1MouseMove(TObject *Sender, TShiftState Shift,

int X, int Y)

{

if (MouseDn)

{

Ball->Hide();

Ball->MoveToX(X);

}

}

//-------------------------------------------------------------------

void __fastcall TForm1::Image1MouseUp(TObject *Sender, TMouseButton Button,

TShiftState Shift, int X, int Y)

{

MouseDn=false;

}

//-------------------------------------------------------------------

void __fastcall TForm1::TrackBar1Change(TObject *Sender)

{

Изменяется интервал срабатывания таймера при изменении бегунка TrakBar1 (нач. знач.=300)

Timer1->Interval=TrackBar1->Position;

}

//-------------------------------------------------------------------

ВНИМАНИЕ! В компиляторе отключите останов программы при возникновении отключений (Tools|Debuggeroptions|Languageexceptions):

Соседние файлы в папке ООП.Builder