Menu

Tree [399601] master /
 History

HTTPS access


File Date Author Commit
 assets 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 base64 2017-05-01 jimi15 jimi15 [01fdb1] CameraPointer method refactor, options pages, s...
 doc 2017-06-13 jimi15 jimi15 [399601] Dokumentacja final
 .gitattributes 2017-03-09 Grzegorz Kokoszka Grzegorz Kokoszka [a89670] :lollipop: Added .gitattributes
 .gitignore 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 AIController.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 AIController.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Broadcaster.cpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 Broadcaster.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 ButtonView.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 ButtonView.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 CameraPointer.cpp 2017-06-11 jimi15 jimi15 [95e9c2] Doc readme.md
 CameraPointer.hpp 2017-06-11 jimi15 jimi15 [95e9c2] Doc readme.md
 Client.cpp 2017-06-05 Jakub Mendel Jakub Mendel [443477] H header to HPP
 Client.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Conf.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 Conf.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 ConfCapture.cpp 2017-04-28 jimi15 jimi15 [a86f5d] Configuration refactor
 ConfCapture.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 ConfDetector.cpp 2017-05-09 jimi15 jimi15 [13a3d1] TrackBar refactor, hockey gates, points counting,
 ConfDetector.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 ConfigurationManager.cpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 ConfigurationManager.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Doxyfile 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 DynamicObject2d.cpp 2017-04-28 jimi15 jimi15 [1ac55e] Hockey bounce first slice
 DynamicObject2d.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Gate.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 Gate.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HaveAction.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HaveEnabled.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 HaveEnabled.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HaveFocus.cpp 2017-05-09 jimi15 jimi15 [13a3d1] TrackBar refactor, hockey gates, points counting,
 HaveFocus.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HaveHover.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 HaveHover.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HaveName.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 HaveName.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HavePressed.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 HavePressed.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 HaveVisible.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 HaveVisible.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Hockey.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 Hockey.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 LanControllerClient.cpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 LanControllerClient.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 LanControllerServer.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 LanControllerServer.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuButton.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 MenuButton.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuDefaultsAsk.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuDefaultsAsk.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockey.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuHockey.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockeyConnectServer.cpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 MenuHockeyConnectServer.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockeyCreateServer.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuHockeyCreateServer.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockeyCreateSideBySide.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuHockeyCreateSideBySide.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockeyLobby.cpp 2017-06-03 Grzegorz Kokoszka Grzegorz Kokoszka [f835cd] Lan game first implementations
 MenuHockeyLobby.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockeyMulti.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuHockeyMulti.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuHockeyWin.cpp unknown
 MenuHockeyWin.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuMain.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuMain.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuOptionsFirst.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuOptionsFirst.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuOptionsSecond.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuOptionsSecond.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MenuPaint.cpp 2017-05-19 jimi15 jimi15 [e08132] Some big fix, S refactor
 MenuPaint.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 MousePointer.cpp 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 MousePointer.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Networking.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Object2d.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 Object2d.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Paddle.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 Paddle.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 PaddleController.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Pressable.cpp 2017-05-09 jimi15 jimi15 [13a3d1] TrackBar refactor, hockey gates, points counting,
 Pressable.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Program.cpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 Program.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 Puck.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 Puck.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 S.hpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 Server.cpp 2017-06-05 Jakub Mendel Jakub Mendel [443477] H header to HPP
 Server.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 TextInput.cpp 2017-06-11 jimi15 jimi15 [983b9d] Doku and broadcast fix
 TextInput.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 TrackBar.cpp 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 TrackBar.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 UniCameraPointer.hpp 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 UniPointer.cpp 2017-04-20 jimi15 jimi15 [64177e] Some small fixes, PaddleController
 config.inc 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 main.cpp 2017-04-28 jimi15 jimi15 [a86f5d] Configuration refactor
 makefile 2017-06-10 jimi15 jimi15 [bf39ea] Readme.md for doxygen and some small fixes
 packages.config 2017-04-13 Grzegorz Kokoszka Grzegorz Kokoszka [e5e188] Revert "Separated pong game for testing w/o ope...
 precompiled.sh 2017-06-10 jimi15 jimi15 [49f4b1] AI fix, doxygen comments
 procedura wykrywania 2017-06-03 jimi15 jimi15 [56fc5f] Makefile update
 procedura wykrywania.svg 2017-06-11 jimi15 jimi15 [95e9c2] Doc readme.md
 procedura wykrywania.svg.2017_06_11_17_42_14.0.svg 2017-06-11 jimi15 jimi15 [95e9c2] Doc readme.md
 readme.md 2017-06-12 jimi15 jimi15 [4d569d] Dokumentacja almost done

