Fairtris 2: The Ultimate Challenge

0

Tak, wiem, ale możliwość podłączenia klawiatury czy gamepada pod smartfona czy tablet ma może 0.01% użytkowników takich urządzeń. Tak więc absolutnie nie opłaca mi się produkować wersji na mobilki, bo dla tych, którzy musieliby grać dotykowo, musiałbym przerobić całą obsługę menu oraz interfejs rozgrywki, aby pokazywał w których miejscach paluchami stukać. Po prostu to kompletnie nieopłacalne, dlatego na pewno nie zrobię wersji mobilnej. 😛

0

I tak dajesz to za darmo, więc na jedno wychodzi, czy opłacalne, czy nie :]

Port dla chętnych mógłbyś skompilować na Androida, bez żadnego dostosowywania do platformy.

0

Skoro daję za darmo, to tym bardziej nie opłaca mi się poświęcać dziesiątek godzin na port, z którego skorzysta może kilka osób. Repo jest otwarte — chcesz, to bierz kod i portuj na Androida, ja nie mam na to czasu.

1
furious programming napisał(a):

Tak, wiem, ale możliwość podłączenia klawiatury czy gamepada pod smartfona czy tablet ma może 0.01% użytkowników takich urządzeń. Tak więc absolutnie nie opłaca mi się produkować wersji na mobilki, bo dla tych, którzy musieliby grać dotykowo, musiałbym przerobić całą obsługę menu oraz interfejs rozgrywki, aby pokazywał w których miejscach paluchami stukać. Po prostu to kompletnie nieopłacalne, dlatego na pewno nie zrobię wersji mobilnej. 😛

Raczej każdy telefon z Androidem to obsługuje. Sparowałem sobie kiedyś kontroler od Switcha z telefonem i działało bez problemu (i okazało się, że można w jakimś stopniu obsługiwać telefon padem :D).

0

@szatkus1: Jemu raczej chodzi o to, kto w taki sposób korzysta z telefonu/tabletu, a nie kto ma taką techniczną możliwość.

furious programming napisał(a):

Repo jest otwarte — chcesz, to bierz kod i portuj na Androida, ja nie mam na to czasu.

Pewnie. Mógłbym to zrobić.
Ale ja chcę zobaczyć, że Ty też umiesz :]

0
szatkus1 napisał(a):

Raczej każdy telefon z Androidem to obsługuje.

Nie chodzi o to, że nie obsługuje, bo wiem, że obsługuje wszystkie peryferia podłączane po USB i BT, a o to, że szkoda na to czasu. Mi wystarczy tyle, że działa na Windows, maxOS i Linux (i pewnie tez na FreeBSD). To nie jest software komercyjny, tak czy siak mało kto w ogóle się nim zainteresuje.

Gierka jest gotowa, porty na nie-windowsowe platformy w najbliższym czasie zostaną skompilowane — wracam do swojego właściwego projektu (tzn. już wróciłem i dłubię dalej). W najbliższym czasie pojawi się co najmniej jeden release, z bug-fiksami, bo np. hit-test nie działał na Linux i musiałem dorzucić poprawki (na razie czekam na feedback).

0

@Spine

@furious programming: ale do telefonu też można podpiąć kontroler/klawiaturę. Więc można wspierać Androida przynajmniej, żeby się dało grać kontrolerem/klawiaturą.
Platformy mobilne to nie tylko ekran dotykowy :]

Ale wtedy to już trochę przestaje być mobilne. Ciężko byłoby grać np. w autobusie na smartfonie z podpiętą klawiaturą - potrzebne są podobne warunki jak do grania na laptopie.

1

@Manna5: Ale ze specjalnym padem to już wystarczą warunki jak do grania na Nintendo Switch :]

screenshot-20240321085540.png

1

Nowa stabilna wersja — Fairtris 2.1.1

Dodana została obsługa skrótu Alt+Enter, które od teraz również służy do włączenia/wyłączenia ekskluzywnego fullscreenu (można też użyć F11 oraz dwukluku lewym przyciskiem myszy). Zmieniłem też sposób rejestrowania callbacku do hit-testowania — teraz callback rejestrowany jest tuż po utworzeniu okna i jest aktywny całą sesję gry, bez względu na to jaki rozmiar ma okno i w którym trybie działa.

