Tryb graficzny w Pascalu - Helion · 2010. 5. 31. · Komputer może pracować w trybach: q...

16
Komputer może pracować w trybach: graficznym (ang. q graphics mode), tekstowym (ang. q text mode, character mode). Fachowcy nazywają grafikę tworzoną za pomocą Turbo Pascala dla środowiska MS -DOS grafiką BGI (ang. Borland Graphics Interface — interfejs graficzny Borlanda). W Windows stosuje się inny interfejs graficzny — GDI (ang. Graphics Device Inter- face), dlatego też grafikę przeznaczoną dla Windows fachowcy w żargonie nazywają grafiką GDI. Monitor komputera musi mieć odpowiedni sterownik sprzętowy nazywany kartą graficzną lub sterownikiem graficznym. Najważniejsze parametry pracy sterowni- ków to: liczba możliwych do wyświetlenia kolorów (tzw. paleta barw), q rozdzielczość (liczba świecących punktów na ekranie, tzw. pikseli), q ilość pamięci, q parametry procesora graficznego (na kartach grafiki może być zainstalowany q osobny procesor). Standardowe karty graficzne (stare i nowsze) obsługiwane przez Turbo Pascala to m.in.: VGA q (ang. Video Graphics Array) — typowy tryb pracy: rozdzielczość 640×480, 16 kolorów; SVGA q (ang. Super VGA) — typowy tryb pracy: rozdzielczość 800×600, ponad 65 000 barw. 6 Tryb graficzny w Pascalu