Read Me

Dokumentacja projektu

Spis treści

Cel projektu

Celem projektu było utworzenie adaptacji gry Air %Hockey napisanej w języku C++ w środowisku 2d, której główną cechą jest sterowanie przy użyciu kamerki internetowej. Miały być zrealizowane trzy tryby gry:
* tryb jednoosobowy z przeciwnikiem sterowanym przez komputer
* tryb dla dwóch graczy przy jednym komputerze
* tryb gry w sieci lokalnej

Sterowanie miało się odbywać przez detekcję jednokolorowych okrągłych wskaźników przy częstotliwości rejestracji klatek pozwalającej na komfortową obsługę. Warstwa graficzna oraz komunikacja sieciowa miała być zrealizowana przez bibliotekę SFML, która jest prosta ale spełniająca nasze wymagania. Komunikacja z kamerką internetową oraz narzędzia do przetwarzania obrazu w czasie rzeczywistym miała być zrealizowana dzięki potężnej bibliotece OpenCV. Pobocznym celem było napisanie prostego interfejsu graficznego dostosowanego do naszych potrzeb z uwagi na nie stosowanie dodatkowych bibliotek rozszerzających SFML np. SFGUI. Dodatkowym celem było napisanie aplikacji działającej na platformie Windows oraz Linux co ułatwiły wybrane przez nas biblioteki.

Dla użytkownika

Wymagania sprzętowe

  • Karta graficzna z obsługą OpenGL >= 2.0
  • Kamerka internetowa z możliwością nastawy ekspozycji oraz FPS >= 25
  • Pamięć RAM >= 1 GB
  • Rozmiar aplikacji ok 10 MB
  • Procesor minimum 2 rdzenie np. Intel® i3-530 2.93 GHz

Wymagania fizyczne (wskaźniki)

Do prawidłowego działania aplikacji potrzebne są jednokolorowe wskaźniki. Kształt zarejestrowanego wskaźnika powinien być okrągły.

Proponowane przez nas wskaźniki to piłeczki pingpongowe z wyciętą dziurą do zakładania na palec (wskazujący oraz kciuk).

Ping pong z dziurą

Dla lepszej wygody i dopasowania można wyścielić dziurę tkaniną, przymocować ją np klejem na gorąco.

2 Ping pongi z tkaniną

Należy pamiętać aby kolor wskaźników był unikatowy w obrębie sceny, co pomoże uniknąć niemożliwych do odfiltrowania szumów tła. Wskaźniki białe również są możliwe do zastosowania lecz wymagają większych starań odnośnie tła (odbicia światła słonecznego i sztuczne źródła światła mogą być źródłem niepożądanych zakłóceń).

Alternatywnie jako wskaźnik można użyć swojego smartphone'a. Należy zaopatrzyć się w odpowiedni obrazek z dwoma jednokolorowymi kołami np. taki:

2 Ping pongi z tkaniną

Instrukcja obsługi

Uruchomienie aplikacji

Wykonywalny plik aplikacji to airhockey.exe (Windows) lub airhockey (Linux). Po jego otworzeniu ukaże się napis:

Nie znaleziono kamery

Jeżeli mamy podłączoną kamerkę to napis powinien zniknąć w ciągu kilku sekund. Jeżeli mimo podłączenia nadal występuje należy dowiedzieć się pod jakim identyfikatorem występuje i spróbować ustawić go w pliku program.conf.

Główne menu

Główne menu pozwala przejść do:
* Podmenu gry Air %Hockey
* Paint testu
* Ustawień

