Game multiplayer 8-ball two players on internet. Backend: json and sql. Frontend: JavaScript ES5 + Canvas 2D.
Serwer jest autorytetem stan server(anti-cheat).
Rys. 1 — Ekran gry. Od lewej: pasek graczy nad stołem (avatar + login + pula),
stół z rozstawionym trójkątem bil i białą na linii rozbicia, prawy panel: PUNKT UDERZENIA
(duża biała do ustawiania efektu), WBITE BILE (kolejność) i RUNDA.
Pod stołem komunikat stanu „Oczekiwanie na graczy" i przycisk „Usiądź do stołu".
Rys. 2 — Testy silnika strzałów (A–H). Dla każdego strzału silnik raportuje:
trafienie/nietrafienie do łuzy, pozycję końcową i prędkość końcową oraz pełną trajektorię bili.
Testowane scenariusze: wbicie do łuzy narożnej i środkowej (A, F, G, H), odbicie od bandy (B),
toczenie wzdłuż bandy bez wpadnięcia (C, D) i trajektoria z mijaniem łuzy (E).
Konfiguracja stołów (stawka, min. saldo, kolor, Ø bil, czas, wymiary)
pamiec
Aktywny stan gry stołu (bile, miejsca, tura, faza, pula)
bazy
Konto gracza: dane użytkownika (login + hash hasła), stan konta (saldo), ranga (vip)
hash
Hash hasła administratora (bcrypt)
logowanie/_ratelimit/
Liczniki prób (throttling logowania/rejestracji, per IP)
<login>.png
Avatar gracza (opcjonalny, w katalogu głównym)
bilard2.png / bilard3.png
Obrazy dokumentacji (testy fizyki / zrzut ekranu gry)
Rys. 3 — Przepływ: strony PHP → API → magazyn plikowy (JSON/TXT) → panel admina.
3. Zasady gry 8-ball
Rozstawienie: biała na linii rozbicia (x=260), trójkąt 15 bil z czubkiem na x=700;
czarna (8) w środku trójkąta, na rogach bila cała i połówka.
Rozbicie: pierwszy strzał z białej w trójkąt; rozbijającego losuje serwer (mt_rand).
Grupy: gracz, który pierwszy w stanie playing wbije bilę, dostaje jej grupę —
całe (1–7) albo połówki (9–15); przeciwnik dostaje drugą grupę.
Kolejka: wbicie własnej bili = strzał dalej; pudło lub faul = tura przechodzi
na przeciwnika.
Czarna (8): legalna dopiero po wybiciu całej grupy; musi wpaść do łuzy
na przekątnej względem łuzy ostatnio wbitej bili (podświetlona złotym
pierścieniem). Czarna za wcześnie lub do złej łuzy = natychmiastowa przegrana.
Faule (skutek: przeciwnik bierze białą do ręki)
Pierwszy kontakt białej z bilą przeciwnika lub czarną (gdy nielegalna)
Biała nie dotknęła żadnej bili i odbiła się od mniej niż 3 różnych band
Wbicie białej lub bili przeciwnika (bila przeciwnika liczy się dla niego)
Przekroczenie czasu na ruch / limitu czasu na rozegranie strzału
Walkower: przeciwnik opuścił stół lub nie wrócił w 30 s → pula dla obecnego
Rewanż: po stanie finished przycisk „Rewanż" pobiera wpisowe ponownie
4. Geometria stołu i łuzy
Współrzędne fizyki zawsze w układzie logicznym 1000×620 px (sukno od (53,53) do (947,547));
skalowanie ekranu nie zmienia fizyki. Każda z 6 łuz to korytarz-prowadnica z lejkowatymi
szczękami — nie punkt. Bila w korytarzu toczy się po rynience do ciemnej dziury (promień ~25 px)
i dopiero tam znika; ścianki kanału odbijają ją do środka (brak „niewidzialnych band").
Rys. 4 — Geometria stołu: sukno, 6 łuz z numeracją i reguła łuzy na przekątnej dla czarnej.
stały krok symulacji — determinizm na obu klientach
FRICTION
0.997 / krok
tarcie tocznia
RAIL_REST
0.8
współczynnik odbicia od bandy
STOP_V
8 px/s (skal. z Ø)
próg zatrzymania bili
MAX_SPEED
1600 px/s (skal. z Ø)
siła strzału = 1.0
Kolizje bil: sprężyste, z separacją pozycji — separacja nigdy nie wypycha bili
z korytarza łuzy z powrotem na bandę.
Efekt (spin): boczny (x) zakrzywia tor białej przed pierwszym kontaktem;
góra/dół (y) modyfikuje zachowanie po kontakcie (follow/draw). Resetowany po każdym strzale.
Skalowanie: siła strzału i próg zatrzymania skalują się ze średnicą bil
(baza Ø28 px) — bile dowolnej wielkości poruszają się naturalnie.
Toczenie bil: obrót = droga/promień; numery i pasy przetaczają się przez kulę
zgodnie z kierunkiem ruchu (pełne 360°).
Zdarzenia symulacji:pocketed (bila+łuza, w kolejności),
firstHit (pierwszy kontakt białej), rails (zbiór dotkniętych band).
Zdarzenia + pozycje końcowe raportowane do serwera jako wynik strzału.
6. Sterowanie i punkt uderzenia
Akcja
PC
Telefon (dotyk)
Celowanie
myszka ustawia kierunek; linia celu + duch bili + tor odbicia
przeciągnięcie ustawia kierunek i siłę jednym gestem („proca")
Siła strzału
przytrzymaj i ciągnij wzdłuż kija do tyłu (w przód maleje); puść = strzał
jak przy celowaniu
Punkt uderzenia
duża biała w panelu: góra = ciągnij za bilą, dół = cofnij, boki = łuk i efekt na bandzie
Biała w ręku
klik stawia od razu
przeciągnięcie ducha i puszczenie palca stawia
Walidacja serwera pozycji białej (place_cue): w obrębie sukna, nie za blisko łuzy,
nie nachodzi na inną bilę.
7. Multiplayer — maszyna stanów i czas
Rys. 5 — Maszyna stanów stołu.
Limit
Stała / konfiguracja
Skutek
Czas na ruch
turn_time per stół (5–300 s, dom. 30)
faul: tura + biała w ręku przeciwnika
Powrót na stół
SEAT_TIMEOUT = 30 s
miejsce trzymane 30 s; potem zwolnione, w grze = walkower
Wynik strzału
SHOT_TIMEOUT = 150 s
strzał wygasa → faul czasowy
Heartbeat
polling get_status co ~1,2 s
odświeża last_activity gracza
Czas na ruch liczony dopiero po zatrzymaniu wszystkich bil (faza aim) —
pasek czasu pojawia się po symulacji. Wszystkie operacje na stanie atomowe pod flock
(withState) — brak wyścigów zapisu.
8. API — pełne zestawienie akcji
bilard_api.php?table=<id>&action=<akcja> (wymaga sesji; akcje POST wymagają tokenu CSRF)
Siadanie wymaga min_balance; start_game pobiera od obu graczy
blind (wpisowe) → pula = 2× stawka.
Zwycięzca zgarnia całą pulę; przy usunięciu stołu w trakcie gry pula zwracana po połowie.
Saldo w baza/<uid>/stankonta.txt; zapisy pod LOCK_EX.
10. Rangi i kalkulator VIP
Ranga
Nadawana
Przywilej
normal
automatycznie przy rejestracji
—
silver / gold
admin (lista graczy)
odznaka przy loginie
VIP
admin
dynamiczny % szansy wbicia przy celowaniu
Kalkulator VIP (klient, tylko podgląd): dla bilej celowanej liczy tor trafionej bili —
bezpośrednio, po odbiciu od bandy i w kombinacji (bila strącana przez trafioną). Procent wynika
z fizycznego przecięcia toru z gardłem kanału łuzy, kąta wejścia i przeszkód na trasie. Liczone
tylko bile legalne (grupa / dowolne gdy grupy nieprzydzielone). Zielony ≥ 50%, czerwony poniżej;
napis poziomy także w trybie pionowym.
11. Panel administratora (admin.php)
Stoły
Parametr
Zakres
Uwagi
Wpisowe (blind)
≥ 1 zł
pula = 2× stawka
Min. saldo
≥ wpisowe
blokada siadania poniżej progu
Kolor sukna
HEX
sukno, rynienki i cienie liczone z tego koloru
Średnica bil
18–44 px
fizyka skaluje się proporcjonalnie
Czas na ruch
5–300 s
„X s/ruch"
Rozmiar stołu
320–1600 × 280–1400 px
tylko stół — bile okrągłe, UI stały rozmiar (letterbox)
Karty stołów: parametry, gracze 0–2/2, pula na stole, stan; akcje:
Zatrzymaj/Wznów, Podgląd (tryb tylko-do-odczytu), Usuń.
Lista graczy: login, saldo, aktualny stół, dropdown rangi.
Świeża instalacja tworzy 1 stół. Ostrzeżenie przy domyślnym haśle admina.
Interfejs gry
Pasek graczy u góry: avatar + login + grupa + miniatury bil; aktywny gracz
ma migoczące złote obramowanie avatara; pośrodku pula i przycisk ZASADY GRY.
Panel pod stołem: punkt uderzenia, wbite bile w kolejności, runda/ruch.
Pasek info: kolejka, faule, biała w ręku, ruch bil, stan gry.
„Rozpocznij grę" — przycisk na środku stołu; po zakończeniu = „Rewanż".
Tryb pionowy (telefon): gdy ekran wyższy niż szerszy na urządzeniu mobilnym,
stół renderuje się obrócony o −90°, dopasowany do ekranu. Cienie/refleksy kompensują obrót
(światło zostaje ekranowe), napisy i % VIP są kontr-obrócone. Na komputerze zawsze poziomo.
12. Warstwa bezpieczeństwa
(plik6).php wspólny moduł dołączany przez każdy publiczny plik PHP:
Licencja domenowa (anty-kradzież): skrypt działa tylko na domenach z listy
SEC_LICENSED_HOSTS; wpis .domena obejmuje wszystkie subdomeny.
Nielicencjonowana domena → HTTP 403.
Sesja: ciasteczko HttpOnly + SameSite=Lax + secure (HTTPS),
use_strict_mode, regeneracja ID po zalogowaniu.
CSRF: token sesji wymagany we wszystkich akcjach zmieniających stan
(formularze, API admina, API gry).
Rate limiting: logowanie admina 5/5 min, logowanie gracza 8/5 min,
rejestracja 5/10 min — liczniki per IP w baza/_ratelimit/.
Nagłówki: X-Frame-Options, nosniff, Referrer-Policy (także w .htaccess).
.htaccess: blokada listingu, plików ukrytych, rozszerzeń danych
(.txt .json .hash .bak .zip …) oraz katalogów plik specyfikacja.html .