Tworzenie gier: SAPER
Pobierz kod SAPER
Opisywana gra została utworzona w Delphi7. Zasady gry są znane i myślę, że nie trzeba ich przytaczać. Najciekawszym elementem gry z punktu
widzenia oprogramowania jest odsłanianie niezaminowanych pól.
Przygotowanie formatki
Formatka powinna zawierać komponenty:
- TMainMenu- opcje programu
- TPanel- tu będziemy wyświetlać ilość znalezionych min, czas gry oraz buźki
- TImage- sześć sztuk; trzy
umieszczone w TPanel do wyświetlania wyżej opisanego oraz trzy komponenty TImage służące jako zasobniki grafiki; z tych zasobów będziemy wycinać interesujące nas fragmenty bitmap
Opis klasy TPlansza
Czytelniku, jeżeli nie znasz programowania obiektowego, to masz kłopot. Tego musisz nauczyć się sam, czy to z książki, czy z kursów. Polecam forum www.unit1.pl
Deklaracja klasy znajduje się w dołączonym kodzie do artykułu tu jedynie opiszę wybrane jej metody
Tym konstruktorem tworzymy obiekt TPlansza który jest zmodyfikowanym potomkiem TImage . Podczas tworzenia podmieniamy standardowe metody obsługi kliknięcia i zwolnienia klawisza myszki. Konkretnie robimy to tu:
Procedury MouseDown i MouseUp oprogramowujemy pod kątem akcji związanych z grą i nie będę tu ich opisywać, w kodzie programu znajduje się komentarz do wybranych linii. Podczas tworzenia obiektu TPlansza tworzymy zmienną bmp typu TBitmap. Zmienna ta będzie przechowywać pobrane obrazy klatek pól, min. W momencie gdy cała plansza zostanie narysowana to wyświetlimy ją na ekranie procedurą TPlansza.RysujPlansze w przypadku rozpoczynania rozgrywki. Podczas trwania gry stan planszy zmienia się, gdy klikamy myszką w określony obszar. Naturalnym pomysłem jest zmiana wyglądu planszy tylko w tym obszarze. W kodzie programu znajdziesz Czytelniku procedurę BitBlt. Użycie tej procedury pozwala wkleić fragment bitmapy w określony obszar. Skoro TPlansza jest potomkiem TImage wykorzystamy to tak
przykładowo:
dla
k:=3;
w:=4;
KafelW:=16;
KafelH:=16;
Kafel obszar x:=3*16= 48, y:=4*16=64 zostanie wklejony fragment bitmapy metoda srcCopy z pozycji x:=32, y:=0;
Następnie należy odświeżyć stan planszy- czyli nasz obraz. Komponent TImage posiada metodę odświeżająca rysowanie- Repaint. I to jest cała tajemnica rysowania. Nie przerysowujemy całej planszy gry a jedynie ten obszar, w którym doszło do zmiany grafiki. To podejście ma znaczenie przy dużych światach gry.
Losowe budowanie planszy
Kod programu zawiera tablicę plansz typu: początkujący, średnio zaawansowany, ekspert
Mapa:array[0..2,0..2]of byte=
((10,10,10),
(16,16,40),
(30,16,99)
);
Przykładowo poziom ekspert to (30,16,99) czyli: 30 kolumn, 16 wierszy i 99 min. Teraz jedynie należy wylosować pozycję min i zapamiętać wynik w odpowiedniej kolumnie i wierszu. Cały układ wylosowanej planszy pamiętany jest w tej tablicy:
PoleMinowe:array of array of tKafel;
gdzie tKafel to typ rekordowy
Losowanie min odbywa się
Tablica PoleMinowe[w,k] przechowuje informacje o stanie pola związanego z miną i nie decyduje o rysowaniu planszy w sposób bezpośredni. Plansza wyjściowo zawsze jest rysowana z jednego elementu graficznego
który jest wycinany z poniższego graficznego zasobu
W zależności jak toczy się gra na plansze są odpowiednio wklejane inne fragmenty zasobu ja do tego celu użyłem wcześniej wymienionej procedury BitBlt
W tej tablicy również dzieje się rozgrywka na zasadzie pamiętania i sprawdzania stanu pola. Aby odczytać, w którym polu kliknięto wystarczy współrzędne kursora myszy odpowiednio podzielić przez szerokość lub wysokość kafla. Kolumnę odczytamy
x div 16 a wiersz y div 16.
Wynik sprawdzenia stanu pola decyduje o losach gry i odbywa się to w tym zdarzeniu
procedure TPlansza.MouseDown(Sender:TObject; Button: TMouseButton; Shift: TShiftState;X, Y: Integer);
Proszę sprawdzić w kodzie programu.
Odkrywanie obszaru niezaminowanego
Każde wewnętrzne pole gry ma po ośmiu sąsiadów, pola skrajne odpowiednio mniej. W grze należy sprawdzić z iloma minami sąsiaduje dane pole. Sąsiadów danego pola możemy przeglądać na przykład zgodnie z ruchem wskazówek zegara odpowiednio przesuwając indeks wiersz i kolumny względem indeksu aktualnego pola. Skoki indeksów wygodnie jest zapisać w dwuwymiarowej tablicy
Funkcji, która to wykonuje
function TPlansza.IleMinSasiednich(aK,aW:integer):byte;
Wynikiem jej działania jest ilość min z którymi sąsiaduje dane pole. Jednocześnie zostaje podjęta decyzja o zmianie koloru czcionki. Oczywiście wynik jej działania ma wpływ na odkrywanie obszaru niezaminowanego.
Ta procedura
procedure TPlansza.OdkryjPustePola(aK,aW,n:integer);
jest odpowiedzialna za odkrywanie terenu i wywoływana jest rekurencyjnie. Proszę prześledzić ciało tej procedury w dołączonym źródle.
Koniec