Szukam pomysłów, jak wykonać następujące czynności: Chcę napisać prosty „świat” w Javie. Jeden, który mógłbym rozpocząć, a następnie dodać nowe obiekty w późniejszym terminie, aby symulować / obserwować różne zachowania między istniejącymi obiektami. Planuje się następnie zakodować nowsze obiekty po pewnym czasie oglądania starych, a następnie załadować / upuścić w istniejącym świecie. Problem polega na tym, że nie chcę nigdy zatrzymywać ani restartować świata po jego uruchomieniu, chcę, aby działał przez kilka tygodni, ale potrzebuję możliwości upuszczania obiektów i ponawiania / przepisywania / usuwania / tworzenia / mutowania ich z czasem bez konieczności ponownego uruchamiania. Świat może być tak prosty, jak tablica 100 x 100 lokalizacji X / Y, z możliwym graficznym interfejsem kafelkowym, który wizualnie reprezentuje świat. Wiem, że potrzebuję pewnego rodzaju procesu ticktimer, aby monitorować obiekty i dać każdemu „szansę na działanie”
Przykład: koduję World.java w poniedziałek i zostawiam włączony. Następnie we wtorek piszę nową klasę o nazwie Rock.java (która się nie porusza). Następnie ładuję / upuszczam (jakoś?) Do tego już działającego świata (który po prostu upuszcza go gdzieś losowo w tablicy świata i nigdy się nie rusza). Następnie w środę tworzę nową klasę o nazwie Cat.java i upuszczam ją na świat, ponownie umieszczoną losowo, ale ten nowy obiekt może poruszać się po świecie (w pewnym przedziale czasu), a następnie w czwartek piszę klasę o nazwie Pies. java, która również się porusza, ale może „oddziaływać” na inny obiekt, jeśli znajduje się on w sąsiedztwie i na odwrót.
To jest ta rzecz. Nie wiem, jakiego rodzaju struktury / projektu potrzebowałbym do kodowania rzeczywistej światowej klasy, aby wiedzieć, jak wykrywać / ładować / śledzić przyszłe (i obecnie nieistniejące) obiekty.
Jakieś pomysły na to, jak zrobiłbyś coś takiego przy użyciu Java?
Odpowiedzi:
Zasadniczo szukasz systemu z możliwością podłączenia na gorąco. Uruchamiasz główną aplikację, a następnie dodajesz wtyczki w czasie wykonywania, które integrują się z pętlą zdarzeń. Najpierw zacznij od myślenia o tym, czego Twój świat oczekuje od bytu gry. Na przykład (na podstawie twojego opisu):
Oczywiście możesz dodać inne metody, które uznasz za konieczne. Zanotuj parametr World za pomocą dwóch odpowiednich metod. To pozwala twojemu nowemu bytowi patrzeć na świat podczas konfigurowania lub aktualizacji. Na przykład w klasie psów możesz poprosić świat o wszystkie koty w okolicy. Następnie tworzysz swój świat, który działa z tym interfejsem i systemem do dynamicznego kompilowania i ładowania kodu Java. Przykład tego można znaleźć tutaj .
Wywołaj tę metodę ze światowego GUI, aby dodać nowe podmioty. W zależności od implementacji World funkcja inicjująca Entity może wyglądać następująco:
źródło
Zrobiliśmy coś takiego w Stendhal na naloty.
Nie staraliśmy się całkowicie unikać ponownego uruchamiania. Dlatego zmiany w naszych podstawowych usługach infrastrukturalnych, takich jak komunikacja klient / serwer, wymagają ponownego uruchomienia. Ale dodawanie bytów, stworzeń i NPC oraz modyfikowanie istniejących obiektów działa. (Aha, a czasem naprawa błędów na żywo, odbicie może być użyte do manipulowania nawet polami prywatnymi).
Ponieważ chcemy nie tylko nowego obiektu opartego na nowych danych (jak inna skóra), ale chcemy dodać nowe zachowanie, program światowy musi mieć możliwość ładowania nowych plików klas . Nazywamy je „skryptami”, ale są prawdziwymi skompilowanymi klasami Java. Klasy te implementują interfejs Script.java .
Maria.java jest prostym przykładem. Jest nową postacią niezależną, która sprzedaje napoje i jedzenie graczom. Możemy również zdefiniować tam bardzo złożone obiekty .
Nowa klasa jest ładowana w ten sposób:
Jeśli możesz zapewnić unikalne nazwy i nigdy nie chcesz zwalniać klas, masz już dość niskiego poziomu.
Rozładunek wydaje się jednak bardzo ważny. Aby to osiągnąć, musisz utworzyć instancję modułu ładującego nową klasę, ilekroć chcesz wstrzyknąć nowy kod. Aby GC mógł wykonać swoją pracę po usunięciu ostatniego odwołania do tego kodu.
W naszym interfejsie mamy komendę / unload, która wywołuje metodę unload, dzięki czemu skrypty mogą przeprowadzać czyszczenie. Rzeczywisty rozładunek odbywa się automatycznie przez GC.
Podczas najazdów często tworzymy wiele tymczasowych obiektów . I chcemy, aby wszystkie zostały usunięte po zakończeniu nalotu. Na przykład Raid Gnomes, który odradza wiele gnomów w pobliżu niewidzialnego administratora, używamy tego kodu: GnomeRaid.java rozszerza CreateRaid.java .
Skrypt może uzyskać bezpośredni dostęp do świata (jak pokazuje pierwszy przykład) i wykonać własne czyszczenie w metodzie unload (). Ale kodery Java nie są używane do czyszczenia i jest to denerwujące. Stworzyliśmy więc piaskownicę, z której mogą korzystać skrypty. Po rozładowaniu wszystkie obiekty dodane do świata za pośrednictwem klasy Sandbox są usuwane.
źródło
Uratuj świat (bez zamierzonej gry słów) i cały jego stan (pozycje, prędkości, wszystkie zmienne).
Jest to jednak ogólne rozwiązanie, nie znam specyfiki Javy, aby wiedzieć, czy możesz dynamicznie implementować bloki kodu i klasy, jak masz nadzieję ...
Opcja 2 polega na powiązaniu języka skryptowego, który można załadować w locie.
źródło
W przypadku Java wszystko czego potrzebujesz to platforma OSGi . Dzięki temu jest to proste w przypadku modułów lub aplikacji wymienianych podczas pracy, a nawet zdalnego zarządzania lub częściowych aktualizacji.
źródło