Na Linuksach hit-test nie działał najlepiej (bug wie czemu), po zmianie rozmiaru okna przestawał być wywoływany przez SDL, więc to rozwiązuje problem na tej platformie. Niestety nie całkowicie, dlatego że nadal zmniejszenie rozmiaru okna z desktopowego fullscreenu do okna mniejszego niż ekran powoduje ten sam problem (callback nie jest wywoływany, więc nie da się przesuwać okna), ale nic więcej nie jestem w stanie z tym zrobić — coś SDL nawala w tej kwestii. Na razie czekam na feedback, ale najprawdopodobniej zgłoszę to jaki bug.

1

Ponieważ @furious programming stanowczo odmówił wspierania Androida, nie miałem innego wyjścia...
Musiałem kupić ROG Ally.

Niestety jest jeden problem. Kontroler w grze muszę konfigurować jako klawiaturę - przyciski kontrolera są zmapowane w systemie tak, aby dało się ich używać jako wybrane klawisze normalnej klawiatury. Czyli np. o przycisku B muszę zapomnieć, bo to escape.

IMG_20240324_141552863_HDR.jpg

Kiedy próbuję konfigurować w grze sterowanie jako kontroler, to gra nie reaguje na wciskane przyciski.
Inne gry normalnie widzą kontroler ROG Ally jako kontroler.

IMG_20240324_141127216_HDR.jpg

1
Spine napisał(a):

Ponieważ @furious programming stanowczo odmówił wspierania Androida, nie miałem innego wyjścia...
Musiałem kupić ROG Ally.

Zgrywus. Ale dzięki za testy! 🙃

Niestety jest jeden problem. Kontroler w grze muszę konfigurować jako klawiaturę - przyciski kontrolera są zmapowane w systemie tak, aby dało się ich używać jako wybrane klawisze normalnej klawiatury. Czyli np. o przycisku B muszę zapomnieć, bo to escape.

Cóż — skoro taka jest specyfika tego urządzenia, to nic na to nie poradzę. Tzn. poradziłbym, po prostu tworząc normalny port dla tego urządzenia, biorąc pod uwagę to w jaki sposób działa. Teoretycznie mógłbym odblokować możliwość przypisania klawisza Esc, ale musiałbym najpierw sprawdzić czy nie będzie to kolidować z obsługą menu gry na desktopach. Ten klawisz jest zarezerwowany nie bez powodu — tak samo jak BkSp.

Kiedy próbuję konfigurować w grze sterowanie jako kontroler, to gra nie reaguje na wciskane przyciski.

Konfiguracja sterowania jako kontrolera bazuje na obsłudze kontrolerów z poziomu SDL-a. Aby gra wykryła wciskane triggery, SDL po pierwsze musi widzieć jakiekolwiek urządzenie będące kontrolerem, a po drugie, SDL musi zwracać aktualny stan triggerów kontrolera, kiedy silnik go o nie odpytuje (np. funkcją SDL_JoystickGetButton czy SDL_JoystickGetAxis).

I teraz ciekawostka — jeśli masz możliwość wejścia do menu konfiguracji kontrolera, to znaczy, że SDL widzi co najmniej jedno urządzenie będące kontrolerem i to dobra wiadomość. Gdyby SDL nie wykrywał żadnego kontrolera, opcja konfiguracji mapowania kontrolera byłaby wyszarzona (wejście do tego menu byłoby zablokowane). Natomiast jeśli nie da się przypisać triggerów tego urządzenia do wybranych funkcji w trakcie mapowania, to problemy mogą być dwa:

  1. SDL widzi co najmniej jeden kontroler, ale gdy wciskasz przyciski, to sterownik tego urządzenia generuje zdarzenia wciskania klawiszy, a nie zdarzenia kontrolera. Przez to możesz konfigurować mapowanie klawiatury, ale nie kontrolera, bo SDL nie dostaje komunikatów dotyczących kontrolerów, a więc dane widzianych przez niego kontrolerów cały czas są domyślne.
  2. SDL widzi więcej niż jedno urządzenie będące kontrolerem, a wciskane przez ciebie przyciski i osie nie dotyczą pierwszego widzianego przez SDL-a kontrolera, a drugiego lub kolejnego, czego silnik gry nie sprawdza.

