Wraz z Eltenem 2.4 ukaże się nowe API dla Eltenowych programów. To ostatnia próba rozpropagowania pisania rozszereń Eltena, plus eksperyment z funkcjami niezwiązanymi z forum.
Nowe API pozwala na większą integrację programów z Eltenem. Do tej pory program pokazywał się w menu głównym, względnie możliwebyło dodanie go do menu użytkownika. Nowe API ujednolica te interfejsy, dodając możliwość wyświetlania własnych opcji w "Co nowego" i wysyłania powiadomień, oznaczania, które osoby korzystają z programu (np. by wyświetlać odpowiednie opcje tylko w menu właściwych użytkowników), a także możliwość odświeżania stanu programów w tle. Na razie funkcjonalność napisana jest z myślą o grach. Prezentacja nowego rozwiązania będzie miała miejsce w odświeżonej wersji Szachów, która doda listę najlepszych graczy, będzie umożliwiała wyzywanie tylko korzystających z gry użytkowników, ale co najważniejsze będzie wysyłała powiadomienia o oczekujących grach. Prócz Szachów pojawią się jeszcze dwie gry niespodzianki.
Zobaczymy, co tak da się ugrać.
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
Wiem, że Eltenowych programistów nie mamy, ale kilka osób tu działało chociażby w BGT, tak więc zapytam, czy jest coś, co by się przydało? Postarałem się o opracowanie kilku funkcji wysokopoziomowych, by ułatwić pewne rzeczy, zwłaszcza początkującym programistom. Także i części Eltena przepiszę do ich używania, by sam SourceCode stał się przykładem. Oczywiście, te funkcjonalności będą miały pewne ograniczenia w stosunku do używania pełnego API, ale powinny wystarczyć do nawet całkiem złożonych projektów.
Poniżej kilka szkiców koncepcyjnych.
1. Zautomatyzowane formularze Funkcja znana z języków wysokopoziomowych takich, jak Appleowski Swift, czyli nakładanie zdarzeń na elementy interfejsu, pozostawiając sterowanie programem samo sobie. Poniższy przykład tworzy trzy przyciski, po których poruszamy się tabulatorem. Wciśnięcie pierwszego spowoduje odtworzenie dźwięku, drugi przejdzie dalej, tzn. zamknie formularz, trzeci zaś powie coś i wyświetli na linijce brajlowskiej.
Omówienie kodu: Funkcja form.wait zamraża działanie programu aż do zmiany okna lub wywołania funkcji form.resume, z wyjątkiem zdarzeń w formularzu. W ten sposób można nie pisać pętli zdarzeń, skupić się zaś na samym kodzie. Funkcja on służy do rejestrowania zdarzeń. Zależnie od typu kontrolki są to różne zdarzenia, przykładowo: Dla wszystkich kontrolek: :focus, :leave, :key(keyid), Przycisków: :press, Checkboxów: :change, List: :select(index), :change(index), itp.
2. Prostsze rysowanie menu Celem było stworzenie jak najprostszego menu dla klas. Teraz sprawa jest taka:
draw_menu { option("Opcja 1") { # kod tutaj } option("opcja 2") { "kod tutaj" } submenu("Opcja 3") { option("Opcja 3A") { # kod tutaj } option("Opcja 3B") { # kod tutaj } } }
Myślę, że ten kod sam siebie wyjaśnia. :)
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
@daszekmdn Taki układ formów jest bardziej Rubiowski, a łączy zalety tamtego. Sztuczna implementacja innych konceptów to tylko proszenie się o błędy. @nuno69 Tak, plus kilka samplów, nad którymi właśnie pracuję. Małych, ale robiących coś sensownego.
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
Wiem, że biblioteka, tak jak WPF. Tylko, że w językach typu Delphi/Swift poziom integracji z systemem jest taki, że trudno oddzielić sam język od frameworka.
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
Mapa - nowa struktura dedykowana grom pisanym w EltenAPI. To nic innego, jak... no właśnie, mapa. Ponownie, wykorzystanie dość ograniczone, ale dla większości prostych gier wystarczające. Za propozycje jeszcze jakichś predefiniowanych funkcjonalności w mapach będę bardzo wdzięczny. Przykładowa definicja:
map = Map.new(20, 30) { # mapa o wymiarach 20 (szerokość) i 30 (wysokość) # Domyślnie używany jest dźwięk list_focus, ale można go zmienić - o tak: move_sound(appfile("step.ogg")) # funkcja appfile zwraca pełną ścieżkę do pliku programu, zależnie od lokalizacji plików Eltena. # Tak definiujemy pola, na które wejść z jakiegoś powodu nie można, parami x,y: wall(3, 4) wall(8, 8) # albo obszarami linii prostej od x 3 y 4 do x 8 y 9 wall(4, 5, 8, 9) # domyślnie ściany nie wydają dźwięku, ale można to zmienić wall_sound(appfile("wall.ogg")) # także granice mapy nie mają dźwięku, jeśli chcemy go dodać border_sound(appfile("map_border.ogg")) Możemy zdefiniować pola, na których coś się stanie, gdy staniemy: action(2, 2) { alert("Stoisz na polu o współrzędnych 2, 2") } action(1, 1) { alert("Stoisz na polu o współrzędnych 1, 1 i dlatego usłyszysz fajną muzyczkę.") play(appfile("music.ogg")) } } # tu kończy się definicja mapy # można teraz zdefiniować globalne zdarzenie, który wydarzy się po wciśnięciu np. entera na dowolnym polu: map.on(:key_enter) { alert("Stoisz na polu o współrzędnych #{map.x}, #{map.y}") } # zamykamy mapę po wciśnięciu escape map.on(:key_escape") { map.dispose } # no i mapę pokazujemy na ekran. Od tej pory następne linie kodu nie będą się wywoływały do zamknięcia mapy, w naszym przypadku po klawiszu escape map.show
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
@nuno69 już jest, tamta funkcja action, która tworzy akcję na polu właśnie, po wejściu na nie. Można też dodawać akcję po utworzeniu mapy, funkcja map.action zamiast action w definicji, będzie przykład. @daszekmdn Do przeciwników nie planuję na razie. Sporo to kodu, a gry są tak różne, że i tak by się ich przepisywało, bo każdy ma własny koncept walk, hp itd. Więc logika przeciwników jest do napisania własnego. Co do losowych miejsc, można to zrobić Rubiowską funkcją rand, o tak: map=Map.new { action(rand(size_x), rand(size_y)) { alert("Wlazłeś na losowo wybrane pole ze zdarzeniem") } }
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
A, i tak... mapy są tylko 2d. Można oczywiście stworzyć mapę 1d, ustawiając wysokość mapy na 1. Nie przewiduję implementacji map 3d, bo to tak różne koncepty znów są... Ewentualna taka implementacja pozostaje również kwestią użytkownika.
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.
Mogę dodać. Ruby to potrafi na wątkach o tak: timer = Thread.new { loop { #pętla, by timer się nie zamykał sleep(1) # czekaj jedną sekundę play("signal") # odtwórz signal co sekundę } }
Ale można zrobić timer prościej, np. coś takiego, tylko wolna refleksja, jak jesteś za, mogę zakodzić:
timer = Timer.new(1, true) { # co jedną sekundę, true czyli loopowanie go play("signal") }
#StandWithUkraine
Shoot for the Moon. Even if you miss, you'll land among the stars.