Menu hockey
W menu gry Air %Hockey mamy do wyboru:
* Grę jednoosobową z przeciwnikiem sterowanym przez komputer.
* Grę wieloosobową
* Powrót do menu głównego

Przebieg gry

Widok gry
Na załączonym obrazku przedstawiony jest widok gry w trybie jednoosobowym.

Gra polega na odbijaniu krążka celem zdobycia bramki przeciwnika. Krążek porusza się w środowisku niewielkiego tarcia. Paletka gracza może poruszać się tylko w obszarze własnej połowy. Każda runda rozpoczyna się od umiejscowienia krążka w centrum areny.
Gra kończy się po zdobyciu 10 punktów jednak z wymaganą przewagą 2 punktów.

Koniec gry
Po zakończonej grze możemy powrócić do menu lub zagrać ponownie.

Paint test

Paint test
Paint test służy do testowania działania wskaźników. Zawiera przycisk czyszczenia płótna. Aby przejść do menu głównego należy wcisnąć przycisk Escape.

Menu multiplayer
Z menu gry wieloosobowej możemy przejść do:
* Gry "side by side" - czyli granie przy jednym komputerze dla 2 osób
* Utworzenie serwera LAN
* Połączenie z serwerem LAN

Gra przez LAN

Menu create server
W menu tworzenia serwera możemy ustawić nazwę serwera. Następnie możemy przejść do lobby lub powrócić do wcześniejszego menu.

Server lobby
Obrazek przedstawia widok lobby po stronie serwera. Przycisk play pojawia się wtedy gdy klient wybierze nasz serwer. Po kliknięciu play rozpoczyna się rozgrywka wieloosobowa.

Client server list
Widok listy serwerów po stronie klienta.

Ustawienia

Kalibracja kamerki i detektora

Ustawienia kamerki
Na przedstawionym obrazku widać pierwszą stronę ustawień. Kamerka pracowała w słabym oświetleniu. Źródłem światła była jedynie lampka nocna lecz dzięki odpowiedniej konfiguracji detekcja punktów wskaźnika działa prawidłowo.

Parametry do konfiguracji to:
* Ekspozycja - im wyższa tym dłużej naświetlana jest klatka. Powoduje zwiększenie jasności lecz przy tanich kamerkach także spadek FPS poniżej akceptowalnych wartości.
* Gamma - im wyższa tym ciemniejsze obszary są rozjaśniane, zbyt duża wartość powoduje utratę ogólnego kontrastu.
* Balans bieli - pozwala skompensować nadmierne przesunięcie barw w stronę czerwonego lub niebieskiego
* Przesunięcie barwy - pozwala dokonać dużego przesunięcia barw w przestrzeni HSV. Przydatne gdy wykrywany kolor jest w okolicach początku (czerwony) lub końca (fioletowy). Pozwoli to na lepsze dobranie składowej H niskiej oraz wysokiej
* Składowa detektora H niska - oznacza dolną granicę wykrywanej barwy w przestrzeni HSV
* Składowa detektora H wysoka - oznacza górną granicę wykrywanej barwy w przestrzeni HSV
* Składowa detektora S niska - oznacza dolną granicę wykrywanego nasycenia w przestrzeni HSV
* Składowa detektora S wysoka - oznacza górną granicę wykrywanego nasycenia w przestrzeni HSV
* Składowa detektora V niska - oznacza dolną granicę wykrywanej jasności w przestrzeni HSV
* Składowa detektora V wysoka - oznacza górną granicę wykrywanej jasności w przestrzeni HSV
* Próg ruchu - służy do konfiguracji maski ruchu. Im wyższa wartość tym różnica klatek aktualnej i poprzedniej musi być większa aby maska zadziałała w tych punktach.
* Próg maski okręgu 1 oraz 2 - służy do konfiguracji maski detektora okręgów. Niska wartość powoduje wykrycie większej ilości okręgów. Może powodować spowolnienie procesu przetwarzania.
* Minimalny rozmiar - oznacza minimalny rozmiar wykrywanego punktu. Przydatne do odfiltrowania punktowych szumów mniejszych od właściwego znacznika a które nie mogą zostać wyeliminowane w inny sposób.
* Limit punktów - ogranicza nadmierną ilość wykrytych punktów. Do prawidłowego działania wystarczą 4.