Niestety silnik Fairtrisa został napisany tak, że obsługiwał tylko pierwszy wykryty kontroler i tylko jego input był brany pod uwagę — nowy Fairtris niczego w tym temacie nie zmienia. Ze względu na to, że to w założeniu był pierdołowaty projekt, aby skrócić czas implementacji, zaprogramowałem najprostszy możliwy system obsługi kontrolerów i ich mapowania. No i teraz mamy tego efekty. 🤣

Rozwiązań mamy kilka, zależnie od tego ile czasu zechce się na to poświęcić. Myślę, że sensownym i w miarę przenośnym rozwiązaniem będzie modyfikacja klasy reprezentującej kontroler, tak aby po prostu odpytywała wszystkie dostępne kontrolery i jeśli cokolwiek w którymkolwiek kontrolerze jest wciśnięte, to tego stan zostanie wykorzystany. Powinno to działać zarówno na tym przenośnym urządzeniu, jak i na desktopach.

Inne gry normalnie widzą kontroler ROG Ally jako kontroler.

Pewnie dlatego, że po prostu sprawdzają input wszystkich dostępnych kontrolerów, a nie tylko pierwszego dostępnego. Albo w ogóle mapping mają zrobiony tak, że gra słucha dowolnego input — klawiatury i wszystkich kontrolerów — i pierwsze co się natrafi to przypisuje do wybranej funkcji.

0

Z tego co widzę, klawisz Esc nie musi być klawiszem zarezerwowanym, dlatego że obsługa menu głównego bazuje albo na predefiniowanych klawiszach (strzałki, Enter i Esc), albo na inpucie kontrolera.

Problem jednak jest taki, że jeśli przypiszesz jakąkolwiek funkcję do przycisku B (który emituje zdarzenie wciśnięcia klawisza Esc), to możesz nie być w stanie obsługiwać menu główne. Bo jeśli przypiszesz Esc do przycisku A (choćby przez przypadek), wciśnięcie tego przycisku będzie emitować sprzeczne zdarzenia — wejścia do menu i wyjścia z niego. Silnik zgłupieje, bo obsłuży oba jednocześnie, więc w praktyce stracisz bezpowrotnie możliwość sterowania menu — będzie musiał wyłączyć grę i usunąć plik z ustawieniami.

Nie mam pojęcia dlaczego ta konsola generuje zdarzenia klawiatury, skoro jest konsolą udającą kontroler oraz mającą przyciski i gałki takie jak kontroler. Śmierdzi mi to tym samym debilizmem co w przypadku automatycznych mapperów kontrolerów czy choćby hardware'owym przyciąganiem pozycji gałki do głównych osi (@Spine wiesz w czym rzecz).

Dokładnie takiego samego rodzaju problem miałem przy programowaniu pierwszego Fairtrisa, kiedy testowałem kontroler retrobit, w kształcie kontrolera NES-a (krzyżyk i cztery przyciski, nic więcej). Wciśnięcie kierunku D-Pada generowało zdarzenie D-Pada oraz dodatkowo gałki analogowej, której ten kontroler w ogóle nie miał. WTF.


Coż, Fairtris ma prymitywną obsługę kontrolerów, bo był projektem dla zabawy. Nie wiem czy będzie mi się chciało to zmieniać, bo mam dużo pracy przy swoim projekcie silnika i gry. Może się skuszę na jakąś małą poprawkę, np. dodanie odpytywania wszystkich dostępnych kontrolerów, ale to jeszcze zobaczę.

W silniku do Kidsów system mapowania jest wypasiony, bo wspiera wszystkie podłączone kontrolery, a także daje możliwość przypisania konkretnych urządzeń do konkretnych graczy. Nie ma więc znaczenia ile gamepadów się podłączy, a także ile z nich jeden gracz chce używać, mapowanie może ustawić tak jak tego chce — użyć jednego kontrolera lub rozłożyć sterowanie na kilka urządzeń. Może grać dwoma kontrolerami, kontrolerem i klawiaturą, myszką i klawiaturą, myszką i gamepadem, a nawet wszystkim co w ogóle jest dostępne — część funkcji przypisanych do myszki, część do klawiatury, a inne do jednego lub więcej gamepadów.

0
furious programming napisał(a):

