Średni · lekcja 21

Projekt 2: Kolorowy zgadywacz — gra w Angularze z zapisem wyników

Drugi projekt jest lżejszy niż kalkulator BMI — skupia się głównie na logice front-endowej (Angular) i dynamicznym stylowaniu elementów, z prostym zapisem najlepszego wyniku na backendzie. To dobre ćwiczenie przed dużym, trzecim projektem (system zamówień).

Zacznij tutaj

Po co się tego uczymy?

Drugi projekt jest lżejszy niż kalkulator BMI — skupia się głównie na logice front-endowej (Angular) i dynamicznym stylowaniu elementów, z prostym zapisem najlepszego wyniku na backendzie. To dobre ćwiczenie przed dużym, trzecim projektem (system zamówień).

Wprowadzenie

Teoria

Zasady gry: aplikacja pokazuje losowo wybrany kolor SŁOWNIE (np. "Kliknij: NIEBIESKI"), a użytkownik musi kliknąć odpowiedni przycisk spośród kilku kolorowych kwadratów. Poprawna odpowiedź zwiększa wynik, błędna — nie. Po każdej odpowiedzi losowane jest kolejne pytanie. Po zakończeniu rundy (np. 10 pytań) wynik jest wysyłany do backendu i zapisywany jako próba do rankingu najlepszych wyników.

Kluczowe mechanizmy Angulara ćwiczone w tym projekcie:

  • Dynamiczne stylowanie przez [style.background-color]="kolor.kodHex" — wiązanie właściwości bezpośrednio do stylu CSS elementu, sterowane danymi z TypeScript (rozszerzenie [property binding] z lekcji 9);
  • Generowanie losowych danych — Math.random() (wbudowana funkcja JavaScript/TypeScript) do wyboru losowego koloru i przetasowania kolejności przycisków;
  • @for z track (lekcja 9) do wyrenderowania dynamicznej liczby przycisków kolorów z tablicy;
  • Stan gry w polach klasy (aktualne pytanie, wynik, licznik pytań, flaga "gra zakończona") — ten sam wzorzec "jedno źródło prawdy w komponencie", co w Blazor czy w PageModel z Razor Pages.

Zapis wyniku na backendzie. Po zakończeniu rundy Angular wysyła POST z liczbą punktów do prostego kontrolera WynikiController, a osobna strona/zakładka "Ranking" (GET /api/wyniki?limit=10) pokazuje 10 najlepszych wyników posortowanych malejąco — dokładnie ten sam wzorzec CRUD/API, którego uczyłeś się od lekcji 11.

Zobacz zależności

Schemat

Start rundy: wynik = 0, pytanie = 1, losujNastepnePytanie()

losujNastepnePytanie():
  szukanyKolor = kolory[Math.floor(Math.random() * kolory.length)]
  przetasowaneKolory = [...kolory].sort(() => Math.random() - 0.5)

Widok:
  <p>Kliknij: {{ szukanyKolor.nazwa }}</p>
  @for (k of przetasowaneKolory; track k.nazwa) {
    <button [style.background-color]="k.kodHex"
            (click)="sprawdzOdpowiedz(k)"></button>
  }

sprawdzOdpowiedz(wybrany):
  jeśli wybrany === szukanyKolor → wynik++
  pytanie++
  jeśli pytanie > 10 → zakonczRunde()
  w przeciwnym razie → losujNastepnePytanie()

zakonczRunde():
  this.http.post("/api/wyniki", { punkty: wynik }).subscribe(...)
  pokazEkranKoncowy = true

Połącz z praktyką

Przykład z życia

Ten typ prostej gry quizowej z natychmiastową informacją zwrotną i rankingiem wyników to wzorzec spotykany w niezliczonych aplikacjach edukacyjnych i rozrywkowych — łącznie z systemem testów na samej stronie bitedu.pl, gdzie też losuje się pytania i zlicza poprawne odpowiedzi.