Transcript of Tryb graficzny w Pascalu - Helion · 2010. 5. 31. · Komputer może pracować w trybach: q...

  • Komputer może pracować w trybach:

    graficznym (ang. q graphics mode),tekstowym (ang. q text mode, character mode).

    Fachowcy nazywają grafikę tworzoną za pomocą Turbo Pascala dla środowiska MS-DOS grafiką BGI (ang. Borland Graphics Interface — interfejs graficzny Borlanda). W Windows stosuje się inny interfejs graficzny — GDI (ang. Graphics Device Inter-face), dlatego też grafikę przeznaczoną dla Windows fachowcy w żargonie nazywają grafiką GDI.

    Monitor komputera musi mieć odpowiedni sterownik sprzętowy nazywany kartą graficzną lub sterownikiem graficznym. Najważniejsze parametry pracy sterowni-ków to:

    liczba możliwych do wyświetlenia kolorów (tzw. paleta barw), qrozdzielczość (liczba świecących punktów na ekranie, tzw. pikseli), qilość pamięci, q parametry procesora graficznego (na kartach grafiki może być zainstalowany qosobny procesor).

    Standardowe karty graficzne (stare i nowsze) obsługiwane przez Turbo Pascala to m.in.:

    VGA q (ang. Video Graphics Array) — typowy tryb pracy: rozdzielczość 640×480, 16 kolorów; SVGA q (ang. Super VGA) — typowy tryb pracy: rozdzielczość 800×600, ponad 65 000 barw.

    6Tryb graficzny

    w Pascalu

    programowanie_strukturalne.indb 47 2010-05-20 13:20:38

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    48

    6.1. Inicjowanie trybu graficznegoPrzed przystąpieniem do rysowania popatrzmy na okno Turbo Pascala i poczyńmy kilka wyjściowych spostrzeżeń.

    Tryb tekstowy jest trybem domyślnym. Zanim spróbujemy cokolwiek narysować, 1 . należy przełączyć kartę w tryb graficzny. Trybów graficznych (podobnie jak trybów tekstowych) jest więcej niż jeden. 2 . Ten sam rysunek może wyglądać zupełnie inaczej w innym trybie — o innej rozdzielczości.

    Zamiast zatem rozpoczynać tworzenie programu w sposób rutynowy (od klauzuli Uses Crt;), musimy najpierw włączyć tryb graficzny. W kompilatorach Turbo Pascal i Borland Pascal do obsługi tego trybu służą następujące (niezbędne) elementy:

    Uses Graph; { modul z procedurami i funkcjami graficznymi }

    InitGraph(); { procedura — zainicjuj tryb graficzny }

    CloseGraph; { procedura — zamknij tryb graficzny, wroc do trybu tekstowego}

    Procedura CloseGraph() nie potrzebuje dodatkowych informacji, zatem aby zamknąć tryb graficzny, nie musimy podawać w nawiasach żadnych argumentów. Ponieważ jed-nak trybów graficznych może być wiele, między nawiasami procedury InitGraph() powinniśmy umieścić dodatkowe informacje. Najprostszy sposób ich wypełnienia może wyglądać tak:

    Uses Crt, Graph;

    Var Karta, Tryb: Integer;

    BEGIN

    Karta := Detect;

    InitGraph(Karta, Tryb, ‘C:\TP\BGI’);

    — gdzie:

    Var Karta, Tryb: Integer; — deklaracje dwóch zmiennych parametrów (tryb może zmieniać się w trakcie pracy programu);

    Karta — identyfikator sterownika graficznego (ang. Graphics Driver);

    Tryb — tryb graficzny (ang. Graphics Mode — rozdzielczość, liczba kolorów);

    ‘C:\TP\BGI’ — katalog, w którym znajduje się sterownik *.BGI.

    Ponieważ komputery wolą numery niż słowa, wszystkie karty i wszystkie tryby mają predefiniowane przez producenta nazwy karty (np. VGA) i numery (np. dla kart VGA — 9). Jeśli pamiętamy, że karta VGA ma numer 9, a HGC — numer 7, możemy inicjo-wać tryb graficzny, np.:

    Karta := 9;

    InitGraph( Karta, ...

    programowanie_strukturalne.indb 48 2010-05-20 13:20:39

  • 49

    6.1. Inicjowanie trybu graficznego

    Dokładnie taki sam skutek przyniesie wywołanie procedury z użyciem predefiniowa-nej stałej symbolicznej:

    Karta := VGA;

    InitGraph( Karta, ...

    Jeśli jednak zechcemy napisać program w sposób bardziej uniwersalny albo po prostu nie mamy głowy do cyferek, wygodniej namówić komputer, by sam sprawdzał, z jaką kartą ma do czynienia tam, gdzie właśnie został uruchomiony. Służy do tego predefi-niowana stała Detect (równa 0).

    Wpisanie zera do komórki pamięci przeznaczonej na zapamiętanie parametru Kar-ta powoduje automatyczne sprawdzenie przez procedurę InitGraph() i zapamiętanie w tymże miejscu numeru wykrytej karty. Po zadeklarowaniu zmiennych Karta i Tryb, możemy zapisać to tak:

    Var Karta, Tryb: Integer;

    BEGIN

    Karta := Detect;

    InitGraph ( Karta, Tryb, ...

    Przygotowując się do pracy w trybie graficznym, możemy zdać się na ustawienia do-myślne. Procedura InitGraph() automatycznie wybierze tryb o najwyższej możliwej dla danej karty rozdzielczości. Jeśli więc mamy na przykład kartę VGA, uzyskamy identyczny skutek, wpisując następujący kod:

    Karta := VGA;

    Tryb := VGAHi;

    InitGraph ( Karta, Tryb, ...);

    Tryb VGA może być realizowany w wersjach VGAHi, VGAMed, VGALo (High, Me-dium, Low). Oczywiście, tryby graficzne także mają swoje identyfikatory. Przedstawia je tabela 6.1.

    Tabela 6.1. Wyliczenie trybów graficznych dla standardu VGA

    Nazwa symboliczna Identyfikator Rozdzielczość w pikselach

    VGAHi 2 640×480

    VGAMed 1 640×350

    VGALo 0 640×200

    W zależności od wersji albo w podkatalogu ..\BGI, albo w katalogu głównym Turbo Pascal przechowuje pliki sterowników graficznych dla różnych kart. Nazwa pliku wy-nika z nazwy standardu graficznego, który obsługuje, a rozszerzenia mogą być dwa:

    *.BGI q — sterownik grafiki BGI dla DOS,*.CHR q — czcionki graficzne.

    programowanie_strukturalne.indb 49 2010-05-20 13:20:39

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    50

    Jeśli mamy kartę VGA lub SVGA, będzie potrzebny sterownik: EGAVGA.BGI. Ten plik (i ewentualnie pliki z czcionkami graficznymi, jeśli program zamierza pisać) można skopiować do bieżącego katalogu, w którym znajduje się wersja *.EXE programu, któ-ry ma korzystać z trybu graficznego. Jeśli tak zrobimy, wywołanie procedury inicjującej tryb graficzny może wyglądać tak:

    Karta := 9;

    Tryb := 2;

    InitGraph ( Karta, Tryb, {’’ );

    Puste apostrofy oznaczają właśnie „katalog bieżący”. Ponieważ na komputerze autora niniejszego podręcznika Turbo Pascal rezydował na dysku C:, w przykładach ścieżka dostępu do sterownika *.BGI ma postać: ‘C:\TP\BGI’. Użytkownik jednakże powi-nien dostosować zapis do konfiguracji plików i katalogów na swoim komputerze. Poniżej zaprezentowany został prosty przykład grafiki w Turbo Pascalu.

    Listing L601.PASProgram Bazgroly_1;

    Uses Crt, Graph;

    Var Karta, Tryb: Integer;

    BEGIN

    ClrScr;

    WriteLn(‘Tryb tekstowy, czekam 2 sekundy...’);

    Delay(2000);

    Karta:=Detect;

    InitGraph(Karta, Tryb, ‘C:\TP\BGI’);

    OutText(‘Tryb VGAHi, czekam [2 sekundy]...’);

    Line(0,0,200,100);

    Delay(2000);

    Tryb:=Tryb - 1;

    InitGraph(Karta, Tryb, ‘C:\TP\BGI’);

    OutText(‘Tryb VGAMed, czekam na [3 sekundy]...’);

    Line(0,0,200,100);

    Delay(3000);

    Tryb:=Tryb -1;

    InitGraph(Karta, Tryb, ‘C:\TP\BGI’);

    OutText(‘Tryb VGALo, czekam [1.5 sekundy]...’);

    Line(0,0,200,100);

    Delay(1500);

    programowanie_strukturalne.indb 50 2010-05-20 13:20:39

  • 51

    6.2. Procedury graficzne Line() i Circle()

    CloseGraph;

    END.

    Pascal używa do wyprowadzania tekstów w trybach graficznych procedury OutText(). Wynika to z możliwości wyboru czcionek graficznych, czego procedury z grupy Write, doskonale spisujące się ze standardowymi czcionkami w trybie tekstowym, niestety nie potrafią. Program powyżej został napisany i uruchomiony w trybie karty VGA. Zwróćmy uwagę na procedurę Line() rysującą linie proste w domyślnym kolorze ry-sunku — białym, na tle o domyślnym kolorze — czarnym.

    6.2. Procedury graficzne Line() i Circle()Narysujmy na ekranie linię i okrąg. Nazwy procedur graficznych, które będą nam do tego potrzebne, są łatwe do odgadnięcia w sposób intuicyjny — Line() i Circle(). Parametry (argumenty), które musimy im przekazać przy wywołaniu, są też oczywiste.

    Graficzne współrzędne ekranowe dla linii mają postać:

    X1 q — początek linii, współrzędna pozioma (piksele liczone od lewej do prawej);Y1 q — początek linii, współrzędna pionowa (piksele liczone od góry w dół);X2 q — koniec linii, współrzędna pozioma (piksele liczone od lewej do prawej);Y2 q — koniec linii, współrzędna pionowa (piksele liczone od góry w dół).

    Wywołanie będzie mieć postać:

    Line(X1, Y1, X2, Y2);

    Współrzędne ekranowe graficzne (liczone od 0, a nie od 1) dla okręgu mają postać:

    X q — współrzędna ekranowa X środka okręgu (gdzie wbić cyrkiel?);Y q — współrzędna ekranowa Y środka okręgu (gdzie wbić cyrkiel?);R q — długość promienia okręgu w pikselach (jak rozewrzeć cyrkiel?);

    Wywołanie będzie mieć postać:

    Circle(X, Y, R);

    Poniżej zaprezentowano przykładowy program. Po skorygowaniu ścieżki dostępu do modułów graficznych BGI zadziała na każdym komputerze.

    Listing L602.PAS Program Bazgroly_2;

    Uses Crt, Graph;

    Var Karta, Tryb: Integer;

    BEGIN

    Karta := Detect;

    InitGraph(Karta, Tryb, ‘C:\TP\BGI’);

    programowanie_strukturalne.indb 51 2010-05-20 13:20:39

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    52

    If (GraphResult grOk)

    Then WriteLn(‘Nie udalo sie zainicjowac trybu graficznego!’)

    Else

    Begin

    Line(100, 200, 200, 200);

    Line(200, 200, 200, 50);

    Line(200, 50, 100, 200);

    Circle(200, 200, 30);

    End;

    Delay(3000);

    CloseGraph;

    WriteLn(‘Koniec trybu graficznego...’);

    ReadLn;

    END.

    Oprócz oczywistego wykreślania linii i okręgu wykonujemy w tym programie jeszcze jedną ważną rzecz. Sprawdzamy mianowicie, czy tryb graficzny został poprawnie za-inicjowany. Wykonuje to dla nas funkcja GraphResult(), która podaje rezultat próby zainicjowania grafiki. Funkcja tym różni się od procedur, że zwraca w miejsce wywoła-nia wynik swojego działania. Jeślibyśmy nie zastosowali skróconego zapisu wywołania funkcji GraphResult(), ten fragment programu wyglądałby tak:

    Var Rezultat: Integer;

    ...

    Rezultat := GraphResult;

    If (Rezultat grOk)

    Then WriteLn(‘Nie udalo sie zainicjowac trybu graficznego!’)

    Else

    Begin

    Line(100, 200, 200, 200);

    ....

    Stała grOk jest predefiniowana w pliku GRAPH.TPU i oznacza wynik, który powinna zwrócić funkcja GraphResult(), jeśli znajdujemy się w prawidłowo zainicjowanym trybie graficznym.

    programowanie_strukturalne.indb 52 2010-05-20 13:20:39

  • 53

    6.3. Biblioteka graficzna Turbo Pascala: GRAPH.TPU

    6.3. Biblioteka graficzna Turbo Pascala: GRAPH.TPU Zestaw funkcji i procedur graficznych jest zdefiniowany w module GRAPH.TPU. Poni-żej znajduje się pełna lista funkcji i procedur graficznych Turbo Pascala.

    Arc() q — łuk, wycinek okręgu.Bar() q — prostokąt, słupek, na przykład dla wykresów słupkowych.Bar3D() q — słupek niby-trójwymiarowy.Circle() q — okrąg.ClearDevice() q — czyszczenie ekranu graficznego.ClearViewPort() q — czyszczenie okna (część ekranu), w trybie graficznym.CloseGraph() q — zamknij tryb graficzny (wróć do trybu tekstowego). DetectGraph() q — sprawdź, jaką kartę graficzną mamy i w którym trybie graficz-nym właśnie pracujemy.DrawPoly() q — narysuj wielokąt.Ellipse() q — narysuj elipsę.FillEllipse() q — narysuj elipsę wypełnioną wewnątrz.FillPoly() q — narysuj wielokąt wypełniony wewnątrz. FloodFill() q — wypełnij region. Region to zamknięty, ograniczony liniami o innym kolorze obszar ekranu (np. prostokąt, koło, trójkąt itp.). Kształt regio-nu może być dowolny, ale wcześniej, przed zapełnieniem, trzeba określić kolor i wzór wypełniacza.GetArcCoords() q — podaj współrzędne ostatnio rysowanego łuku. GetAspectRatio() q — zwraca współczynniki „skali rysunku” (aspect ratio). Ponieważ proporcje rozdzielczości (w pikselach) po poziomej osi X i po pionowej osi Y są różne dla różnych kart graficznych (porównaj: Hercules i VGA), pozwala na skalowanie rysunku.GetBkColor() q — podaj bieżący kolor tła.GetColor() q — podaj bieżący kolor rysowania.GetDefaultPalette() q — ustaw domyślną paletę kolorów.GetDriverName() q — podaj nazwę sterownika graficznego (karty).GetFillPattern() q — podaj bieżący wzorek wypełniacza.GetFillSettings() q — podaj bieżący kolor i wzorek wypełniacza.GetGraphMode() q — podaj bieżący tryb graficzny.GetImage() q — zapamiętaj rysunek.GetLineSettings() q — podaj bieżący styl linii (ciągła, przerywana, grubość itp.).GetMaxColor() q — podaj najwyższy dostępny numer koloru.

    programowanie_strukturalne.indb 53 2010-05-20 13:20:39

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    54

    GetMaxMode() q — podaj najwyższy dostępny tryb graficzny (o maksymalnej roz-dzielczości).GetMaxX() q — podaj maksymalną wartość współrzędnej X na ekranie.GetMaxY() q — podaj maksymalną wartość współrzędnej Y na ekranie.GetModeName() q — podaj nazwę trybu graficznego.GetModeRange() q — podaj zakres dostępnych trybów graficznych.GetPalette() q — podaj bieżącą paletę kolorów.GetPaletteSize() q — podaj wielkość palety kolorów.GetPixel() q — podaj stan wskazanego punktu na ekranie (jaki ma kolor?). GetTextSettings() q — podaj bieżące ustawienia do wyprowadzania tekstu (współrzędne, kolor, czcionka itp.). GetViewSettings() q — podaj parametry bieżącego okna graficznego (View Port Settings).GetX() q — podaj bieżącą współrzędną X kursora graficznego (niewidocznego).GetY() q — podaj bieżącą współrzędną Y kursora graficznego (niewidocznego). GraphDefaults() q — wróć do domyślnych ustawień trybu graficznego, kursor graficzny na początek ekranu. GraphErrorMsg() q — podaj komunikat (string) o błędzie grafiki w oparciu o po-dany numer.GraphResult() q — wynik zainicjowania trybu graficznego.ImageSize() q — wielkość rysunku.InitGraph() q — zainicjuj tryb graficzny.InstallUserDriver() q — zainstaluj sterownik graficzny użytkownika.InstallUserFont() q — zainstaluj czcionki graficzne użytkownika.Line() q — rysuj linię prostą. LineRel() q — rysuj linię prostą relatywnie do bieżącej pozycji kursora graficznego.LineTo() q — linia od bieżącej pozycji kursora do wskazanego punktu. MoveRel() q — przesuń kursor graficzny relatywnie (w stosunku do pozycji począt-kowej).MoveTo() q — przesuń kursor graficzny do wskazanego punktu.OutText() q — wyprowadź tekst. OutTextXY() q — wyprowadź tekst, począwszy od punktu o zadanych współrzęd-nych X i Y.PieSlice() q — narysuj wycinek wykresu kołowego.PutImage() q — wstaw na ekran rysunek.PutPixel() q — zapal punkt na ekranie.Rectangle() q — narysuj prostokąt.

    programowanie_strukturalne.indb 54 2010-05-20 13:20:39

  • 55

    6.3. Biblioteka graficzna Turbo Pascala: GRAPH.TPU

    RegisterBGIdriver() q — zarejestruj sterownik graficzny BGI.RegisterBGIfont() q — zarejestruj czcionki dla środowiska graficznego.RestoreCrtMode() q — wróć do trybu tekstowego (zwykle na chwilę).Sector() q — narysuj wypełniony wycinek elipsy/okręgu.SetActivePage() q — wybierz aktywną stronę.

    SetAllPalette() q — zmień wszystkie kolory palety na podane.SetAspectRatio() q — ustaw skalę rysunku.SetBkColor() q — ustaw kolor tła.SetColor() q — ustaw kolor rysunku.SetFillPattern() q — ustaw wzór wypełniacza wnętrza figur i regionów.SetFillStyle() q — ustaw rodzaj wypełniacza.SetGraphBufSize() q — ustaw wielkość bufora pamięci dla grafiki.SetGraphMode() q — włącz tryb graficzny.SetLineStyle() q — ustaw rodzaj linii (ciągłe, przerywane, grube itp.).SetPalette() q — ustaw stosowaną paletę barw. SetRGBPalette() q — ustaw paletę trójskładnikową. Każdą barwę można przed-stawić jako kombinację barw elementarnych R = Red (składowa czerwona), G = Green (składowa zielona), B = Blue (składowa niebieska).SetTextJustify() q — ustaw sposób wyrównywania tekstu.SetTextStyle() q — ustaw styl tekstu.SetUserCharSize() q — ustaw wielkość czcionek użytkownika.SetViewPort() q — ustaw okno graficzne na ekranie.SetVisualPage() q — wybierz stronę pamięci karty widoczną na ekranie.SetWriteMode() q — ustaw tryb „nadrysowania” na poprzedni rysunek.TextHeight() q — ustaw wysokość tekstu.TextWidth() q — ustaw szerokość tekstu.

    Wiele sterowników graficznych pozwala na utworzenie w pamięci  kilku stron. Każda z  takich stron  to odwzorowanie  jednego ekranu graficznego. Strona aktywna (Active Page) to ta strona, na której odbywa się rysowanie. Wszystkie operacje mogą odby-wać się wyłącznie w pamięci. Visual Page  lub Visible Page — to ta strona, która jest na bieżąco odwzorowywana na ekranie. Jest to jedna z popularnych technik animacji obrazów (patrz: SetVisualPage()). 

    WSKAZÓWKA

    programowanie_strukturalne.indb 55 2010-05-20 13:20:39

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    56

    Prezentację możliwości biblioteki graficznej zaczniemy od procedur graficznych: Line() (linia), Circle() (okrąg), Rectangle() (prostokąt), Ellipse() (elipsa), PutPixel() (punkt). Na rys. 6.1 poniżej widać efekt działania programu z listingu L603.PAS.

    Listing L603.PASProgram Grafik;

    Uses Graph, Crt;

    Var X1, Y1, X2, Y2, R1, R2: Integer; {zmienne - parametry rysunku}

    Var Karta, Tryb, KodBledu: Integer; {parametry trybu graficznego}

    Var Xmax, Ymax: Integer; {parametry: maksymalne wspolrzedne}

    Var Licznik: Integer;

    BEGIN

    Karta := Detect;

    InitGraph(Karta, Tryb,’C:\TP\BGI’);

    KodBledu := GraphResult;

    If KodBledu = grOk Then

    Begin

    X1:=100; X2:=300; Y1:=100; Y2:=300; R1:=100;

    Line(X1, Y1, X2, Y2);

    ReadKey;

    Rectangle(X1, Y1, X2, Y2);

    Circle(X1, Y1, R1);

    MoveTo(X2, Y2);

    OutText(‘Tekst do wyprowadzenia...’);

    For Licznik:=1 To 100 Do PutPixel((Licznik*3), (Licznik*2), White);

    ReadLn;

    End

    Else WriteLn(‘Klops... Tryb graficzny mi nie wychodzi...’);

    ReadLn;

    CloseGraph;

    END.

    programowanie_strukturalne.indb 56 2010-05-20 13:20:39

  • 57

    6.3. Biblioteka graficzna Turbo Pascala: GRAPH.TPU

    rysunek 6.1. Ekran po uruchomieniu programu w trybie VGAHi

    Nietrudno zauważyć, że zamiast wywoływać funkcje i procedury tak:

    Line(100, 100, 200, 200);

    Circle(100, 200, 300);

    — zastosowaliśmy nieco inną taktykę:

    Var X1, Y1, X2, Y2, R1: Integer;

    ...

    X1:=100; X2:=300; Y1:=100; Y2:=300; R1:=100; R2:=50;

    Line(X1, Y1, X2, Y2);

    Rectangle(X1, Y1, X2, Y2);

    Circle(X1, Y1, R1); ...

    Utworzenie w pamięci zmiennych, a następnie ich przypisywanie w programie nazywa się parametryzacją programu. Wydłuża to trochę kod programu, ale pozwala później autorowi na łatwą i szybką jego modyfikację. Jeśli zechcemy, by obiekty graficzne roz-mieszczone zostały na ekranie w inny sposób, wystarczy zmienić tylko jeden wiersz w kodzie, na przykład:

    X1:=10; X2:=200; Y1:=100; Y2:=300; R1:=20;

    programowanie_strukturalne.indb 57 2010-05-20 13:20:39

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    58

    Rysunek będzie wówczas zupełnie inny. Wart rozważenia jest też następujący fragment:

    MoveTo(X2, Y2);

    OutText(‘Tekst do wyprowadzenia...’);

    For Licznik:=1 To 100 Do PutPixel((Licznik*3), (Licznik*2), White);

    Dochodzi tu do manipulowania niewidocznym z natury kursorem graficznym. Choć pozostaje on niedostrzegalny na ekranie, jego położenie nie jest bez znaczenia. Ko-rzystają z niego zarówno procedury MoveTo(), LineTo(), jak i procedury drukujące tekst. Na przykład procedura MoveTo(X2, Y2); przesuwa kursor graficzny do punktu 300, 300. Od tego właśnie punktu rozpocznie się wyprowadzanie tekstu wskazanego w procedurze OutText(‘Tekst do wyprowadzenia...’);.

    Pętla programowa typu For będzie zapalać kolejne piksele, których współrzędne zosta-ną obliczone za pomocą wyrażeń:

    (Licznik*3) = 3, 6, 9, 12, 15, ...

    (Licznik*2) = 2, 4, 6, 8, 10, ...

    Linia punktowa widoczna na rysunku składa się z takich właśnie pikseli o współ-rzędnych: (3,2), (6,4), (9,6), ... itd., aż do (300, 200). Zamiast prostego wywołania: PutPixel(X, Y, Kolor); użyliśmy i tu wyrażeń matematycznych. Jest to metoda bardzo przydatna przy wykreślaniu wykresów funkcji i innych nietypowych krzywych. Dla wyjaśnienia tych mechanizmów dodajmy do naszego programu elipsę i narysujmy trochę pojedynczych pikseli.

    Listing L604.PASProgram Grafik_2;

    Uses Graph, Crt;

    Var X1, Y1, X2, Y2, R1, R2: Integer; {zmienne - parametry rysunku}

    Var Karta, Tryb, KodBledu: Integer; {parametry trybu graficznego}

    Var Xmax, Ymax: Integer; {parametry: maksymalne wspolrzedne}

    Var Licznik: Integer;

    BEGIN

    Karta := Detect;

    InitGraph(Karta, Tryb, ‘C:\TP\BGI’);

    KodBledu := GraphResult;

    If KodBledu = grOk Then

    Begin

    X1:=100; X2:=150; Y1:=100; Y2:=300; R1:=90; R2:=50;

    Line(X1, Y1, X2, Y2);

    ReadLn;

    programowanie_strukturalne.indb 58 2010-05-20 13:20:39

  • 59

    6.3. Biblioteka graficzna Turbo Pascala: GRAPH.TPU

    Rectangle(X1, Y1, X2, Y2);

    Circle(X2, Y2, R2);

    Ellipse(100, 100, 0, 360, 100, 60);

    Ellipse(100, 100, 0, 180, 50, 30);

    Ellipse(X2, Y2, 45, 279, R1, R2);

    MoveTo(X2+100, Y2);

    OutText(‘Tekst do wyprowadzenia...’);

    Xmax := GetMaxX;

    MoveTo((Xmax div 2), (GetMaxY div 2));

    OutText(‘X

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    60

    Fragment ustawiający tekst na środku ekranu mógłby wyglądać i tak:

    Xmax := GetMaxX Div 2;

    Ymax := GetMaxY Div 2;

    MoveTo(Xmax, Ymax); OutText(‘....’);

    Ponieważ GetMaxX i GetMaxY to funkcje, a nie procedury, zwracają one wyliczoną przez siebie wartość do programu w miejsce, z którego zostały wywołane. Zmiennych pomocniczych Xmax i Ymax do przechowywania wyniku zwróconego przez funkcje nie musimy stosować. Podobnie rzecz się ma z wywołaniem procedury Ellipse(). War-tość zwracana przez funkcje może stać się bezpośrednio argumentem dla innej funkcji lub procedury. Zmienne pomocnicze do przechowywania wartości zwracanych przez funkcje nie są konieczne.

    Ellipse(GetMaxX Div 2, GetMaxY Div 2, 0, Licznik, GetMaxX Div 4, GetMaxY Div 4);

    W procedurze tej pojawiają się wyrażenia matematyczne. Przykładowo wyrażenie:

    GetMaxX Div 2;

    — można wyjaśnić następująco:

    Wywołaj funkcję 1 . GetMaxX() (podaj maksymalną dostępną współrzędną ekrano-wą X). W przypadku emulacji karty VGA funkcja zwróci wartość 639.

    Prototyp funkcji (lub procedury), nazywany również sygnaturą, jest po prostu deklaracją funkcji (procedury). Deklaracja określa typ wartości zwracanej, nazwę i typy argumen-tów. Porównajmy. Oto prototypy, czyli deklaracje:

    Procedure P(X, Y : Integer);

    Function F(X, Y, Z : Real) : Real;

    A to definicje:P(X,Y) — to procedura, F(X,Y,Z) — to funkcja.

    Procedure P(X, Y : Integer);

    Begin

    X := X+Y;

    End;

    Function F(X, Y, Z : Real) : Real;

    Begin

    F := X*T*Z;

    End;

    DEFINICJA

    programowanie_strukturalne.indb 60 2010-05-20 13:20:39

  • 61

    6.3. Biblioteka graficzna Turbo Pascala: GRAPH.TPU

    Podziel zwróconą wartość przez 2 (ewentualnie zaokrąglając do liczby całkowi-2 . tej): 639 / 2 = 319.Wynik podstaw jako parametr przy wywołaniu 3. Ellipse().

    Wywołanie będzie więc równoważne takiemu:

    Ellipse(319, 239, 0, Licznik, 159, 119);

    Licznik będzie się zmieniać: 0, 1, 2, 3, 4, ... . Ponieważ czwarty z kolei parametr ozna-cza kąt końcowy rysowanego wycinka elipsy, będą rysowane wycinki od kąta 0 do kąta końcowego: 0, 1, 2, 3, ... stopnie itd.

    Dzięki temu zobaczymy rysowanie w zwolnionym tempie (rysunek 6.2).

    Var X, Y: Integer; {- wspolrzedne srodka elipsy }

    rysunek 6.2. Elipsy i poprzednie procedury po zmianie parametrów

    To, że współrzędne środka elipsy powinny być liczbami całkowitymi, można wyjaśnić stosunkowo łatwo. Numery poszczególnych pikseli są to liczby całkowite. Ale w pro-totypie procedury Ellipse() jest również coś dziwacznego:

    Var KątStartowy, KątKoncowy: Word;

    Deklaracja takich zmiennych powinna wyglądać nie tak:

    Var Kąt1, Kąt2 : Integer;

    — lecz tak:

    Var Kąt1, Kąt2 : Word;

    programowanie_strukturalne.indb 61 2010-05-20 13:20:40

  • ROZDZIAł 6 t Tryb graficzny w Pascalu

    62

    Czym różni się szesnastobitowa liczba całkowita typu Integer od szesnastobitowej liczby całkowitej typu Word? To proste — brakiem znaku. Liczby typu Word to takie same liczby jak znane już liczby typu Integer, tyle tylko, że zawsze i z całą pewnością są dodatnie (a ściślej: nieujemne).

    Na nośniku elektronicznym umieszczono dodatkowe przykłady programów graficz-nych. Przed kompilacją i uruchomieniem należy sprawdzić, czy ścieżka dostępu do sterownika BGI jest zgodna z położeniem plików na komputerze użytkownika.

    Narysuj na ekranie kopertę, domek i bałwanka.1 .

    ĆWICZENIA

    programowanie_strukturalne.indb 62 2010-05-20 13:20:40