Cóż — skoro taka jest specyfika tego urządzenia, to nic na to nie poradzę. Tzn. poradziłbym, po prostu tworząc normalny port dla tego urządzenia, biorąc pod uwagę to w jaki sposób działa.

furious programming napisał(a):

Nie mam pojęcia dlaczego ta konsola generuje zdarzenia klawiatury, skoro jest konsolą udającą kontroler oraz mającą przyciski i gałki takie jak kontroler.

Tony Hawk's Pro Skater 1+2 ładnie ogarnia temat padów i widzi kontroler jako Xbox.

screenshot-20240324161451.jpg

Może to być też zasługa Steama, który potrafi pośredniczyć w obsłudze kontrolera:

screenshot-20240324162426.png

Moja gierka w Unity ma zrobioną konfigurację sterowania tak aby wszystko łapała (nawet kliknięcia myszy) i też odbiera input z kontrolera jako klawiaturę:

screenshot-20240324161859.png

Tam gdzie nazwa urządzenia jest w ostrych nawiasach, to ustawienia "fabryczne".

0

Jeśli SDL nie otrzymuje danych o inpucie kontrolera (a najwyraźniej nie otrzymuje), to niczego nie jestem w stanie z tym problemem zrobić. Musiałbym zrobić wersję testową, która by sprawdzała input wszystkich dostępnych kontrolerów i wtedy wiedzielibyśmy czy da się ten problem wykluczyć czy nie.

0

Jeszcze sprawdziłem w mojej gierce, czy działają fabryczne ostawienia dla pada.
Działają ;)

Prawy trigger i prawy shoulder robią atak i super atak.

Niestety predefiniowane ustawienia Fairtrisa nie działają dla kontrolera ROG Ally.
Ale to może być tak jak pisałeś. Że powinieneś czytać input ze wszystkich kontrolerów.

0

Cieszę się, ale jeśli chcesz wiedzieć czy Fairtris posiada błędy czy nie, powinieneś sprawdzić jakąkolwiek gierkę stworzoną w SDL. Wtedy bym wiedział czy czytanie input ze wszystkich dostępnych kontrolerów będzie konieczne.

0

Zainstalowałem SuperTux.
Też kontrolera nie widzi i prekonfigurowane mapowanie nie działa.

Ale nie wiemy, czy ta gra nie implementuje mapowania tak samo jak Twoja...

0

Chyba jest nadzieja, jak obejść problem bez wsparcia od developera...
Wywalić apkę od Asusa. Tylko, że wtedy będę miał sam ekran dotykowy - pad nie będzie służył za myszkę i fragment klawiatury.

https://www.asus.com/global/support/faq/1050046/
screenshot-20240324165332.png

Ale skoro Tony Hawk dał radę, to musi być jakiś właściwy sposób/dobra praktyka, żeby obsłużyć ten kontroler.


edit: w mojej gierce dodałem ignorowanie klawiatury dla ustawień po prawej stronie (które w domyśle są dla kontrolera).

image

