{"id":21879541,"url":"https://github.com/nerooc/qb-3d","last_synced_at":"2026-04-10T23:05:48.104Z","repository":{"id":124517166,"uuid":"380357448","full_name":"nerooc/QB-3D","owner":"nerooc","description":"Project for the 3D graphics subject","archived":false,"fork":false,"pushed_at":"2021-12-15T20:54:51.000Z","size":5730,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-26T18:31:53.518Z","etag":null,"topics":["game","react-three-fiber","zustand"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nerooc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-06-25T21:28:22.000Z","updated_at":"2021-12-15T21:01:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"6a7b5293-1f0d-4c85-910e-590876c3cbc5","html_url":"https://github.com/nerooc/QB-3D","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2FQB-3D","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2FQB-3D/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2FQB-3D/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerooc%2FQB-3D/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nerooc","download_url":"https://codeload.github.com/nerooc/QB-3D/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244885696,"owners_count":20526296,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["game","react-three-fiber","zustand"],"created_at":"2024-11-28T08:17:10.797Z","updated_at":"2026-04-10T23:05:48.070Z","avatar_url":"https://github.com/nerooc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# **QB - React Three Fiber** | Projekt Grafika 3D\n\nTomasz Gajda\n\n\n## 1. Problem i założenia projektu\n\nCelem projektu było stworzenie prostej gry, która dostępna byłaby z poziomu różnorodnych urządzeń. Jako że najłatwiejszą opcją do stworzenia gry międzyplatformowej jest skorzystanie z technologii internetowych - tak właśnie uczyniłem. \n\n**Stos technologiczny:**\n\n\n\n* Typescript\n* React\n* SASS\n* @react-three/fiber\n* zustand\n* netlify\n\n**Pomniejsze wykorzystane biblioteki:**\n\n* react-icons\n* react-device-detect\n\n\n## 2. Krótki wstęp teoretyczny\n\nStworzona gra korzysta z frameworka **React** i wrappera **React-Three-Fiber** który obudowuje zawarte w **Three.js** klasy w komponenty wykorzystywane w React. Biblioteka ta oferuje prostszy interfejs obsługi 3D w Javascript/Typescript nie tracąc przy tym na wydajności.\n\nOprócz tego wykorzystałem preprocesor SASS do stylowania elementów, które tego wymagały w aplikacji (np. **HUD**). Na koniec za pomocą **netlify** i konsolowego interfejsu szybko deployowałem grę do sieci.\n\n\n## 3. Zakres funkcjonalności\n\nZasady gry są dość proste - gracz ma za zadanie omijać sześciany znajdujące się na trasie i przebyć w ten sposób jak **największy** dystans.\n\n### 3.1 Proces gry\n\nKontrolując blok za pomocą strzałek bądź klawiszy “A” oraz “D” (czy też specjalnych przycisków na ekranach mobilnych) gracz musi omijać przeszkody znajdujące się na płaszczyźnie.\n\n![alt_text](https://github.com/nerooc/3d-project/blob/main/src/assets/images/gameScreen.png)\n\nRys. 1 - Główny ekran gry\n\n### 3.2 Zapisywanie wyników\n\nUzyskany wynik jest widoczny w trakcie gry jak i na ekranie po przegranej. Trzy najlepsze wyniki są zapisywane do **localStorage **i wyświetlane na ekranie “Game Over”.\n\n![alt_text](https://github.com/nerooc/3d-project/blob/main/src/assets/images/scoreboard.png)\n\nRys. 2 - Zestaw wyników na ekranie końcowym\n\n### 3.3 Manipulacja muzyką\n\nW grze dodany jest również Soundtrack - za pomocą przycisku w prawym górnym rogu ekranu możemy go włączać/wyłączać w trakcie gry.\n\n![alt_text](https://github.com/nerooc/3d-project/blob/main/src/assets/images/soundBtn.png)\n\n\n![alt_text](https://github.com/nerooc/3d-project/blob/main/src/assets/images/muteBtn.png)\n\n\nRys. 3 - Przycisk, którym możemy manipulować muzyką\n\n\n## 4. Opis implementacji\n\nW aplikacji znajdziemy zbiór komponentów, które wraz z zapisywanym stanem tworzą całą grę:\n\n### 4.1 Stan aplikacji\n\nW folderze “store” znajduje się zapisany stan naszej aplikacji. Do manipulacji stanem w aplikacji wykorzystałem bibliotekę **“zustand”**, czyli rozwiązanie dużo prostsze w użyciu niż popularne aktualnie biblioteki Redux czy też oferowane przez samego React’a Context API. Możemy tam znaleźć wszystkie zmienne przechowywane w stanie. Są one aktualizowane w czasie działania aplikacji.\n\n\n### 4.2 Player\n\nKomponent ten przedstawia model sześcianu, którym steruje gracz oraz wszystkie operacje które manipulują jego pozycją, szybkością poruszania itp. Są tutaj też manipulację kamerą, która powinna podążać za sześcianem.\n\n\n### 4.3 Obstacles\n\nKomponent ten odpowiada za generowanie przeszkód na trasie - sześcianów o losowo wygenerowanej pozycji na płaszczyźnie Z.\n\n\n### 4.4 Ground\n\nKomponent generuje płaszczyznę o teksturze fioletowej siatki, po której porusza się gracz i na której pojawiają się przeszkody.\n\n### 4.5 GameState\n\nPomimo przechowywania stanu gry w innym miejscu, stworzyłem również ten komponent by śledził aktualną sytuację w grze, aktualizował wynik i w przypadku końca gry zmieniał stan.\n\n### 4.6 KeyboardControls\n\nKomponent w pełni poświęcony śledzeniu inputa z klawiatury - na bieżąco zapisuje do stanu, które przyciski są naciskane.\n\n### 4.7 Soundtrack\n\nKomponent obsługujący muzykę zaimplementowaną w grze. Nasłuchuje zmiany na przycisku odpowiadającego za manipulację muzyką w HUD.\n\n### 4.8 HUD\n\nKomponent nakładający HUD na ekran gry - przedstawia wszystkie ważne dla użytkownika informacje w jasny i czytelny sposób. W tym komponencie również sprawdzane jest jakim urządzeniem posługuje się użytkownik - jeśli jest to urządzenie mobilne, renderowane są dodatkowe przycisku do sterowania.\n\n### 4.9 GameOver\n\nKomponent z ekranem “Game Over” - wyświetla wynik aktualnej próby oraz listę najlepszych wyników zapisaną w localStorage.\n\n\n## 5. Podsumowanie i pomysły na rozbudowę\n\nReact-Three-Fiber daje niesamowite możliwości tworzenia gier i aplikacji internetowych przy użyciu całkiem prostego API. Bardzo przyjemnie mi się z nim pracowało, natomiast czas który chciałem poświęcić na stworzenie gry był ograniczony, dlatego też kod nie we wszystkich miejscach wygląda tak jak powinien, a i kilka funkcjonalności, które planowałem na początku nie zostało zaimplementowane: \n\n\n### 5.1 Zmiana trudności\n\nW planach miałem implementację zwiększającego się poziomu trudności - wraz z przekroczeniem kolejnych kamieni milowych (np. 5000 pkt.) ilość przeszkód lub prędkość kierowanego obiektu miały się zwiększyć (dlatego też mamy licznik prędkości w lewym dolnym rogu HUD). \n\n\n### 5.2 Skybox\n\nW tym momencie tło nad płaszczyzną jest czarne - dodaje to klimatu grze, natomiast można by było tam wstawić jakąś ładną grafikę, która pasowałaby do aplikacji. \n\n\n### 5.3 Ładniejsze tekstury\n\nNie jestem największym fanem tego w jaki sposób wyglądają obecnie przeszkody - materiał klocków mógłby być ładniejszy. Można w tym miejscu nawet pobawić się shader’ami. \n\n### 5.4 Lepsza detekcja kolizji\n\nPomimo że wszystkie obiekty są sześcianami, detekcja opiera się na odległości po promieniu okręgu o środku wewnątrz sześcianu - to powoduje że czasami pomimo dotknięcia krawędzi przeszkody uda się nam ujść z życiem.\n\n### 5.5 Wgrywanie customowych modeli\n\nChoć sześcian się wpisuje w kwadratowy wygląd świata przedstawionego, zdecydowanie ciekawym pomysłem byłaby możliwość dodania modelu, którym sterował by gracz zamiast sześcianu.\n\n\n## 6. Literatura\n\nDo stworzenia projektu wykorzystałem głównie **oficjalną dokumentację RTF**, oraz pomniejsze strony służące jako poradniki do obsługi tej biblioteki:\n\n1. [https://docs.pmnd.rs/react-three-fiber/getting-started/introduction](https://docs.pmnd.rs/react-three-fiber/getting-started/introduction)\n2. [https://github.com/pmndrs/react-three-fiber](https://github.com/pmndrs/react-three-fiber)\n3. [https://codesandbox.io/examples/package/react-three-fiber](https://codesandbox.io/examples/package/react-three-fiber)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerooc%2Fqb-3d","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnerooc%2Fqb-3d","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerooc%2Fqb-3d/lists"}