Сайт Koder.kz сайт для Delphi программистов.

koder.kz

Web or desctop App Developer

Написать

Добавил 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.