Przewodnik po DelphiX

 

Ten przewodnik jest poświęcony zestawie komponentów do programowania pod DirectX w Object Pascalu (potocznie Delphi). Można go ściągnąć z tego miejsca. Cały artykuł będę opierał na kodach źródłowych z Delphi 5. Przewodnik jest adresowany raczej do początkujących osób gdyż DelphiX nie pozwala na pisanie aplikacji 3d i skomplikowanych 2d z jednego prostego powodu - jest za wolne.

DelphiX składa się z 12 komponentów. Opiszę je teraz.

- DXDraw. Jest to podstawowy komponent. Jest jakby obszarem na którym wszystko jest rysowane. Aplikacja może mieć poand jeden taki obszar.
Właściwości: (wybrane)

  • align - "wyrównanie" czyli położenie na formie

  • AutoInitialize - czy komponent sam ma się inicjować (przygotowywać do pracy), zalecam ustawienie na true.

  • Constraints - ograniczenia rozmiaru.

  • Display - ustawienia rozdzielczości, głębi koloru itp. (używane w trybie pełnoekranowym)

  • Options: (wszystkie właściwości typu boolean)

    • doFullScreen - określa czy aplikacja ma pracować na pełnym ekranie

    • doNoWindowChange - zabrania (jeśli ustawione na true) zmianę stanu okna (maksymalizacja, minimalizacja, przywrócenie)

    • doAllowReboot - blokuje (po ustawieniu na false) użycie klawiszy Crtl+Alt+Delete

    • doWaitVBlank - oczekuje na powrót plamki (likwiduje efekt migotania obrazu)

    • doAllowPalette - pozwala na użycie wszystkich 256 kolorów z palety na pełnym ekranie

    • doSystemMemory - powierzchnia jest zarezerwowana w pamięci systemowej

    • doStrecth - powierzchnia jest rysowana na ekranie proporcjonalnie do rozmiaru komponentu

    • doCenter - powierzchnia jest wyświetlana na środku komponentu

    • doFlip - automatyczne wywoływanie metody DXDraw.Flip

    • do3D - Direct3D jest używany

    • doHardware - użycie akceleracji sprzętowej

    • doRetainedMode - użycie trybu Retained (tryb w którym operujemy tylko na modelach resztę wykonuje za nas Direct3D)

    • doSelectDriver - DirectDraw jest domyślnie użyty na pełnym ekranie. Jeśli chcesz użyć Voodoo itp. ustaw tą właściwość na true.

    • doZBuffer - czy użyć Z Bufferingu

  • Surface Height, Surface Width - rozmiar powierzchni (obszaru na którym rysuje)

  • Surface - powierzchnia którą można traktować jako ekran na którym rysujemy. Wszystko co jest tutaj narysowane zostaje przenoszone do pamęci karty graficznej przez procedure Flip którą później opiszę. Najczęściej używane właściwości i metody to:
    • Canvas - płótno, na nim rysujemy bezpośrednio, dzięki standardowym procedurom możemy rysować koła, linnie, kwadrat itp, oraz wypisywać tekst metodą TextOut.


    • procedure Fill(DevCol:LongInt) - wypełnia jednym kolorem całe płótno, najczęściej używane do czyszczenia ekranu

Metody: (wybrane)

  • procedure Initialize - procedura inicjująca działanie DXDraw.

  • procedure Flip - kopiuje zawartość powierzchni na ekran. UWAGA!!! Przed wywołaniem tej metody koniecznie wywołać metodę Canvas.Release gdyż bez tego system nie rysuje albo się zawiesza.

- DXDIB. Nie będę opisywał tego komponentu gdyż, nie jest on używany do programowania gier. Opis tego komponentu wykracza poza ramy tego kursu.

