Dzisiaj zajmiemy się napisaniem kolejnej gry - znanego wszystkim z komórek Nokii, Snake'a. Wykorzystamy kod, który napisaliśmy już przy okazji Tetrisa.
Nauczymy się także korzystać z przestrzeni nazw System.Generics, która
zawiera typowe struktury danych, takie jak stos, kolejka czy lista. My
wykorzystamy listę dwukierunkową (LinkedList<>).
Na początku trochę o tej właśnie liście. Jej deklaracja wygląda następująco:
System.Generics.LinkedList<T> nazwa_zmiennej;
T jest typem przechowywanych wartości. W tej strukturze danych
przechowywane są elementy LinkdeListNode, które zawierają właściwe
zmienne, które chcemy pamiętać (właściwość Value - jest ona typu T).
Dane są ułożone w określonej kolejności. Każdy element wie jaki jest jego
poprzednik i następnik (właściwości Next, Previous). Sama lista
posiada z góry zdefiniowane właściwości, z których możemy swobodnie korzystać. Przechowuje
ona np. swój początek oraz koniec (właściwości First oraz Last).
W tej strukturze danych dzięki połączeniu pomiędzy sąsiednimi elementami, możemy dostać się do dowolnej
wartości przesuwając się po elementach w prawo lub w lewo. Mamy do dyspozycji szereg metod do obsługi listy. Między innymi
AddFirst, AddNext, Find, Remove. Po szczegóły odsyłam
do dokumentacji
MSDN. LinkedList będziemy używać do przechowywania węża w
naszej grze. Jest to dość intuicyjne. Pierwszy element odpowiada głowie, a
kolejne - kolejnym segmentom gada. Ostatni z elementów to końcówka ogona.
Zajmijmy się teraz grą. Tworzymy nowy projekt, nazywamy go Snake.
Zmieniamy nazwę formy na frmSnake, we właściwości Text wpisujemy
Snake. Rozmiary ustawiamy na 371x200, AutoSizeMode na
GrowAndShrink, a MaximizeBox na false - nie chcemy, aby można
było zmieniać rozmiar lub maksymalizować okno aplikacji. Do formy dodajemy 5
etykiet. Dwie z nich nazywamy lblPoziom i lblPunkty, nazwy
pozostałych są nieistotne. Zmieniamy położenie lblPoziom na 325x9 i
wpisujemy tekst 9. Umiejscowienie lblPunkty to 325x32, tekst to
0 (zero). Do dwóch z pozostałych etykiet wpisujemy Poziom i Punkty,
a lokacje ustawiamy odpowiednio na 281x9 oraz 281x32. Do ostatniej kontrolki
wpisujemy:
Enter - Start
Spacja - Pauza
Escape - Koniec
1...9 - Poziom
Posłuży nam ona ze legendę. Jej położenie to 381x84. Teraz dodajemy
kontrolkę Timer i nadajemy jej nazwę licznik - będzie ona
licznikiem czasu. Na końcu ustawiamy jeszcze właściwość formy
KeyPreview na true. Dzięki temu forma będzie przechwycać zdarzenia
powiązane z klawiaturą od wszystkich kontrolek w niej zawartych. To na razie tyle jeśli
chodzi o wygląd aplikacji. Przejdźmy teraz do stworzenia klasy reprezentującej
planszę do gry.

Najpierw dodajemy do projektu pliki, których używaliśmy przy okazji tworzenia
Tetrisa - kratka.cs i Plansza.cs, artykuł ten znajdziemy tutaj. Dokonujemy niewielkiej modyfikacji w kratka
- zmieniamy stałą wymiar na 10. Następnie tworzymy nową klasę i nazywamy ją
Plansza_Snake. Klasa ta będzie dziedziczyć po klasie Plansza
(podobnie jak Plansza_Tetris w Tetrisie). Plansza reprezentuje
podstawowe okno gry. Można w niej rysować poszczególne kratki, odświeżyć lub
wyczyścić ekran. Dopiero Plansza_Snake będzie zawierać węża, metody
służące do poruszania nim i pilnujące zasad gry. Jednak zanim się nią
zajmiemy, stwórzmy klasę Waz. Oto jej pełna treść: