Fairtris 2: The Ultimate Challenge

8

screenshot-20240316213016.png

Release dla Windows 64-bitFairtris_2.0.0.20_release.zip

Repozytoriumhttps://github.com/furious-programming/Fairtris-2-UC
Fairtris 2: wikihttps://github.com/furious-programming/Fairtris-2-UC/wiki


Fairtris 2: The Ultimate Chllenge to kolejne odsłona gry Fairtris, tym razem już nie w formie narzędzia do testowania różnych mechanik i generatorów, a jako normalna gra wideo. Silnik pozostał ten sam, ale został unowocześniony, dodałem sporo usprawnień i poprawek (w tym łatek błędów), a także otrzymał nową szatę graficzną, zdecydowanie ładniejszą niż ta poprzednika — graficzny skok z NES do SNES.

Nowa wersja niemal całkowicie zrywa z kompatybilnością z NES-em, usunięte zostały niemal wszystkie ficzery, które istnieją w Nintendo Tetris®, a pozostały tylko te dające najlepszą responsywność sterowania oraz najwięcej zabawy. Fairtris 2 nie posiada ograniczenia co do długości rozgrywki, takiego jak wersja na NES-a — największa wspierana szybkość opadania klocków została nieco obniżona, aby dało się grać w nieskończoność. Dzięki temu możesz grać tak długo jak tylko potrafisz.

Zgodnie z nowymi osiągnięciami graczy klasycznej odsłony, dodałem wsparcie zglitchowanych palet kolorów dla stosu i klocków, które używane są na poziomach od 138 do 255. Ostatecznym wyzwaniem jest dojście do poziomu 255 i jego pobicie, które zostanie nagrodzone niespodzianką. Dojście do poziomu 256 zajmuje około półtorej godziny jest bardzo trudne, szczególnie przez bardzo nieprzyjazne zglitchowane kolory klocków na niektórych poziomach.

Mechanika sterowania została ujednolicona i wybrane zostały tylko najlepsze funkcje, a także dodana jest opcja ustawienia szybkości automatycznego przesuwania klocków, dostępna w ustawieniach gry. Nowy Fairtris w dalszym ciągu wspiera siedem różnych algorytmów losujących kolejne klocki, więc każdy może wybrać sobie taki, który mu się podoba i daje najlepszą zabawę.

Okno gry może działać w trybie desktopowym i być mniejsze od ekranu, może też działać w trybie desktopowego fullscreenu (na dowolnym ekranie) oraz w ekskluzywnym fullscreenie, dającym najlepszą wydajność (niestety tylko na głównym ekranie). Grę można obsługiwać z poziomu klawiatury i gamepadów, a także zmienić mapowanie klawiatury/gamepada, w ustawieniach gry.


Jeśli potrzebujesz dowiedzieć się więcej, zobacz readme oraz wiki projektu w GitHub. Znajdziesz tam opisy dotyczące poszczególnych ekranów gry, sterowania oraz jej zawartości.

1

Pierwsze uruchomienie było bolesne - zniknął mi kursor myszki i okno z grą nie chciało się pokazać.
Musiałem menadżerem zadań wyłączyć aplikację.
Za drugim razem się uruchomiło normalnie na full screenie.

0

Dziwne — nic złego nie powinno się dziać. Fullscreen, jeśli się odpala, to zawsze na głównym ekranie i zawsze w natywnej rozdzielczości. A co jeśli jeszcze raz rozpakujesz archiwum, np. do innego katalogu i odpalisz? Znowu pierwsze uruchomienie będzie wadliwe?

1

Problem się wtedy pojawia ponownie.

screenshot-20240316235717.png

Jak odpalę menu start i najadę na ikonkę Fairtrisa na pasku zadań to miniaturka okna mruga.
Ale klikanie na ikonkę nic nie daje, gra się nie pokaże.

0

Prosiłbym o jeszcze jeden test — wypakuj grę, usuń plik settings.ini i odpal grę. Jeśli odpali się normalnie (obstawiam, że tak będzie) to będzie to oznaczało, że domyślne dane w pliku ustawień są popsute i powodują ten problem.

W sumie to w ogóle nie powinienem tego pliku dołączać do release'u, bo gra sama go tworzy, jeśli go nie ma i w takim przypadku skorzysta z ustawień domyślnych i z domyślnego mapowania (takiego samego jak w tym pliku konfiguracyjnym).

1

Na czysto wypakowane do folderu o innej nazwie.
Usunąłem settings.ini i odpala się tak samo zbugowane.
Ale za drugim razem odpala się normalnie.

0

To jeszcze jeden test…

Wypakować archiwum, otworzyć plik settings.ini, zmienić linijkę VIDEO=1 na VIDEO=0, czyli wyłączyć ekskluzywny tryb wideo. Okno gry powinno się pojawić na głównym ekranie, lewy górny róg w punkcie 0,0, jako małe okienko bez obramowania.

Spine napisał(a):

Ale za drugim razem odpala się normalnie.

Obstawiam, że plik konfiguracyjny przy drugim uruchomieniu ma inną zawartość niż podczas pierwszego uruchomienia. Dobrze by było wiedzieć które dane się zmieniają pomiędzy pierwszym a drugim uruchomieniem.

1

U mnie działa OK, win 10 (aktualny)

0

Ogólnie gra wstaje w ten sposób, że tworzy okno o zerowym rozmiarze i niezdefiniowanej pozycji. Dzięki temu, funkcja SDL_CreateWindow nie pokazuje okna w ogóle (w końcu ma zerowy rozmiar), nic na ekranie nie miga. Potem przychodzi czas na odczyt danych z pliku konfiguracyjnego — w nim jest numer ekranu, współrzędne X i Y, enum z rozmiarem okna oraz flaga aktywacji ekskluzywnego trybu wideo. Jeśli nie ma konfiga, to dane są ustawiane na domyślne wartości. Wtedy też wołana jest metoda, która zajmuje się ustawieniem rozmiaru i pozycji okna, na podstawie danych z konfiga/domyślnych oraz odpalany jest ekskluzywny fullscreen (ten zawsze na głównym ekranie).

Tutaj za bardzo nie ma czego zepsuć, dlatego dziwi mnie twój przypadek @Spine, bo nigdy wcześniej się z czymś takim nie spotkałem. Ani w przypadku tej gierki, ani silnika do Kidsów. Może SDL z czymś nie potrafi sobie poradzić.


PS: a tak w ogóle to współrzędne okna z konfiga są ignorowane. Rozmiar okna jest ładnie ustawiany, ale okno zawsze jest centrowane na głównym ekranie. Podczas inicjalizacji okna, do ustawienia rozmiaru i pozycji okna używam metody przeznaczonej też do zmiany rozmiaru/pozycji okna (np. w ekranie opcji gry), a ona po zmianie rozmiaru, centruje okno na ekranie. Tak więc trzeba zrobić w sumie to samo, ale bez centrowania.

1

No ja to odpalam na Win11.
Wysłałem Ci filmik na priv.

1

u mnie działa, ale czas juz spac

1

@Spine: zauważ, że kiedy najedziesz mychą na przycisk aplikacji, to miniaturka jakoś dziwacznie miga i pokazuje 5fps, czyli coś ssie przepotężnie. Nie wiem dlaczego po chwili okno pojawia się jako małe (rozmiar 2x natywnego bufora), bo powinno być na pełen ekran (ekskluzywny fullscreen).

SDL nie umie u ciebie odpalić ekskluzywnego fullscreena, okno ustawiane jest na małe, zamiast na pełen ekran. Drugi odpał ładuje pewnie inne dane z konfiga, przez co gra nie próbuje już włączyć ekskluzywnego fullscreena i startuje normalnie.

Jeśli możesz, sprawdź co znajduje się w konfigu po pierwszym uruchomieniu i zamknięciu. Możesz wrzucić jego zawartość do posta tutaj — to w końcu żadna tajemnica. Dzięki temu mógłbym prześledzić przepływ sterowania podczas rozruchu i być może znaleźć coś ciekawego. 😉

1

Znalazłem błąd z zapamiętywaniem pozycji — w sumie bzdurka, poszło gładko.

https://github.com/furious-programming/Fairtris-2-UC/commit/9b91511cbdae80515ba1244d71a93cfe377b474e

1
furious programming napisał(a):

Jeśli możesz, sprawdź co znajduje się w konfigu po pierwszym uruchomieniu i zamknięciu. Możesz wrzucić jego zawartość do posta tutaj — to w końcu żadna tajemnica. Dzięki temu mógłbym prześledzić przepływ sterowania podczas rozruchu i być może znaleźć coś ciekawego. 😉

Zawartość taka sama jak przed uruchomieniem:

screenshot-20240317044124.png

0

Ah gowniany windows zablokowal mi uruchamianie "nierozpoznanej" aplikaji :) Potem powalcze :)

1
Spine napisał(a):

Zawartość taka sama jak przed uruchomieniem:

Dzięki za sprawdzenie. W takim razie nie mam powodu myśleć, że kod gry jest temu winny. Gdyby był, to w przypadku błędu poleciałby wyjątek i pojawiłby się komunikat na ekranie (tym bardziej, jeśli SDL zwróciłby błąd). Jeśli pierwsze uruchomienie jest zepsute, a każde kolejne jest dobre, mimo braku zmian w pliku ustawień, to całkiem możliwe, że Windows coś kombinuje i przy pierwszym uruchomieniu nieznanego pliku po prostu go skanuje i blokuje mu fullscreen. W końcu w momencie bootowania coś mocno ogranicza wydajność procesu gry, stąd przez kilka sekund 5fps.

karpov napisał(a):

Ah gowniany windows zablokowal mi uruchamianie "nierozpoznanej" aplikaji :) Potem powalcze :)

Ale z czym chcesz walczyć? Dialog o nierozpoznanej aplikacji (bez podpisu cyfrowego) trzeba potwierdzić, klikając w odpowiedni link w tym okienku — system pozwoli normalnie uruchomić program. 😉

4

Przerobiłem kod gry na wieloplatformowy — niewiele przy tym roboty było. 😉

  • stronę pomocy (czyli wiki w GitHub) otwiera się teraz funkcją OpenURL zamiast ShellExecute,
  • kod obsługi progressbara na przycisku paska zadań jest wykluczony dyrektywami {$IFDEF WINDOWS},
  • klasa zegara, do pobierania częstotliwości i licznika ticków CPU używa funkcji z SDL-a,
  • dla innych platform niż Windows, ustawienia oraz najlepsze wyniki zapisywane są w katalogu preferencji użytkownika.

I to tyle — pół godziny roboty i kod niezależny od platformy.

0

Pobrałem i zagrałem. Fajna, podoba mi się gra, szczególnie idea uniezależnienia od OS poprzez rozwiązanie licznika ticków. Btw, ponad dwadzieścia lat temu napisałem tetrisa na D5. Klocki były tworzone w oparciu o DrawGrid, sama definicja klocków była zapisana w zwykłym pliku tekstowym.

0
machinebyte4 napisał(a):

[…] szczególnie idea uniezależnienia od OS poprzez rozwiązanie licznika ticków.

To nie do końca tak. Framerate jest stały (60 lub 50fps), dlatego że jest klon gry z NES-a, główne mechaniki (system przesuwania i rotacji, aktualizacja stosu i liczników itd.) zostały z niego przeportowane i tak powstał pierwszy Fairtris. Ogólnie pisząc, pierwsza wersja była w praktyce portem gry na NES-a, ale trochę do niej dodałem — w tym ulepszyłem sterowanie i dodałem ciemny motyw jako drugi. Fairtris 2 bazuje na tym samym silniku.

