Добавил admin | Категория Pascal за 12 уроков, перевод | 31 Января 2014
Если вы чувствуете что графика не столь важна сейчас для вас можете перейти к 9тому уроку а 8 урок изучить позже. Программисты которых интересует графика в Pascal обязательно должны заинтересоваться данным уроком.
Этот урок будет охватывать:
- Введение в графику
- Инициализация графики
- Использование графики
- Расширенное использование графики
Для работы нам потребуется egavga.bgi, скачать его можно тут. Скачайте его и разместите в каталоге BGI в директории Turbo Pascal.
Данный файл защищен законом об авторском праве, в случае его использования предполагается что вы купили Turbo Pascal, файл egavga.bgi является собственностью сообщества Borland Pascal. Так же стоит отменить что вы скачиваете и используете данный файл на свой страх и риск. Сайт Koder.kz не берет на себя ответственности за любой ущерб вам или вашей техники нанесенный данным файлом.Введение в графику
Графика в Turbo Pascal представляет собой инструмент более сложного вывода информации на монитор пользователя. Паскаль имеет графическую библиотеку с помощью которой мы и будем предоставлять необходимую информацию на мониторе. Для того что бы задействовать графическую библиотеку нам необходимо подключить графический модуль к нашей программе. Для этого разделе Uses добавим модуль Graph
Инициализация графикиДля того что бы иметь возможность работать с графикой в паскале мы должны ее задействовать, мало подключить нужный модуль, нужно еще ее правильно проинициализировать. Инициализация нам необходима для того что бы мы могли использовать графические процедуры и функции. По сути объявлением в Uses модуля Graph мы говорим программе где находятся процедуры и функции которые мы собираемся использовать в программе. При инициализации графики в вашем приложении драйвер видеокарты автоматически начнет использовать наш с вами BGI файл EGAVGA.BGI. а при завершении графического режима так же автоматически перейдет на стандартный видео драйвер. Инициализация и работа в графическом режиме Turbo pascal показана ниже
Program Lesson8_Program1;
Uses Crt,Graph;
Var GraphicsDriver, GraphicsMode,
ErrCode : Integer;
{two var's are needed for initialisation}
Begin
Writeln('Initialising Graphics, please wait...');
GraphicsDriver := Detect;
InitGraph(GraphicsDriver, GraphicsMode,'');
{IMPORTANT, read the following or
otherwise graphics will not work!! ;)}
(*between the inverted commas,
type in the path of the graphics BGI file
(usually 'C:\TP\BGI'),
OR
change the dir in the file menu (PRESS Alt+F)
and roll down your mouse pointer to the 'change dir'
menu; then either type the path to the BGI file,
or go to C: -> TP -> BGI*)
ErrCode := GraphResult;
If GraphResult <> grOK then { <> means 'not equal to' }
Begin
ClrScr;
Writeln('Graphics error occured: ',
GraphErrorMsg(ErrCode));
Writeln('If a file not found error is displayed above');
Writeln('then, change the dir from the current');
Writeln('location to C:\ -> TP -> BGI, '+
+'from the file menu!');
Readln;
Halt(1);
End Else
Begin
Randomize;
SetColor(Random(15) + 1); {Set text colour}
{Output text at 20 pixels from the top of the screen,
and 20 other from the left side of the screen.}
OutTextXY(20,20,'Welcome to the new generation
of Pascal Programming:');
OutTextXY(20,30,'Pascal Graphics!!');
OutTextXY(25,70,'You will learn more
graphics procedures and');
OutTextXY(25,80,'functions, later in this lesson :-)');
Readln;
End;
CloseGraph;
End.
Функция InitGraph(GraphicsDriver,GraphicsMode,'');
Последний параметр, который мы передаем пустым, строковым ('') является ни чем другим как полный путь к файлу графического драйвера BGI. Если в качестве пути ничего не указывать то программа будет искать файл графического драйвера в папке приложения. Но следует явно указывать этот параметр так как например в операционной системе Windows 7, вместо того что бы искать этот файл в папке с программой операционная система ищет его в system32 что естественно приводит к ошибке в программе. Если вы не изменить адрес папки (C:\TP) после установки, вы можете использовать этот путь: "C:\TP\BGI', например: InitGraph(GraphicsDriver, GraphicsMode, 'C:\TP\BGI'); В случае возникновения ошибки при переходе в графический режим (подключении нашего драйвера) мы должны сообщить об ошибке пользователю.
То есть если If GraphResult <> grOK then, GraphResult вернула что то отличное от grOK следовательно проинициализировать графический режим нам не удалось. В случае удачной инициализации мы можем использовать графические процедуры и функции (ветка else) из графической библиотеки graph в приведенном выше примере мы использовали только OutTextXY() и SetColor() однако функций намного больше, о них речь пойдет ниже.
Графический режим в турбо паскале завершается функцией CloseGraph. Полезная информация: Обратите внимание, что разрешение экрана 640 х 480 пикселей.
Использование графикиИспользовать графику в Паскале довольно не сложно, все что вы должны уметь это правильно инициализировать графику, использовать внутренние процедуры и функции ну и правильная выгрузка графического драйвера. Ниже приведем примеры процедур и функций графического режима Турбо Паскаль:
Название | Описание | Пример |
SetBkColor(colour/colour code); | Цвет фона | SetBkColor(Brown); или SetBkColor(6); |
SetColor(colour/colour code); | Цвет текста | SetColor(Green); или SetColor(2); |
OutText(''); | Вывод текста | OutText('BGI Graphics'); |
OutTextXY(X,Y,''); | Вывод текста в указанных точках, на оси координат | OutTextXY(300,100,'BGI Graphics'); |
MoveTo(X,Y); | Установить курсор на позицию переданную в X/Y | MoveTo(GetMaxX,GetMaxY); |
PutPixel(X,Y,colour/colour code); | Ставит точку в указанной позиции | PutPixel(50,128,Cyan); или PutPixel(50,128,5); |
Line(X,Y); | Рисует линию | Line(30,111); |
Rectangle(X1,Y1,X2,Y2); | Рисует прямоугольник | Rectangle(30,50,25,45); |
Circle(X,Y,Radius); | Рисует круг | Circle(GetMaxX Div 2, GetMaxY Div 2, 100); |
Ellipse(X,Y,P,Q,HorR,VerR); | Рисует эллипс с центральными точками X, Y , начиная с P градусов до Q градусов, с горизонтальным радиусом Хорр и вертикальной радиусе VERR . | Ellipse(300,160, 0,360,60,40); |
Arc(X,Y,P,Q,Radius); | Рисует дугу, начиная с X, Y , углом P градусов и заканчивая углом Q градусов, с радиусом Radius. | Arc(100,200,0,90,70); |
PieSlice(X,Y,P,Q,Radius); | Аналогично Arc(X,Y,P,Q,Radius); | PieSlice(90,150,20,95,100); |
Bar(X1,Y1,X2,Y2); | Процедура Bar рисует закрашенный прямоугольник (используемый например, в гистограммах) | Bar(50,100,150,500); |
Bar3D(X1,Y1,X2,Y2, Depth,ThreeD_Top); | Аналог Bar(X1,Y1,X2,Y2); но использует псевдо 3D | Bar3D(120,100,250, 150,50,TopOn); |
Далее мы с вами рассмотрим пример программы использующей компьютерную графику, в данном примере используется большинство графический процедур и функций языка Паскаль. Для комфорта предлагаю вам скопировать программу и вставить в свой редактор. Исходный код:
Program Lesson8_Program2;
{Author: Victor J. Saliba}
{victorsaliba@hotmail.com}
{Website: http://pascal-programming.info/}
Uses Crt,Graph;
Var Gd, Gm,
Radius, Grow, IncP, IncQ : Integer;
DecrP, DecrQ : Boolean;
Begin
Gd := Detect;
InitGraph(Gd, Gm, '');
{Do not forget to change the dir path}
{Try C:\TP\BGI}
if GraphResult <> grOk then
Halt(1);
Randomize;
SetColor(Random(15)+1);
{In the following loop, 600 circles:
circles with different radii are
drawn. Everytime the loop is repeated,
the radius increases by
one, and thus the circle becomes +1
larger than the previous one.}
For Radius := 1 to 600 do
Begin
Circle(GetMaxX Div 2, GetMaxY Div 2, Radius);
Delay(1);
End;
ClearViewPort;
SetTextJustify(230, GetMaxY Div 2);
OutTextXY(230,GetMaxY Div 2,'Prepare for another one...');
Delay(1000);
ClearViewPort;
Grow := 0;
{The ellipse loop, is similar to the one
above except in that the vertical
radius increases by 1}
For Radius := 1 to 600 do
Begin
Inc(Grow);
Ellipse(GetMaxX Div 2,
GetMaxY Div 2, 0, 360,
GetMaxX Div 2, Radius + Grow);
Delay(1);
End;
ClearViewPort;
SetTextJustify(230, GetMaxY Div 2);
OutTextXY(230,GetMaxY Div 2,'Now what?'); Delay(1000);
ClearViewPort;
{Here's another graphics invention of mine! Similar
to the first one, but using two circles positioned
on both edges of the screen,
continously increasing in size}
For Radius := 1 to 600 do
Begin
Circle(GetMaxX Div 2, 0, Radius);
Circle(GetMaxX Div 2, GetMaxY, Radius);
Delay(2);
End;
Delay(1000);
ClearViewPort;
SetTextJustify(230, GetMaxY Div 2);
OutTextXY(230,GetMaxY Div 2,'What are you lookin'' at?');
Delay(1000);
ClearViewPort;
Grow := 0;
{Below is a simple rectangle loop,
which inreases its size by 1
(increment x1,y1 and decrement x2,y2)}
For Radius := 1 to 600 do
Begin
Inc(Grow);
Rectangle(((GetMaxX Div 2) - Radius) - Grow,
((GetMaxY Div 2) - Radius)- Grow,
((GetMaxX Div 2) + Radius) + Grow,
((GetMaxY Div 2) + Radius) + Grow);
Delay(2);
End;
ClearDevice;
SetTextJustify(230, GetMaxY Div 2);
OutTextXY(230,GetMaxY Div 2,
'Rotor of a helicopter thorn apart..');
Delay(2000);
ClearDevice;
{The demonstration below shows 4 rotating sectors,
moving horizontally,
and 4 other sectors in the opposite direction}
IncP := 0; IncQ := 0;
For Radius := 1 to 320 do
Begin
Inc(IncQ, 1);
Inc(IncP, (IncQ Div 2));
PieSlice(GetMaxX Div 2 + IncP,
GetMaxY Div 2, 0 + IncP, 2 + IncP, 240);
PieSlice(GetMaxX Div 2 + IncP,
GetMaxY Div 2, 180 + IncP, 182 + IncP, 240);
PieSlice(GetMaxX Div 2 + IncP,
GetMaxY Div 2, 88 + IncP, 90 + IncP, 240);
PieSlice(GetMaxX Div 2 + IncP,
GetMaxY Div 2, 268 + IncP, 270 + IncP, 240);
PieSlice(GetMaxX Div 2 - IncP,
GetMaxY Div 2, 45 + IncP, 47 + IncP, 240);
PieSlice(GetMaxX Div 2 - IncP,
GetMaxY Div 2, 135 + IncP, 137 + IncP, 240);
PieSlice(GetMaxX Div 2 - IncP,
GetMaxY Div 2, 225 + IncP, 227 + IncP, 240);
PieSlice(GetMaxX Div 2 - IncP,
GetMaxY Div 2, 315 + IncP, 317 + IncP, 240);
Delay(10);
ClearDevice;
If IncP >= 220 then
Dec(IncQ, 4);
End;
ClearViewPort;
SetTextJustify(230, GetMaxY Div 2);
OutTextXY(230,GetMaxY Div 2,'Ah, now it is repaired..');
Delay(2000);
ClearDevice;
{The next demonstration shows a fantastic
rotor-like movement animation}
{Do not be amazed by the coding below - it's very simple}
{To make such animation, all you
have to do is to make a sector rotating
by simply increasing its degrees and clear the old one}
IncP := 0; IncQ := 0;
For Radius := 1 to 320 do
Begin
Inc(IncQ, 1);
Inc(IncP, (IncQ Div 4));
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 0 + IncP, 2 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 180 + IncP, 182 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 90 + IncP, 92 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 270 + IncP, 272 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 45 + IncP, 47 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 135 + IncP, 137 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 225 + IncP, 227 + IncP, 240);
PieSlice(GetMaxX Div 2,
GetMaxY Div 2, 315 + IncP, 317 + IncP, 240);
Delay(10);
ClearDevice;
End;
SetTextJustify(230, GetMaxY Div 2);
OutTextXY(220,GetMaxY Div 2,'The chop is on its way!');
Delay(1000);
ClearDevice;
Randomize;
IncP := Random(GetMaxX) + 1;
IncQ := 0;
DecrP := False;
DecrQ := False;
For Radius := 1 to MaxInt do
Begin
If not(DecrP) then Inc(IncP,3) Else
If DecrP then Dec(IncP,3);
If not(DecrQ) then Inc(IncQ,3) Else
If DecrQ then Dec(IncQ,3);
SetColor(LightCyan);
{Now FillCircle! - same radii (20)}
FillEllipse(IncP,IncQ, 20, 20);
Circle(IncP, IncQ, 40);
PieSlice(IncP, IncQ, 0 + (IncP * 80),
6 + (IncP * 80), 100);
PieSlice(IncP, IncQ, 180 + (IncP * 80),
186 + (IncP * 80), 100);
PieSlice(IncP, IncQ, 90 + (IncP * 80),
96 + (IncP * 80), 100);
PieSlice(IncP, IncQ, 270 + (IncP * 80),
276 + (IncP * 80), 100);
If IncP > GetmaxX then DecrP := True Else
If IncP < 0 then DecrP := False;
If IncQ > GetmaxY then DecrQ := True Else
If IncQ < 0 then DecrQ := False;
Delay(10);
ClearDevice; {Try to remove this :-)}
If KeyPressed then Break;
End;
ReadKey;
SetTextStyle(SansSerifFont,HorizDir,1);
SetUserCharSize(2,1,5,1);
OutTextXy(12,20,'Was it fun? Ehh???');
SetUserCharSize(1,1,2,1);
SetColor(LightCyan);
OutTextXY(35,190,'Now you can try to do it yourself.');
OutTextXY(20,240,'If you have any comments then send');
OutTextXY(180,300,'me an e-mail to');
OutTextXY(120,400,'victorsaliba@hotmail.com');
Readln;
CloseGraph;
End.
Я уверен что вы справились с запуском программы, скомпилировать вам ее удалось, если нет, оставляйте комментарии к статье и мы постараемся вам помочь в этом. Если вы обратили внимание то в программе используются процедуры не описанные выше. Давайте рассмотрим их более подробно.
Расширенное использование графикиПо мимо рассмотренных выше процедур и функций для работы с графикой в паскале существуют так же дополнительные, так сказать мало известные процедуры и функции. К примеру нам нужно заполнить квадрат цветом, делается это так: Circle(GetMaxX Div 2, GetMaxY Div 2, 60); FillEllipse(GetMaxX Div 2, GetMaxY Div 2, 60, 60); {Note the radii} Команда 'FillEllipse "заполнит круг текущим цветом. Давайте посмотрим на таблицу:
Название | Описание | Применение |
SetFillStyle(Pattern, Colour); | Изменяет стиль заполнения объекта. Он может быть использован только с bar/bar3d и pieslice. Имеет 13 различных стилей заливки. | SetFillStyle(XHatchFill,LightCyan); или SetFillStyle(10,3); |
SetUserCharSize(MultX, DivX, MultY, DivY); | Отображение текста большего или меньшего размера. | SetUserCharSize(5,1,3,1); |
SetTextStyle(Font, Direction, Size); | Показать текст с помощью стиля шрифта, ориентация и размер указывается. | SetTextStyle(TriplexFont, HorizDir,2); |
ClearViewPort; | Очищает страницу. В обычном режиме это CLS | ClearViewPort; |
GetDriverName | Получить имя драйвера который используется в данный момент. | OutText('Using driver:' + GetDriverName); |
Теперь мы знаем дополнительные функции работы с графикой в паскале, давайте теперь посмотрим как их можно использовать в своей программе, например:
SetTextStyle(SansSerifFont,VertDir,2);
или
Bar3D(40,50,60,100,50,TopOn);
Program Lesson8_Program3;
Uses Graph;
Var Gd, Gm: Integer;
Begin
Gd := Detect;
InitGraph(Gd, Gm, ' ');
if GraphResult <> grOk then Halt(1);
SetTextStyle(TriplexFont, HorizDir, 1);
SetUserCharSize(2,1,10,1);
SetTextJustify(CenterText, CenterText);
OutTextXY(GetMaxX Div 2,200,'Is it big enough?');
readln;
ClearViewPort;
SetTextStyle(SmallFont, VertDir, 5);
SetTextJustify(LeftText,CenterText);
OutTextXY(200,250,'VertDir (vertical) Direction.
Do you understand now??');
Readln;
ClearViewPort;
Bar3d(150,80,450,330,50,TopOn);
SetTextStyle(SansSerifFont, HorizDir, 2);
SetColor(LightRed);
OutTextXY(130,410,'BAR3D(150,80,350,330,50,TopOn);');
Readln;
ClearViewPort;
Bar3d(150,80,450,330,50,TopOff);
SetColor(LightGreen);
OutTextXY(130,410,'BAR3D(150,80,450,330,50,TopOff);');
Readln;
ClearViewPort;
OutTextXY(130,380,'SetFillStyle(BkSlashFill,7);');
SetFillStyle(BkSlashFill,7);
Bar3d(150,80,450,330,50,TopOn);
OutTextXY(130,410,'BAR3D(150,80,450,330,50,TopOn);');
Readln;
ClearViewPort;
OutTextXY(130,380,'SetFillStyle(XHatchFill,6);');
SetFillStyle(XHatchFill,6);
Bar3d(150,80,450,330,50,TopOn);
OutTextXY(130,410,'BAR3D(150,80,450,330,50,TopOn);');
Readln;
CloseGraph;
End.
В качестве итогов статьи хотелось бы отметить что это всего на всего верхушка айсберга, в работе с графикой Паскаля еще куча интересного и занимательного, но в рамках данной статьи нам это рассмотреть врятли удастся. Статья лиш познакомила вас с основными аспектами работы и показала пару интересных примеров, на их основе можно создавать свои графические программы на языке Pascal.