Gra memory

Podstawowe założenia gry

W tym rozdziale zajmiemy się stworzeniem prostej gry "memory". Gra taka polega na odkrywaniu par obrazków.

Tradycyjnie rozpiszmy zasadę działania naszej gry:

  1. Domyślnie plansza gry jest nieaktywna. Kliknięcie na start aktywuje planszę.

  2. Plansza składa się z x na y kafelków

  3. Kliknięcie na kafelek odsłania go.

  4. Jeżeli drugi kliknięty kafelek jest taki sam jak pierwszy, wtedy oba tiles zostają usunięte z planszy.

  5. Jeżeli drugi kliknięty kafelek jest różny od pierwszego, wtedy oba tiles są zasłaniane i zwiększany jest licznik prób.

  6. Gra kończy się z chwilą usunięcia wszystkich kafelków z planszy

HTML i CSS

Szkielet aplikacji będzie bardzo prosty. Sprowadzać się będzie tylko do planszy, punktacji i przycisku startującego grę. Reszta to czysta dynamika napisana w JavaScript.

Pokaż HTML Pokaż CSS

Planszę naszej gry ustawiamy za pomocą grida. Dzięki temu łatwiej będzie nam reagować na mniejsze ekrany.

Piszemy silnik gry

Naszą grę stworzymy jako pojedynczy obiekt. Zaczniemy od stworzenia podstawowych zmiennych określających planszę i wygląd poszczególnych klocków.

W tablicy tiles będziemy przechowywać "typ" poszczególnych kafelków. Typy te będą występowały parami i będą określać po prostu numer obrazka dla danego kafelka.

W zmiennej tilesImg przechowujemy grafiki dla poszczególnych klocków. Przykładowe obrazki kafelków znajdziesz poniżej (paczuszkę pobierzesz tutaj):

Jakiś czas temu wpadła mi w oko też inna kolekcja, która znajduje się pod adresem: https://www.iconarchive.com/show/childrens-book-animals-icons-by-iconarchive.html

metoda startGame()

Metodą jaką napiszemy na początku będzie startGame().

Pierwszym zadaniem, jakie musi zrobić nasza startująca funkcja to czyszczenie wszystkich zmiennych (nasza gra może rozpoczynać się kilka razy) i stworzenie pomieszanej tablicy par numerów dla kafelków:

Po stworzeniu tablicy z numerami kafelków, możemy na jej podstawie wstawić tiles na planszę:

Po kliknięciu na dany kafelek będziemy pobierać numer który został jemu przypisany. Numer taki musimy więc gdzieś przechować. Idealnie do tego celu nadaje się właściwość dataset.

metoda tileClick()

Po kliknięciu na dany kafelek odpalamy metodę tileClick():

Na samym początku sprawdzamy, czy dany kafelek nie jest już wcześniej kliknięty (czyli czy nie jest wrzucony do tablicy tilesChecked).

Jeżeli nie jest, a index klikniętego elementu nie występuje już w tablicy (nasza tablica będzie mogła zawierać maksymalnie 2 elementy, więc wystarczy sprawdzić jej 1 element), wtedy możemy go do niej dodać (zapobiegnie to sytuacji, gdy 2x klikniemy ten sam element).

Dodatkowo przy dodawaniu elementu do tablicy ustawiamy mu odpowiednie tło, którego numer pobieramy z dataset danego kafelka.

Następuje wybranie 2 kafelka. Jeżeli "cardType" obydwu elementów tablicy tilesChecked jest taki sam, znaczy to, że para kafelków została dopasowana. Odpalamy więc funkcję deleteTiles(). Jeżeli cardType jest różne, znaczy to że tiles są różne, więc musimy je ukryć na nowo. Służy do tego metoda resetTiles(). Obie metody odpalamy z opóźnieniem 500ms, tak by wybrane tiles nie ukrywały się od razu:

W postaci takiej jak powyższa nasz skrypt nie będzie działał prawidłowo. Wyobraź sobie sytuację: gracz wybiera 2 tiles, zostaje odpalona z opóźnieniem funkcja deleteTiles() lub resetTiles(). Jednak w tym samym czasie gracz może spokojnie klikać resztę kafelków i nasze działania zostają zakłócone. Aby to naprawić dodamy do naszego skryptu dodatkową zmienną canGet, która wyłączy możliwość klikania na czas usuwania lub resetowania kafelków:

metoda deleteTiles()

Jak widać powyżej, jeżeli oba pobrane tiles mają taki sam cartType, wtedy odpalamy funkcję deleteTiles().

Kafelki do usunięcia znajdują się teraz w tablicy tilesChecked. Wystarczy je więc usunąć za pomocą metody remove(), po czym na nowo ustawić tablicę tilesChecked.

Nasza plansza ustawia elementy za pomocą grida. Gdy usuniemy jakiś kafelek, wszystkie przesuną się o jedno miejsce. Tego nie chcemy, dlatego na miejsce usuniętego kafalka musimy wstawić jakiś element.

metoda resetTiles()

Funkcja resetująca tiles do stanu zakrytego jest jeszcze prostsza. Oba tiles wracają po prostu do stanu początkowego, po czym tak samo jak powyżej ustawiamy na nowo tablicę tilesChecked i zmienną canGet.

Pokazywanie liczby ruchów

Ostatnimi rzeczami którymi się zajmiemy to pokazywanie graczowi liczby ruchów które wykonał oraz zakończenie gry.

Liczenie ruchów to nic trudnego. Przy każdym kliknięciu na kafelek po prostu zwiększamy zmienną moveCount, a wynik wypisujemy w elemencie divScore:

Koniec gry

Pozostało nam do wykonania sprawdzenie czy użytkownik nie odkrył wszystkich kafelków i tym samym nie zakończył gry. Wystarczy wprowadzić dodatkową zmienną, w której będziemy przechowywać liczbę odkrytych par. Jeżeli liczba ta będzie większa lub równa połowie wszystkich kafelków znaczy to, że gra została zakończona. Oczywiście sprawdzenie takie wykonujemy tylko przy usunięciu kafelków z planszy:

Przy czym alert() wydaje się najbardziej biednym sposobem pokazywania zakończenia gry. Już lepiej pokazać wcześniej przygotowany element np. korzystając z template, lub też przenieść użytkownika na inną stronę:

Tak jak poprzednio, nie zapomnijmy wyzerować naszej zmiennej przy starcie gry

Naszą pracę kończymy podpięciem pod przycisk rozpoczęcia gry:

Cały kod

Cały kod naszej aplikacji wygląda teraz tak:

Last updated