Liczenie ticków jest obowiązkowe, aby utrzymać stały framerate, nie renderować klatek-duplikatów i ogólnie zużywać minimalną ilość czasu CPU. Użycie delty nie wchodzi w grę, interpolowanego renderowania też nie, bo to niczego nie da, a tylko zużycie zasobów wzrośnie. Nie można też uniezależnić framerate'u od odświeżania ekranu, bo będą widoczne skoki podczas grania na dużej szybkości opadania klocków. Screen tearing w ogóle nie jest widoczny w przypadku tej gry, więc najłatwiej było wyłączyć VSync i napisać taki zegar jaki jest. To daje timing zgodny z NES-em i wysoką responsywność, dzięki czemu hardkorowi gracze nie mają problemów z graniem.

Btw, ponad dwadzieścia lat temu napisałem tetrisa na D5. Klocki były tworzone w oparciu o DrawGrid, sama definicja klocków była zapisana w zwykłym pliku tekstowym.

Można i tak — u mnie akurat definicje klocków znajdują się w tablicy zaszytej w kodzie (siedem typów klocków, po cztery orientacje każdy). Jest to identyczna implementacja jak w przypadku Tetrisa na NES-a od Nintendo. Z tą różnicą, że mając takie dane w kodzie, nie ma problemu z utratą pliku z danymi klocków lub nieprawidłową jego zawartością.

Jeśli jesteś zainteresowany tym jak reprezentowane są klocki i jak działa ich system rotacji, to polecam artykuł Applying Artificial Intelligence to Nintendo Tetris — w nim znajdziesz masę informacji na temat tego, jak działał Tetris na NES-a i jak działa Fairtris.

0

