Gra szubienica

Prawie każdy grał w wisielca. Gracz zgaduje ukryte hasło wybierając odpowiednie litery. Jeżeli się pomyli, wtedy dorysowujemy kolejne części szubienicy, aż w końcu nieszczęśnika wieszamy. Podobną zabawę kojarzymy pod nazwą Koło Fortuny - z tym że, tam Magda Masny nikogo nie wieszała. W poniższym tekście postaramy się wykonać coś podobnego.

Podstawowe założenia gry

Na sam początek rozpiszmy działania jakie musimy zakodować:

  1. na samym początku tworzymy html dla elementów gry:

    1. Guzik ze startem gry

    2. Guziki z literkami

    3. Plansza gry zawierająca aktualne hasło i liczbę dostępnych prób

  2. Na początku za pomocą skryptów wypełnimy planszę literkami, które będzie można klikać

  3. Po kliknięciu na przycisk start odpalamy grę. Pobieramy hasło, aktywujemy guziki z literkami, wypisujemy hasło i zerujemy próby

  4. Po każdym wyborze litery sprawdzamy czy jest ona w haśle, wyłączamy dany przycisk z literą (tak by nie można było jej ponownie wybrać) i sprawdzamy próby

  5. Jeżeli próby się skończyły, kończymy grę i wyłączamy przyciski z literkami.

  6. Jeżeli hasło zostało odgadnięte kończymy grę i wyłączamy przyciski z literkami.

Cały wygląd oczywiście zrobimy za pomocą CSS - wykorzystamy do tego CSS3 dzięki czemu poznamy kilka nowych technik :)

HTML i CSS

Na początku realizujemy 1 punkt z naszej listy - czyli tworzymy html dla naszej aplikacji. Jak założyliśmy musimy stworzyć planszę gry zawierającą próby oraz hasło do zgadnięcia.

Pokaż HTML Pokaż CSS

Piszemy silnik gry

Naszą grę napiszemy w formie obiektu. Skrypt rozpoczniemy od utworzenia podstawowych zmiennych, takich jak aktualne hasło, hasła z których będziemy losować i oczywiście pobrane elementy gry na których zaraz będziemy pracować:

Nasza plansza z literami w HTML jest obecnie pusta. Pierwszą rzeczą jaką zrobimy to wypełnienie jej literami. Funkcję taką odpalimy we wspólnej metodzie initBoard(), która odpali nam wszystkie początkowe funkcje:

Kolejnym krokiem jest podpięcie klików pod takie litery. Podobnie jak w innych przypadkach eventów nie będziemy podpinać bezpośrednio pod litery, a pod rodzica:

Do przechowania danej litery wykorzystaliśmy dataset. Na razie po kliknięciu na literę wyłączamy kliknięty element, oraz wypisujemy daną literę w konsoli.

Metoda gameStart()

Mamy przygotowaną planszę. Po kliknięciu na przycisk "Losuj nowe hasło" rozpoczniemy właściwą grę. Posłuży nam do tego metoda gameStart(). Po odpaleniu takiej metody powinniśmy wyzerować wszystkie potrzebne właściwości (u nas tyle jedna - liczba prób). Dodatkowo powinniśmy wylosować nowe hasło do zgadnięcia, pokazać graczowi liczbę prób oraz włączyć litery:

Metody enableLetters() i disableLetters()

Przed rozpoczęciem gry litery powinny być nieklikalne. Dopiero po rozpoczęciu gry powinniśmy umożliwić graczowi ich klikanie. Potrzebujemy do tego 2 metod: enableLetters() i disableLetters():

Żeby przetestować powyższy skrypt podepnijmy pod przycisk "losuj nowe hasło" odpalenie startGame():

Nie mamy jeszcze metod randomSentence() i showAttempts() więc zanim je napiszemy zakomentujmy ich wywołanie w metodzie startGame.

Metoda showAttempts()

Zaczynamy od odkomentowania łatwiejszej metody - showAttempts(), która będzie służyć do pokazywania liczby prób graczowi:

Metoda randomSentence()

Kolejna metoda do odkomentowania to randomSentence(), która wylosuje dla nas nowe hasło, które będziemy zgadywać.

Aby wylosować hasło z tablicy sentences musimy wylosować liczbę z przedziału między dwoma liczbami. Użyjemy do tego wzoru ze strony https://stackoverflow.com/questions/4959975/generate-random-number-between-two-numbers-in-javascript#answer-7228322.

Po wylosowaniu hasła podstawiamy go pod zmienną currentSentence. Pod zmienną currentSentenceLetters podstawiamy litery wylosowanego hasła pozbawione spacji. Gdy użytkownik zgadnie daną literę będziemy ją usuwać właśnie z tej zmiennej. Dzięki temu na samym końcu wystarczy sprawdzić, czy z tej zmiennej zostały usunięte wszystkie litery. Jeżeli tak - hasło zostało odgadnięte.

Zanim jednak do tego dojdziemy, musimy wyczyścić planszę z hasłem (elemSentence) a następnie wygenerować w niej bloki na których będziemy pokazywać dane litery. Ważne jest to, że między słowami znajduje się spacja. Klocek z taką spacją nie powinien mieć ani obramowania ani tła. Uzyskujemy to przez dodanie takiemu blokowi dodatkowej klasy game-sentence-box-space.

Metoda checkLettersInSentence()

Po kliknięciu na literkę powyżej wypisywaliśmy ją w konsoli. Napiszmy teraz metodę checkLettersInSentence() w której sprawdzimy czy kliknięta litera istnieje w haśle. Jeżeli istnieje, zaznaczymy ją na planszy, oraz usuniemy jej wystąpienie ze zmiennej currentSentenceLetters:

Po kliknięciu na literkę wywołujemy powyższą metodę checkLettersInSentence() przekazując jej daną literę.

Metoda ta za pomocą includes sprawdza czy litera ta istnieje w aktualnie wylosowanym haśle czyli currentSentence. Jeżeli istnieje, robimy pętlę po tym haśle i dla liter na planszy które mają odpowiedni indeks wstawiamy daną literę. Dzięki temu pojawiają się one na planszy.

Kolejnym krokiem jest usunięcie wszystkich wystąpień danej litery ze zmiennej currentSentenceLetters. Dzięki temu wystarczy później sprawdzić, czy zmienna ta ma jakieś litery. Jeżeli jest pusta, wszystkie litery zostały odkryte i gracz wygrał.

Do takiego sprawdzenia napiszemy oddzielną metodę isLetterExists().

Jeżeli dana litera nie istnieje w zmiennej currentSentence, odejmujemy liczbę prób i jeżeli wynosi ona 0, pokazujemy zakończenie gry, za co odpowiedzialna będzie metoda gameOver().

Metoda isLetterExists()

Powyższa metoda do sprawdzenia czy istnieją jeszcze jakieś litery w haśle używa metody isLetterExists(). Tak jak było powyżej opisane, wystarczy tutaj sprawdzić, czy w zmiennej currentSentenceLetters istnieją jakieś litery:

Metody gameComplete() i gameOver()

Ostatnie metody jakie napiszemy to zakończenie gry - czy to pozytywne, czy negatywne.

Dla łatwiejszych testów w poniższym demie przy losowaniu w konsoli wypisuję aktualne hasło.

Podsumowanie

Nasza gra nie jest żadnym zaawansowanym tworem. Nie nadaje się do konkursów, bo wystarczy spojrzeć w źródło by znać odpowiedź. Ale jako ciekawostka dla młodszego rodzeństwa - w sam raz. Oczywiście przydała by się ładniejsza, może nieco słodsza oprawa graficzna.

Jak też zauważysz, alert nie za bardzo pasuje do pokazywania informacji o zakończeniu gry. O wiele lepszym rozwiązaniem było by pokazać jakąś dynamicznie tworzoną warstwę z informacją. Może nawet element dialog, który pojawił się w html

Last updated