- DXImageList. Ten komponent służy do przechowywania bitmap których będziemy używać do rysowania na powierzchni DXDraw. Bitmapy możemy dodawać do niego przed kompilacja używając odpowiedniej właściwości w Object Inspectorze. Są również dwie metody dynamiczne na dodanie bitmap do listy, pierwsza z nich jest to odczytanie ze strumienia (pliku) elementów zapisanych w specjalnym formacie *.dxg. Drugi sposób to wywoływanie procedury dodającej nowy element do listy. Tak samo jak komponent DXDraw tak i DXImageList jest wymagany w każdej aplikacji (tutaj grze) jaką piszemy za pomocą DelphiX.
Właściwości:

  • DXDraw - określa komponent typu TDXDraw na którego powierzchni będą rysowane bitmap

  • Items - właściwość typu TPictureCollection która zawiera listę bitmap w postaci typu TPictureCollectionItem:

    • Name - właściwość typu string określająca nazwę bitmapy

    • Transparent, TransparentColor - ustala czy obrazek ma przezroczyste punkty jeśli tak to jakiego koloru (druga właściwość)

    • PatternHeight, PatternWidth - rozmiar pattern'a. Pattern można nazwać pojedynczym prostokątem który jest klatką animacji. Animacje 2d w DirectX są w postaci wielu bitmap (klatek), które są sklejone bokami. Rozmiar Pattern'a to rozmiar pojedynczej klatki (bitmapy przed sklejeniem) który jest potrzebny do rysowania wybranej klatki, procedura oblicza sobie obszar bitmapy który ma narysować.

    • function Find(const Name: string) : TPictureCollectionItem - funkcja przeszukująca listę bitmap w poszukiwaniu elementu o nazwie podanej w parametrze. Wynikiem funkcji jest bitmapa, jeśli nie znajdzie żadnej pasującej do nazwy generowany jest wyjątek

    • function IndexOf(const Name: string) : integer - funkcja podobna do poprzedniej z tą różnicą, że ta zwraca index bitmapy

    • procedure Draw(Dest:TDirectDrawSurface; X, Y, PatternIndex: Integer) - procedura która rysuje Item'a na powierzchni przekazywanej w pierwszym parametrze (Dest), X i Y jak można się domyślić to położenie na ekranie. Ostatni parametr to Index Pattern'a czyli klatki. Po opis Pattern odsyłam trochę wyżej.

    • procedure DrawRotate(Dest: TDirectDrawSurface; X, Y, Width, Height, PatternIndex: Integer; CenterX, CenterY: Double; Angle: Integer); - procedura podobna do poprzedniej ale trochę bardziej rozszerzona. Pierwsze trzy parametry są takie same jak w poprzedniej. Width, Height to rozmiar bitmapy, PatternIndex został wyjaśniony wyżej. CenterX i CenterY są chyba najtrudniejszymi do wyjaśnienia parametrami, ale jakoś spróbuję to prosto wyjaśnić. Jak zapewne zauważyłeś są to typy 'ułamkowe', maksymalną wartość jaką mogą przyjąć to 1. Te dwa parametry określają punkt o jaki bitmapa ma zostać obrócona. Punkt jest podawany nie jako 'zwykłe' współrzędne X i Y, ale przesunięcie względem lewego górnego rogu bitmapy wyrażone w ułamku rozmiaru bitmapy. Dlaczego jest to takie zamotane? Spytaj autora DelphiX. ;-) Mały przykładzik do tego co napisałem i wzór:
      załóżmy że rozmiar bitmapy to 50x50, chcemy rysować obrót o środek tej bitmapy to podajemy CenterX = 0.5 i CenterY = 0.5 czyli połowa wysokości i połowa szerokości (25x25) i mamy środek bitmapy względem lewego górnego rogu. Wnioskując można opracować mały wzór, jeśli mamy położenie w pikselach punktu obrotu, i chcemy obliczyć CenterX i CeneterY to robimy tak:
      CenterX = PictureWidth / Położenie_X
      CenterY = PictureHeight / Położenie_Y
      Mam nadzieje, że to jest jasne, starałem się jak najprościej to opisać. Dalej mamy Angle, czyli kąt o który następuje obrót. UWAGA! Kąta nie podajemy w stopniach! Kąt obrotu to wartość z przedziału 0..255. Czyli kąt 0 = 0, 60 = 42.5, 90 = 63.75, 120 = 85, 360 = 255, itd.

    • procedure DrawAlpha(Dest: TDirectDrawSurface; const DestRect: TRect; PatternIndex: Integer; Alpha:Integer) - procedura pozwalająca rysować przezroczyście, używająca metody Alpha Blendingu. Pierwszy parametr jest znany. Drugi parametr jest obszarem na którym będzie rysowana bitmapa. PatternIndex również jest znany. Alpha określa przezroczystość w przedziale od 0 (w ogóle nie będzie rysowana) do 255 (rysowana tak samo, jak metodą Draw). UWAGA! Aby metoda DrawAlpha miała jakiś sens paleta kolorów musi być większa niż 8-bit, w przeciwnym wypadku będzie rysowana tak, że Alpha = 0, nie rysowana w ogóle, Alpha > 0 rysowana tak samo jak w metodzie Draw.

    • procedure DrawAdd(Dest: TDirectDrawSurface; const DestRect: TRect; PatternIndex: Integer; Alpha: Integer=255) - procedura która dodaje wartości pixeli z obrazka który mamy narysować i powierzchni na której rysujemy

    • procedure DrawRotateAlpha(Dest: TDirectDrawSurface; X, Y, Width, Height, PatternIndex: Integer; CenterX, CenterY: Double; Angle,Alpha: Integer) - to chyba jest procedura z największą liczbą parametrów w DelphiX. ;-)) Jest to połączenie obracania bitmapy i przezroczystości. Myślę, że cała składnia jest znana.

    • procedure DrawWaveX(Dest: TDirectDrawSurface; X, Y, Width, Height, PatternIndex, amp, Len,ph: Integer) - procedura rysująca bitmapę 'pofalowaną' w poziomie. Efekt dość ciężko opisać więc najlepiej go zobaczyć. Sześć pierwszych parametrów jest znane. Do wyjaśnienia następnych parametrów posłużę się rysunkiem zamieszczonym w pomocy DelphiX:
      Rysunek wyjaœniajšcy parametry
      Pozostaje jeszcze jeden parametr - Ph. Objaśnię go prostym językiem, nie używając specjalistycznych określeń. Jest to odległość pierwszego 'wygarbienia' fali od dołu bitmapy. Czyli jeśli chcemy uzyskać efekt falowania (przesuwania się tego 'wygarbienia) to musimy cały czas zwiększać parametr Ph.

    • procedure DrawWaveXAdd, procedure DrawWaveXAlpha - są to połączone poprzednie procedury

    • SystemMemory - właściwość określająca użycie pamięci systemowej. Efekt użycia pamięci systemowej jest taki, że rysowanie bitmap przebiega szybciej ale dla bardzo dużych bitmap (ponad 1500x1500 pikseli) system może się zawieszać

- DX3D. Jak wspomniałem na wstępie DelphiX nie nadaje się do pisania gier 3d więc nie będę opisywał tutaj tego komponentu.

- DXSound. Jest jakby odpowiednikiem DXDraw w dźwięku, do tego komponentu "wysyłamy" dźwięki które mają być odtworzone, ten komponent inicjuje kartę dźwiękową itd. Pozwala na użycie DirectSound.

Celowo pomijam tutaj opis właściwości lub metod gdyż są one bardzo żadko używane.

- DXWave. Tutaj sytuacja powtarza się dokładnie tak samo jak w DXDIB. DXWave raczej nie używa się w programowaniu gier więc pomijam tutaj jego opis.

- DXWaveList. Jest to odpowiednik DXImageList. W tym komponencie jest przechowywana lista plików typu *.wav.
Właściwości: (wybrane)

  • DXSound - Określa komponent typu TDXSound za pomocą którego będą odtwarzane dźwięki które są dodane do listy.
  • Items - właściwość typu TWaveCollection która zawiera listę bitmap w postaci typu TWaveCollectionItem:

    • Name, function Find(const Name: string): TWaveListItem, procedure IndexOf (const Name: string): Integer - te procedury, funkcje i właściwości opisałem w opisie DXImageList.

    • procedure Play(Wait:Boolean) - właściwość typu string określająca nazwę bitmapy

    • procedure Stop - zatrzymuje odtwarzanie

    • Frequency - właściwość typu integer

    • Looped - właściwość typu boolean określająca czy odtwarzanie danego dzwięku ma być powtarzane

    • Pan - właściwość typu integer określająca balans dzwięku, przyjmuje wartości od -10000 do 10000.

    • Volume - właściwość typu integer określająca głośność dźwięku, przyjmuje wartości od -10000 do 0.

- DXInput. Jest to komponent odpowiedzialny za obsługę urządzeń wejścia używanych do sterowania grą, np. klawiatura, mysz, joystick.

Podstawową metodą jest Update. Ta metoda uaktualnia stan klawiszy klawiatury, muszy, pozycję wskaźnika myszy itd. Najczęściej wykorzystywane właściwości do sprawdzania stanu urządzeń wejściowych:

  • Keyboard.Keys[kod_klawisza] - właściwość typu boolean określająca czy klawisz o kodzie wyrażonym w nawiasach kwadratowych (index tablicy) jest wciśnięty (gdy true)

  • Mouse.x, Mouse.y - wektory o jakie przesunoł się wskaźnik myszy od ostatniego wywołania procedury Update.

  • Mouse.Buttons[numer_klawisza] - właściwość typu boolean, określająca czy klawisz myszy o numerze podanym jako index tabeli jest wciśnięty.

- DXPlay. Komponent który można wykorzystać do zaprogramowania gry sieciowej, ale nie polecam tego gdyż z niewiadomych mi przyczyn często się wiesza i gryzie z niektórymi kartami sieciowymi. Polecam użycie Socketów. I dlatego nie opisze tego komponentu tutaj.

- DXSpriteEngine. Moim zdaniem jest to najgorszy składnik DelphiX. Nie dość ze ma bardzo małe możliwości to jeszcze jest strasznie wolny. NIGDY nie polecam używać tego komponentu i nie będę go tutaj opisywał bo to nie ma sensu.

- DXTimer. Jest to udoskonalony standardowy timer Delphi. Jest o wiele szybszy i posiada jedna przydatną właściwość:

FrameRate - ilość klatek na sekundę

Po opis innych właściwości odsyłam do opisów standardowych timer'ów.

W trakcie pisania doszedłem do wniosku, że nie ma sensu dołączać przykładowego kodu źródłowego gdyż wszystko jest bardzo dobrze opisane w przykładach dołączonych do DelphiX. Z tych przykładów i z helpa DelphiX czerpie całą wiedze o tych komponentach. {albo z kursu, który znajdziecie tu za miesiąc ;) - Heniu}

(c) 2001 by GREK - www.warsztat.px.pl