Framerate jest stały (60 lub 50fps), dlatego że jest klon gry z NES-a, główne mechaniki (system przesuwania i rotacji

Ach, ok, teraz rozumiem. Odnosiłem ten timing do mojego "sposobu" opartego na TTimer, ale ja w tamtych czasach (cos koło 2000 roku) nie miałem widełek klona NES-a opartego na SDL czyli OpenGL, tylko siermiężną grafikę a o SDL wtedy nawet nie słyszałem 😀

0

Ale nadal do precyzyjnego odmierzania czasu były dostępne funkcje QueryPerformanceFrequency i QueryPerformanceCounter. Zresztą Fairtris też ich używa (pod Windows), bo funkcje SDL_GetPerformanceFrequency i SDL_GetPerformanceCounter są wrapperami na wymienione funkcje z Win32 API.

Tyle tylko, że wcale nie ma obowiązku odmierzania czasu w ten sposób — w małych gierkach (i nie tylko) spokojnie można się ograniczyć do GetTickCount, czyli do milisekundowej precyzji. Taką właśnie zapewnia TTimer i do prostych zastosowań wystarczy.

0

Jeszcze dwie rzeczy trzeba było zmienić, aby projekt dało się skompilować i uruchomić na innych platformach.

Natywny uchwyt okna (typu HWND) na innych platformach jest zbędny, więc trzeba go było otoczyć dyrektywami. On jest używany tylko na Windows i tylko do aktualizacji stanu progressbara przycisku na pasku zadań — ten progressbar pokazuje jaką część czasu klatki gra zużywa na jej wygenerowanie. Im krótszy pasek postępu, tym mniej czasu CPU gra wymaga do działania.

No i jak zwykle zapomniałem o zastąpieniu separatorów ścieżek na wieloplatformowe. Codebase pierwszego Fairtrisa był pisany z myślą o Windows, więc separatory były hardkodowane (znaki \) — zamieniłem je na stałą DirectorySeparator, która zawiera separator natywny dla danej platformy.

Pierwwze testy wykazały, że projekt się kompiluje, uruchamia się i działa poprawnie. Teraz tylko pasuje sprawdzić czy kluczowe funkcje również działają i to w sumie tyle, jeśli o portowanie chodzi — resztę ogarniają wieloplatformowe RTL, FCL, LCL i SDL.

0

Tak z ciekawości, builda rozsyłasz gdzieś po tetrisowych społecznościach? Zbierasz informacje typu ile osób pobrało/gra?

1
Boski napisał(a):

Tak z ciekawości, builda rozsyłasz gdzieś po tetrisowych społecznościach?

Założyłem wątek tutaj (oraz wpis na blogu) oraz na forum Lazarusa, gdzie przy okazji zajmujemy się przystosowaniem kodu źródłowego do innych platform. Dodatkowo, mam kontakt z ludźmi z polskiej sceny klasycznego Tetrisa, którym też dałem znać o istnieniu nowej wersji. Repozytorium jest publiczne i powoli łapie gwiazdki. Coś tam wspomniałem też na Discordzie SDL-a. Wieść się powoli rozniesie, ale nie chcę żeby mnie ktoś o spamowanie oskarżał, dlatego nie przesadzam.

Jakiś sensowny marketing nie jest tutaj potrzebny, bo to mały, poboczny projekt, robiony głównie dla zabawy i odpoczynku od mojego głównego projektu. Przy okazji mogę poćwiczyć kontakt z użytkownikami, łapanie feedbacku i wprowadzanie łatek i poprawek, a to bardzo cenne doświadczenie.

Zbierasz informacje typu ile osób pobrało/gra?

Ani ja, ani gra nie zbiera(m) takich informacji — to za mały projekt, aby się tym zajmować. Szkoda, że GitHub nie prowadzi statystyk pobierania release'ów (tak jak choćby SourceForge), bo nawet byłbym zainteresowany. Pierwszy Fairtris został też wydany w Snap Store i tam są proste statystyki pobrań — na dole strony jest kolorowa mapka, ale bez liczników (szkoda). No ale to Linuks, który na desktopach ma znikomą popularność (~4%), w stosunku do Windows (~72%) i macOS (~15%) (źródło).

0

Opublikowałem nowy release — Fairtris 2.0.1

Obejmuje łatkę błędu związanego z zapamiętywaniem pozycji okna, od teraz używa OpenGL jako backendu, dorzuciłem też kilka mniejszych poprawek, przystosowując źródła do innych platform. Z punktu widzenia gameplay'u nic się nie zmieniło, wszystko jest wedle założeń. Zmieniłem też wersjonowanie — od teraz używam major.minor.patch, bez numeru buildu.

0

Dodałem jeszcze skrót Alt+Enter jako aktywacji i dezaktywacji ekskluzywnego trybu wideo.

Wywaliłem klasę TNavigation, po obsługiwała funkcje specjalne tylko w formie pojedynczych klawiszy. Żeby dodać wsparcie Alt+Enter czy jakichkolwiek innych wieloklawiszowych skrótów, trzeba by kombinować, ale prościej było po prostu wywalić tę klasę, a odwołania do jej właściwości zamienić na odwołania do klawiszy z Input.Keyboard.Device[Scancode], w której znajdują się aktualne stany wszystkich klawiszy. Tak więc trochę kodu odpadło, zrobiło się przejrzyście. W kolejnym release ww. skrót będzie już dostępny.

0

A kiedy wersja mobilna?

2

Czemu miałaby w ogóle być?

0

Nigdy nie będzie wersji mobilnej — ta gra przeznaczona jest do grania kontrolerem (od biedy klawiaturą) i wymaga wysokiej precyzji inputów oraz bardzo dobrego timingu. Niektóre ruchy wykonuje się z precyzją co do kilku klatek, a niektóre do jednej klatki — powodzenia przy macaniu ekranu.

Prędzej dodam możliwość grania myszką, niż paluchami. 😉

0

@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 :]

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