Ustawienia dodatkowe
Druga strona ustawień zawiera następujące opcje:
* Przycisk przełączający wyświetlanie obrazu z kamery w tle
* Przycisk przełączający kolisty obszar kliknięcia wskaźnika
* Przycisk przełączający widok wskaźników w grze
* Przycisk do testowania algorytmu paletki

Plik konfiguracyjny

Przykładowa zawartość pliku konfiguracyjnego

deviceId 0 #Id urządzenia przechwytującego, ręczna konfiguracja może być przydatna gdy jest podłączonych kilka urządzeń przechwytujących obraz.

maxId 5 #Maksymalny id dla pętli auto-wykrywania. Zmiana może być przydatna przy nietypowo wysokim identyfikatorze urządzenia przechwytującego

exposure 299

gamma 180

whiteBalance 5001

hueShift 90

hueLow 80

hueHigh 110

saturationLow 55

saturationHigh 255

valueLow 65

valueHigh 255

moveThreshold 15

circleMaskThreshold1 177

circleMaskThreshold2 88

pointsLimit 4

minimumSize 18.548212

serverName Uw== #Nazwa serwera zakodowana w base64

winSizeX 1039 #Szerokość okna

winSizeY 644 #Wysokość okna

winPosX 0 #Pozycja X okna

winPosY 0 #Pozycja Y okna

leftNick QQ== #Lewy nick zakodowany w base64

rightNick Qg== #Prawy nick zakodowany w base64

pointerClickCircle 1 #Wyświetlanie promienia kliknięcia

pointerInGame 1 #Wyświetlanie wskaźników w grze

videoBackground 1 #Wyświetlanie obrazu z kamerki w grze

Dla programisty

Wykorzystane narzędzia

  • Biblioteki
  • SFML
  • OpenCV

  • Programowanie

  • Eclipse CDT
  • Microsoft Visual Studio
  • make
  • git

  • Tworzenie dokumentacji

  • doxygen
  • medit
  • Libre Office Writer

  • Tworzenie prezentacji

  • Inkscape
  • Microsoft PowerPoint

Założenia programu