było:

        void ListenForInput()
        {
            var rebind = rebindInputAction.PerformInteractiveRebinding(0);

a teraz jest:

        void ListenForInput()
        {
            var rebind = rebindInputAction.PerformInteractiveRebinding(0);

            if (isForGamepad)
            {
                rebind.WithControlsExcluding("Keyboard");
                rebind.WithControlsExcluding("Mouse");
            }

Niestety to nie pomogło. Obiekty z flagą isForGamepad nie łapią teraz nic, kiedy wciskam przyciski kontrolera.

0

Przełączyłem Tryb sterowania w Centrum sterowania z Automatycznego na Gamepad i teraz działa.

Prawdopodobnie jak grę się uruchamia przez Steam itp., to ROG Ally automatycznie wie, żeby przejść w tryb gamepada, a takie gierki łyse bez launchera nie wpływają na tryb sterowania.

IMG_20240325_031529296_HDR.jpg

Oczywiście mam zastrzeżenia co do standardowej konfiguracji...

  1. W Tetris przecież nie będę grał analogiem, zmieniłem na d-pad.
  2. Zazwyczaj w grach konsolowych wszystko zatwierdza się przyciskiem south (XBOX - A, PS - Cross). W Fairtrisie na ROG Ally zatwierdzanie fabrycznie idzie klawiszem B.
  3. Binding Start/Select też musiałem zmodyfikować na hamburger/prostokąty.
0
Spine napisał(a):

Oczywiście mam zastrzeżenia co do standardowej konfiguracji...

Silnik nie ma pojęcia jak wygląda podłączony kontroler, ani jak wygląda układ jego przycisków i jakie kody są do tych przycisków przypisane. Mapowanie kontrolera jest hardkodowane, dlatego może, ale nie musi pasować do kontrolera — nie ma automatycznego bindingu. Kody znajdują się tutaj:

const
  CONTROLLER_SCANCODE_BUTTON_UP     = CONTROLLER_SCANCODE_AXIS_Y_NEGATIVE;
  CONTROLLER_SCANCODE_BUTTON_DOWN   = CONTROLLER_SCANCODE_AXIS_Y_POSITIVE;
  CONTROLLER_SCANCODE_BUTTON_LEFT   = CONTROLLER_SCANCODE_AXIS_X_NEGATIVE;
  CONTROLLER_SCANCODE_BUTTON_RIGHT  = CONTROLLER_SCANCODE_AXIS_X_POSITIVE;
  CONTROLLER_SCANCODE_BUTTON_SELECT = CONTROLLER_SCANCODE_BUTTON_8;
  CONTROLLER_SCANCODE_BUTTON_START  = CONTROLLER_SCANCODE_BUTTON_9;
  CONTROLLER_SCANCODE_BUTTON_B      = CONTROLLER_SCANCODE_BUTTON_0;
  CONTROLLER_SCANCODE_BUTTON_A      = CONTROLLER_SCANCODE_BUTTON_1;

Do sterowania domyślnie używane są dwie pierwsze osie, czyli albo gałka analogowa, albo D-Pad — bo jeśli kontroler nie posiada analogu, to D-Pad jest przypisany do osi X i Y (zamiast być POV-em). Do rotacji klocków oraz akceptacji i powrotu w menu przypisane są domyślnie przyciski o kodach 0 i 1, natomiast dla select i start o kodach 8 i 9, na wzór kontrolera z PS.

W poprzedniej wersji tej gry, mapowanie dla kontrolerów domyślnie w ogóle nie było ustawione i chyba wrócę do tego. Pierwsze podłączenie kontrolera wymagać będzie wejścia do menu i ustawienia sobie mapowania (skoro i tak każdy kontroler jest inny). Po ustawieniu i zapisaniu zmian, mapowanie zostanie zapisane w pliku konfiguracyjnym, więc w każdej kolejnej sesji będzie można z niego korzystać, już bez ustawiania czegokolwiek.


Fairtris był pierwotnie pisany z myślą o scenie klasycznego Tetrisa, dlatego domyślne mapowanie zostało ustawione tak, aby pasowało do klonów kontrolerów z NES-a. Te kontrolery mają D-Pad reprezentowany przez osie (nie mają analogów), a przyciski A i B mają odwrotną kolejności niż w ROG Ally — B jest z lewej, A jest z prawej, bo tak wymyśliło Nintendo. Tak mam we wszystkich chińskich klonach, a także w 8bitdo. W dodatku, Nintendo tak zaprogramowało swojego Tetrisa, że przycisk A służy do akceptacji, a B do cofnięcia się w menu — czyli znów na odwrót, nielogicznie.

Nie będę implementował automatycznych bindingów, bo nie mam na to czasu, ale mogę co nieco poprawić, żeby było lepiej. Dwa rozwiązania:

  1. Zmienić domyślne mapowanie. Zamiast osi ustawić hat jako domyślny dla kierunków, bo w końcu kontrolerów z gałkami jest zdecydowanie więcej niż tych bez gałek, a hat jest wygodniejszy do grania. Zamienić kolejność przycisków do rotacji, tak aby pierwszy służył do akceptacji, a drugi do cofania. W końcu konpatybilność z nintendowskim Tetrisem i tak została zerwana.
  2. Nie dostarczać żadnego predefiniowanego mapowania kontrolera — niech domyślnie będzie puste, tak aby gracz musiał samodzielnie ustawić mapowanie, tak jak tego chce, zgodnie z kontrolerem jaki posiada.

Opcja pierwsza wydaje się sensowniejsza — zawsze to lepiej, aby coś tam domyślnie było ustawione. W razie czego nie problem wejść w ustawienia i sobie mapowanie zmienić. Aktualizacja źródeł zajmie minutę, zaraz commita puszczę.

1

Zmieniłem domyślny mapping, tak aby domyślnie kierunki były przypisane do D-Pada, nie do pierwszej osi. Kody przycisków select i start ustawiłem na te bardziej uniwersalne — pasują do ROG Ally i mojego 8bitdo, a także do gamepadów Xboxa. Kody przycisków B i A zostawiłem bez zmian, czyli przycisk o kodzie 0 służy do rotacji odwrotnie do ruchu wskazówek zegara, a o kodzie 1 do rotacji zgodnie z ruchem wskazówek — tak musi być, dla zgodności z nintendowskim Tetrisem. Natomiast zmieniłem ich przeznaczenie, tak aby przycisk o kodzie 0 służył do wyboru menu, a o kodzie 1 do cofnięcia się w menu — niezgodnie z nintendowskim Tetrisem, ale za to zgodnie z logiką.

W nowym release tak będzie domyślnie wyglądał mapping kontrolera i sterowanie menu.

0
furious programming napisał(a):

Nie będę implementował automatycznych bindingów

Spoko. Sporo by było przy tym roboty w pojedynkę.
Unity w swoim InputSystem załatwia sprawę, przynajmniej dla popularnych kontrolerów.

Np. gdy ustawiam bindingi w edytorze, mogę wybrać przypisanie dla konkretnych kontrolerów:

screenshot-20240325172350.png

screenshot-20240325172539.png

Albo ogólnie:

screenshot-20240325172507.png

Oczywiście u siebie ustawiam ogólnie i dany binding działa zarówno pod padem XBOX, jak i PlayStation.

1

SDL posiada automatyczny binding — GameController — ale nie korzystam z tego i nie zamierzam, bo to niczego nie rozwiązuje, a tylko komplikuje wszystko. Nie da się stworzyć mechanizmu, który by zawsze poprawnie przypisywał triggery dowolnego gamepada do odpowiednich funkcji, bo każdy gamepad jest inny i ma różną liczbę i typy triggerów.

SDL wspiera bazę mappingów w formie pliku tekstowego, ale ten ciągle trzeba aktualizować i baza ta tak czy siak nie zawiera danych wszystkich kontrolerów na rynku. Żeby dodać lub zmienić brakujący lub źle określony, trzeba otworzyć ten giga-plik-tekstowy, znaleźć swój gamepad i zmienić dane, albo skorzystać z zewnętrznego narzędzia, stworzyć własny mapping i dopisać go do bazy. Poza tym te bindingi mogą się różnić i różnią się w wielu przypadkach pomiędzy platformami. Tak czy siak robota głupiego.

Dlatego też olewam te automatyczne bindingi i wolę dać graczowi możliwość określenia takiego, jaki mu pasuje. Co z tego, że po podłączeniu gamepada musi wejść do opcji i ustawić sterowanie, skoro robi się to raz. Tak było od zawsze i nikomu to nie przeszkadzało — każdy był zadowolony. I nie dość, że można było ustawić sterowanie absolutnie dowolnego urządzenia, to w dodatku nie wymagało to żadnych aktualizacji, a więc rozwiązanie to działało zawsze, nieważne jak daleko od release'u.

I takie rozwiązanie preferuję — niezależny i nie wymagający aktualizacji system mapowania. Taki system zaimplementowałem w swoim silniku, aby mieć pełen wachlarz możliwości. Każde urządzenie wykrywane przez system jako kontroler może być użyte do grania, nawet jeśli zostanie stworzone 20 lat po wydaniu release'u, bez żadnych aktualizacji i kombinacji.

1

Nowa stabilna wersja — Fairtris 2.1.2

Zawiera poprawkę dotyczącą domyślnego mapowania kontrolerów, przeznaczenia funkcji B i A w kontekście obsługi menu (ich funkcje zostały zamienione miejscami), a także dodałem możliwość pominięcia ekranu początkowego, żeby niecierpliwi nie musieli czekać pięciu sekund na pojawienie się głównego menu gry.

Reszta na razie pozostaje bez zmian, bo śmiga. ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1