Zrealizowane

  • Działanie na platformie Windows oraz Linux dzięki SFML i OpenCV

  • Implementacja algorytmu wykrywania wskaźników z wykorzystaniem biblioteki OpenCV

  • Paint test

  • Gra Air %Hockey

  • Tryb gry jednoosobowej z komputerowym przeciwnikiem
  • Tryb gry wieloosobowej w trybie "side by side" (na jednym komputerze)
  • Podstawowy tryb gry w sieci lokalnej
  • Podstawowa fizyka odbicia krążka uwzględniająca kąt paletki i wartość bezwzględną prędkości liniowej
  • Automatycznie skalowana arena do rozmiaru okna

  • Interfejs graficzny

  • Automatycznie dopasowujące i skalowane menu do okna aplikacji
  • Przycisk z możliwością przypisania akcji jako obiekt std::function<void(const menubutton&)=""></void(const>
  • Menu zbudowane w oparciu o kontener przycisków
  • Jednoliniowe wejściowe pole tekstowe
  • Suwak do nastawy wartości liczbowych, z możliwością ustawienia wskaźnika na docelową zmienną

  • Ustawienia

  • Zapamiętywanie konfiguracji w pliku tekstowym z łatwą możliwością rozbudowy o kolejne parametry
  • Możliwość prostego ustawienia parametrów kamerki
  • Możliwość prostego ustawienia parametrów detektora punktów

Nie zrealizowane

  • Gra Air %Hockey
  • Zaawansowana fizyka odbicia krążka uwzględniająca precyzyjnie wektor prędkości liniowej oraz prędkość kątową
  • Możliwość zmiany strony gry w trybie jednoosobowym oraz wieloosobowym sieciowym
  • Możliwość zmiany ilości potrzebnych punktów do zdobycia
  • Możliwość przełączania gry z przewagą 2 punktów
  • Zaawansowane lobby z funkcją czatu i ustawień rozgrywki

  • Interfejs graficzny

  • Łatwiejszy mechanizm przełączania widoków menu
  • Menu oparte o kontener abstrakcyjnego typu kontrolki

Kompilacja

Wymagania

Aby skompilować projekt należy posiadać następujące biblioteki:
*
SFML >= 2.3.3
* OpenCV >= 3.2
* Video4Linux (tylko dla dystrybucji Linux)

Opcjonalnie można zainstalować doxygen do generacji dokumentacji html.

Linux

Zalecana jest kompilacja z użyciem narzędzia make, które należy zainstalować jeżeli nie jest dostępne.

Dodatkowo wymagany jest kompilator C++ obsługujący standard C++11. Zaleca się użycie g++6.

Instalacja pakietów dla dystrybucji wywodzących się z Debiana:

sudo apt-get install build-essential libsfml-dev libv4l-dev libopencv-dev

Jeżeli wersja biblioteki OpenCV w repozytorium jest nieodpowiednia należy przeprowadzić kompilacje biblioteki ze źródeł OpenCV GIT.

Po udanej kompilacji należy pamiętać o uruchomieniu komendy ldconfig jako root.

Następnie należy przejść do katalogu z kodem źródłowym:

cd NAZWA_KATALOGU_ŹRÓDŁOWEGO

make PH=off ARG=-O3

Użycie PH=off powoduje że nie zostaną utworzone prekompilowane nagłówki natomiast ARG=-O3 przekazuje dodatkową flagę optymalizacji 3 stopnia do kompilatora.

Po udanej kompilacji powinien zostać wygenerowany plik binarny airhockey

Można go uruchomić z terminala, znajdując się w tym samym katalogu:

./airhockey

Dodatkowe możliwości pliku makefile:

Usuwanie plików *.o

make clean

Usuwanie plików .o oraz prekompilowane nagłówki .gch i pomocnicze .md5

make cleanall

Import projektu do Eclipse CDT

Wybieramy:

File > Import... > C/C++ > Existing code as Makefile Project

Wybieramy lokacje kodu źródłowego oraz zaznaczamy język C++ oraz Toolchain for Indexer Settings na Linux GCC

Po imporcie ustawiamy plik wykonywalny

Run > Run Configurations... > C/C++ Application > (PPM) New

Następnie wpisujemy nazwę pliku:

airhockey

Możemy także usprawnić naszą kompilacje przez użycie wielu rdzeni:

Projekt > Properties > C/C++ Build
Odznaczamy Use default build command i dla 4 rdzeni wpisujemy w build commmand:
make -j4

Windows

Kompilacja dla systemów Windows może być przeprowadzona w Visual Studio.

Na początku należy utworzyć nowy pusty projekt C++ a następnie przejść do ustawień:

Project > NAZWA_PROJEKTU properties

C/C++ > General

Okno ustawień projektu

W Additional Include Directories dodajemy katalog include z SFML.

Następnie przechodzimy do ustawień:

Linker > Input

Okno ustawień linkera

W Additional Dependencies należy ustawić następujące pliki:

sfml-graphics-d.lib

sfml-main-d.lib

sfml-system-d.lib

sfml-window-d.lib

sfml-network-d.lib

Dla kompilacji release należy wybrać analogiczne pliki bez końcówki -d

Okno ustawień plików biblioteki

Dalej przechodzimy do ustawień:

Linker > General

W Additional Library Directories dodajemy katalog lib z SFML.

Okno ustawień katalogu biblioteki

Bibliotekę OpenCV można zainstalować przez NuGet:

Tools > NuGet Package Manager > Package Manager Console

Wpisujemy komendę:

Install-Package OpenCV -Version 2.4.11

Konsola nuget

Ostatnią czynnością jest dodanie wszystkich plików źródłowych .hpp i .cpp.

Działanie programu

Aplikacja działa w oparciu o pętlę programu wykonywaną w wątku głównym a także pętlę wykonywaną w wątku pomocniczym.

Decyzja o zastosowaniu dodatkowego wątku została podjęta z uwagi na fakt, że odczyt ramki z kamerki internetowej odbywa się w stosunkowo długim czasie co mogłoby spowodować utratę płynności działania aplikacji.

Uproszczony diagram głównej pętli

Diagram pętli głównej

Główny wątek odpowiada za odczytywanie zdarzeń z okna i reakcją na nie. Dokonywane jest nawiązanie połączenia z kamerką internetową i nastawa jej parametrów. Dodatkowo w nim są aktualizowane wszystkie obiekty potrzebne w aktualnym widoku. Jest tam między innymi obsługa elementów interfejsu graficznego jak i obsługa komunikacji sieciowej. Ostatnią czynnością jest wyrysowanie wszystkich obiektów na scenie i wyświetlenie wygenerowanej klatki.

Uproszczony diagram pętli wątku pomocniczego

Diagram pętli pomocniczej

Pomocniczy wątek odpowiada za odczytanie klatki z urządzenia przechwytującego a następnie przeprowadzenie detekcji punktów wskaźnika lub dwóch wskaźników w zależności od stanu aplikacji.

Diagram algorytmu detekcji wskaźników

Algorytm część 1

Algorytm część 2

Na powyższych rysunkach przedstawiono w uproszczony sposób algorytmu detekcji wskaźników.
Metody OpenCV warte uwagi:
*
cv::absdiff - do wyznaczania absolutnej różnicy pomiędzy dwoma ramkami
* cv::cvtColor - do konwersji przestrzeni barw
* cv::threshold - do progowania ramki
* cv::erode - do operacji erozji
* cv::dilate - do operacji rozszerzania
* cv::bitwise_or - do bitowej sumy dwóch ramek
* cv::bitwise_and - do bitowego iloczynu dwóch ramek
* cv::inRange - do selekcji kolorów
* cv::HoughCircles - do wykrywania okręgów
* cv::SimpleBlobDetector - do do wykrywania jednobarwnych plam

Detekcja kolizji krążka z paletką

Detekcja kolizji krążka z obróconą paletką może być nieco problematyczna. Istnieje natomiast prosty sposób jak to osiągnąć. Zamiast obracać prostokąt (paletkę) należy obrócić krążek pod tym samym kątem pod którym obrócilibyśmy paletkę. Możemy to osiągnąć za pomocą następujących wzorów:

x’ = cos(theta) * (cxoriginX) – sin(theta) * (cyoriginY) + originX

y’ = sin(theta) * (cxoriginX) + cos(theta) * (cyoriginY) + originY

Na poniższym rysunku został przedstawiony ten proces. Niebieskie elementy to te które gracz widzi na ekranie, natomiast obliczenia są przeprowadzane dla elementów o kolorze czarnym.

Obrazowanie 1

Następnie za pomocą prostych instrukcji warunkowych należy znaleźć punkt na paletce, który jest najbliżej środka krążka. Ostatnim krokiem jest sprawdzenie odległości między tym punktem, a środkiem krążka za pomocą twierdzenia Pitagorasa. Jeżeli odległość ta jest mniejsza od promienia krążka, to oznacza, że nastąpiła kolizja.

Obrazowanie 2

Obliczanie kąta odbicia

Do obliczenia nowego kąta piłki po odbiciu zastosowaliśmy obliczenia wektorowe. Kąt pod którym leci piłka rozbijamy na postać wektorową, na składową x oraz y.

x = cos(angle);

y = cos(angle);

Następnie tworzymy 2 nowe wektory. Wektor u, który jest prostopadły do obiektu, z którym nastąpiła kolizja oraz wektor w równoległy do tej ściany.
Te wektory uzyskujemy za pomocą wzorów:

u = (v · n / n · n) * n

w = vu

vn

Gdzie n oznacza wektor siły prostopadłej do ściany.
Posiadając już te 2 wektory możemy uzyskać wektor piłki po odbiciu (v' = w - u) oraz przekształcić go do postaci kątowej.

vuw