Jak powinienem stworzyć zmienne, zróżnicowane jtree z dowolnymi / ogólnymi węzłami kategorii?

12

Uwaga: nie chcę tutaj pomocy w kodowaniu, jestem włączony Programmersz jakiegoś powodu. Chcę poprawić swoje umiejętności planowania / pisania programów, a nie (tylko) rozumienie języka Java .

Próbuję wymyślić, jak stworzyć drzewo, które ma dowolny system kategorii, w oparciu o umiejętności wymienione w tej grze LARP tutaj . Moja poprzednia próba polegała na tym, że umiejętność była również kategorią. Próba kodowania tego była nieporządna. Rysując moje drzewo zauważyłem, że tylko moje „liście” były umiejętnościami, a pozostałe oznaczyłem jako kategorie.

To, co szukam, to sposób na utworzenie drzewa, które będzie próbowało oddzielić Model i Widok, i pozwolić na dodanie dowolnego typu węzła potomnego (z osobnym sposobem edycji / renderowania) do dowolnego rodzica.

Drzewo z listą różnych umiejętności z powyższego linku

Uwaga: Wszystko tutaj jest kupowane jako umiejętność, nawet jeśli wydaje się być własnością. Użytkownicy końcowi uznają to za umiejętności kupowania (co robią na bankomacie w formie papierowej), dlatego należy je przedstawić jako takie, wszystkie na tej samej stronie.

Wyjaśnienie drzewa: Drzewo „rodzi się” z zestawem kategorii zakodowanych na najwyższym poziomie ( broń, fizyczne i psychiczne, medyczne itd.). Na tej podstawie użytkownik musi mieć możliwość dodania umiejętności. Ostatecznie chcą na przykład dodać umiejętność Specjalizacja miecza jednoręcznego ( nie przedmiot). Aby to zrobić, najlepiej kliknij „dodaj” z Weaponszaznaczonym, a następnie wybierz One-handedz węzła combobox, który pojawia się na tym dziecku, a następnie kliknij ponownie dodaj i wprowadź nazwę w polu tekstowym na tym węźle potomnym, który się pojawi. Następnie kliknij przycisk Dodaj ponownie, aby dodać / określić „poziom” lub „poziom” dla tego liścia; najpierw biegłość, potem specjalizacja (na przykład).

Oczywiście, jeśli chcesz kupić inną umiejętność, jest to zupełnie inna droga do liścia. Możesz nie potrzebować pola kombi na tym samym poziomie w dół drzewa, co na przykład z bronią, i potrzebujesz też innej logiki. Właśnie z tego powodu nie mogę się skupić na programowaniu; jak utworzyć zestaw klas i nie określać kolejności, w jakiej należy je ze sobą połączyć, ale nadal mają wszystkie pasujące.

Jaki jest dobry system do opisywania tego rodzaju drzewa w kodzie? Wszystkie inne przykłady JTree, które widziałem, mają pewien przewidywalny wzór, a mój nie . Nie chcę kodować tego wszystkiego w „literałach”, z długimi listami tego, jaki typ (pole kombi, pole tekstowe itp.) Węzła potomnego powinien być dozwolony na jakim rodzicu. Czy powinienem używać klas abstrakcyjnych? Interfejsy?

Jak mogę sprawić, by ten rodzaj obiektów był rozszerzalny, gdy dodam inne umiejętności niewymienione powyżej, które zachowują się inaczej?

Jeśli istnieje nie system dobry do użycia, czy istnieje dobry sposób na wypracowanie jak robić tego typu rzeczy?

Koła zębate w mojej głowie obracają się:

Zawsze muszę:

  • Sprawdź rodzica
  • Podaj opcje w zależności od rodzica

Zaczynam myśleć ze względu na tę skillpowszechność. Potrzebuję czegoś w rodzaju klasy abstrakcyjnej / interfejsu, która definiuje / określa powszechne metody umiejętności i kategorii. Mogę (mam nadzieję) umieścić zasady i opcje w bazie danych i czytać stamtąd. Pytanie brzmi, jak myślę teraz, między metodą abstrakcyjną lub metodą interfejsu a tym, jak ją zaimplementować.

Pureferret
źródło
Zacząłem (po rozmowie z przyjacielem) opracowywanie abstrakcyjnych klas dla SkillComponents w danych, a następnie określanie poszczególnych przypadków poprzez rozszerzenie klasy podstawowej. Drzewo po prostu spojrzy na dane i odpowiednio się narysuje. Odpowiem, jeśli to zadziała.
Pureferret
Pytanie: Życie to umiejętność posiadająca właściwość „poziomu”, którą można zwiększać. Czy jest to unikalne w życiu, czy też inne umiejętności mogą również zwiększać poziom? Mogę sobie wyobrazić kombinację klasy abstrakcyjnej i wielu interfejsów w twoim rozwiązaniu, takich jak abstrakcyjna klasa „Umiejętność” lub „Kategoria” lub „SkillNode” w celu zbudowania twojego drzewa, wraz z wieloma interfejsami, takimi jak „Specjalizowalność” ”lub„ Poziomowalny ”, aby połączyć różne funkcje, które nie są konieczne w strukturze drzewa. Komentowanie dla zabawy ... mam nadzieję, że znajdziesz to, czego szukasz!
David Kaczyński
W pytaniu podajesz jTree. Zastanawiasz się, jak wyświetlać pola tekstowe i pola kombi jako węzły, czy szukasz projektu niespecyficznego dla Javy?
psr
@DavidKaczyński trafiłeś w sedno. Zacznę wdrażać tego rodzaju rzeczy jak najszybciej.
Pureferret,
@psr Próbuję sprawdzić, czy istnieje skodyfikowany wzorzec klas (niekoniecznie „wzorzec projektowy”) klas, lub w inny sposób oprzeć to na tym. David Kaczyński bardzo się do tego zbliża.
Pureferret,

Odpowiedzi:

3

Prosty przykład mutable JTree

wprowadź opis zdjęcia tutaj

Kod (zgodny i przetestowany z Javą 7, aby zrobić powyższy obraz):

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class SimpleTree extends JFrame {
    public static void main(String[] args) {
        new SimpleTree();
    }

    public SimpleTree() {
        super("Mutable Varied JTree");
        Container content = getContentPane();
        N root = new N("Root");

        N weapons = new N("Weapons").add(
            new N("One-handed").add(
                new N("Sword").add("Proficiency", "Specialization"), 
                new N("Mace").add("Proficiency")),
            new N("Bow").add("Proficiency"));
        root.add(weapons);

        N phys = new N("Physical & Mental").add(
            new N("Life"),
            new N("Strength").add(
                "Double", "Triple", "Quadruple"));

        root.add(phys);
        N med = new N("Medical");
        med.add(new N("Bind Wounds"));
        med.add(new N("Set Broken Bones"));
        root.add(med);

        JTree tree = new JTree(root);
        content.add(new JScrollPane(tree), BorderLayout.CENTER);
        setSize(275, 300);
        setVisible(true);
    }

    private class N extends DefaultMutableTreeNode {
        public N(String s) { super(s); }
        public N add(String... strs) {
            for (String s : strs) {
                super.add(new N(s));
            }
            return this;
        }
        public N add(N... ns) {
            for (N n : ns) {
                super.add(n);
            }
            return this;
        }
    }
}

Specjalne podziękowania dla tego samouczka JTree

Aktualizacja: omówienie możliwych rozwiązań

Istnieje samouczek dotyczący tworzenia dynamicznego drzewa za pomocą przycisków u dołu ramki, aby dodać / usunąć / wyczyścić węzły.

W przypadku pól kombi i tym podobnych, chcesz wziąć obiekty odpowiedniej klasy swing i sprawić, by były czymś w rodzaju JComboBox, który implementuje java.swing.tree.MutableTreeNode. Samouczek Java Swing zawiera listę elementów sterujących .

Nadal musisz utworzyć element interfejsu użytkownika, aby umożliwić użytkownikom wybór rodzaju węzła, który chcą dodać, i edytować węzeł. Jeśli dodadzą pole kombi, będą musieli móc określić, jakie opcje będzie dostępne.

Potrzebujesz podstawowego modelu danych, aby zapisać swoje dane. Możesz użyć domyślnego schematu serializacji wbudowanego we wszystkie obiekty Java, ale służy on tylko do prototypowania - zepsuje się, jeśli kiedykolwiek zmienisz kod programu. Będziesz musiał użyć bazy danych z JDBC lub JPA albo będziesz musiał napisać własne procedury serializacji (lub użyć biblioteki, która obsługuje serializację), używając czegoś takiego jak JSON lub XML jako format przechowywania.

Aktualizacja: Proponowane rozwiązanie z przeglądem projektu

Najprostszym rozwiązaniem może być zapomnienie o bazach danych i wymyślenie najpierw wyrażenia XML danych, a następnie edycja pliku XML i wyświetlenie wyników jako JTree bez specjalnych pól kombi lub czegokolwiek. Myślę, że właśnie to sugerował Chibueze Opata swoją odpowiedzią. Częściowa reprezentacja XML tego drzewa może wyglądać następująco:

<folder name="Physical &amp; Mental">
    <int name="Life">12</int>
    <drop-down name="Strength">
        <option name="Single" />
        <option name="Double" />
        <option name="Triple" />
        <option name="Quadruple" />
    </drop-down>
</folder>
<folder name="Medical">
    <text name="Bind Wounds" />
    <text name="Set Broken Bones" />
</folder>

Oto kilka potencjalnych kamieni milowych dla Ciebie:

  • Utwórz format danych XML lub JSON, a następnie napisz program, który odczyta plik tego formatu i wyświetli go jako JTree bez żadnych pól kombi, tylko foldery i pliki.
  • Dodaj kontrolki swing do wyświetlacza JTree
  • Rozwiń swój program, aby zapisać ten sam plik
  • Utwórz interfejs użytkownika, aby użytkownik mógł dodawać i edytować węzły za pomocą GUI

Pamiętaj, aby zapisać kopię zapasową programu za każdym razem, gdy działa on na końcu każdego kamienia milowego. System kontroli źródła zainstalowany na innym komputerze jest do tego idealny. Możesz użyć github, sourceforge lub innej publicznej kontroli źródła, jeśli nie masz nic przeciwko udostępnianiu kodu i nie chcesz konfigurować serwera z kontrolą źródła.

Każde z tych rozwiązań jest pracochłonne i zdecydowanie większe niż projekt dla początkujących. Oznacza to, że poświęcisz znacznie więcej czasu na naukę Java Swing i XML lub JSON niż granie na LARP, dlatego po raz pierwszy zbadałem opcje wykorzystania istniejących narzędzi. Ale najlepszym sposobem na naukę czegokolwiek jest najbardziej zmotywowany do nauki. To może być dla Ciebie idealny projekt.

Mam nadzieję że to pomogło.

GlenPeterson
źródło
Cześć, właśnie rozmawiam przez telefon, więc nie mogę tego w pełni sprawdzić, ale wygląda na to, o co mi chodzi, ale jak mówię w swoim pytaniu, muszę mieć możliwość wymiany różnych typów węzłów. +1 za bycie na dobrej drodze!
Pureferret,
1
„DefaultMutableTreeNode zapewnia operacje sprawdzania i modyfikowania elementu nadrzędnego i potomnego
GlenPeterson
Mój problem z tym, Glen, jest taki, że chociaż reprezentuje jedno potencjalne drzewo, może nie reprezentować umiejętności postaci. Muszą być w stanie wpisać typ broni w polu tekstowym i wybrać na przykład niektóre opcje z rozwijanego pola kombi. W tym sensie jest zmienny i pozwala arbitralnym dzieciom. Masz tylko jeden typ węzła potomnego tutaj, N . Co więcej, tak naprawdę nie jestem po kodzie (jak na dobrym przykładzie), a bardziej ogólny wzorzec projektowy dla tego rodzaju rzeczy / drzewa / modelu danych .
Pureferret
1
OK, więc potrzebujesz programu, który pozwala ludziom tworzyć drzewa - jak kontur. W Microsoft Word jest już widok konspektu. OpenOffice / LibreOffice Write ma podobne funkcje. Co jeszcze potrzebujesz?
GlenPeterson
1
Wiem, że mogę zadawać ludziom niewłaściwe pytania wszystkimi swoimi pytaniami i za to przepraszam. Ale muszę to zrobić, aby zrozumieć problem. Zaktualizowałem koniec mojego rozwiązania powyżej (pod dużym nagłówkiem „Aktualizuj”), co według mnie może być odpowiedzią na twoje pytania lub przynajmniej wskazówkami, jak sam na nie odpowiedzieć. Mam nadzieję że to pomogło.
GlenPeterson
2

Nie sądzę, aby JTree stanowiło właściwą reprezentację problemu, który próbujesz rozwiązać. Spojrzałem na twoją stronę internetową i widzę listy rzeczy. To świetny początek, ale myślę, że istnieje podstawowy projekt danych, który możesz mieć, ale nie widzę.

Życie i siła wyglądają jak atrybuty postaci. Podwójne, Potrójne i Czteroosobowe wyglądają jak wartości dla atrybutu Siła. Potem widzę umiejętności podzielone na broń i medycynę. Uważam broń za posiadanie (które można kupić, znaleźć lub upuścić) i zakładam, że ta umiejętność pozwala ci być skutecznym z daną bronią. Ale sposób, w jaki na to patrzę, broń i medycyna nie mają umiejętności, bohater ma. W rzeczywistości podejrzewam, że Postać jest centralną postacią w twoim projekcie danych.

Oto trzy obiekty danych, które do tej pory wyróżniały się na tle mojego projektu:

Character:
    Life (a value: e.g. 12)
    Strength (a value: e.g. double, triple, quadruple)
    Skills (list or set of weapon-skills, healing-skills)
    Possessions (list of weapons, armor and other possessions)
    WornArmor (maybe only wear one you possess at a time?)
    WieldedWeapon (one or two of your posessions)

Skill:
    Skill-Type (healing, manufacture, or weapon)
    RelevantWeapon (for this skill)

Weapon:
    IsOneHanded (boolean)
    IsBow (boolean)

Teraz postać może mieć broń i umiejętności, ale do naprawdę dobrego ataku potrzebują umiejętności specyficznej dla używanej broni. W każdym razie istnieją tutaj relacje jeden do wielu (jedna postać może mieć wiele umiejętności). Ale jeszcze nie widzę drzew.

Weź bloczek papieru i na pierwszej stronie umieść postać na środku strony i wypisz 5–10 najważniejszych obiektów świata gry. Dowiedz się, jakie dane są jedynie atrybutem innego obiektu (np. Życie i Siła są nieodłącznymi częściami postaci) i jakie są najważniejsze relacje między obiektami, bez myślenia o drzewach, polach tekstowych lub polach kombi. Narysuj linie między obiektami, aby przedstawić relacje. Następnie dowiedz się, które relacje to 1: 1, a które są 1: wiele, a które są liczne: wiele, i oznacz je etykietami. Mogą istnieć „has-a” i „is-a” oraz inne rodzaje relacji.

Możesz zdecydować, że potrzebujesz osobnych reprezentacji dla WeaponSkill vs. HealingSkill vs. ManufactureSkill. Możesz też zdecydować, że są tak podobne, że należą do jednej tabeli umiejętności (w moim przykładzie powyżej) z polem określającym, jaki to rodzaj umiejętności.

To dobry znak, że nie jesteś zadowolony ze swoich dotychczasowych prób - oznacza to, że przed wybraniem jednej z nich chcesz rozważyć wiele możliwości. Im więcej szkiców bierzesz pod uwagę, tym lepszy będzie twój ostateczny projekt. W końcu najlepszym stanie się diagram danych. Gdy jest to dość dobrze rozwiązane, możesz wrócić do myślenia o „polach kombi” lub „polach tekstowych”, ale decyzje dotyczące interfejsu użytkownika pozostawię do końca.

Zamiast patrzeć na JTrees, sugerowałbym zapoznanie się z tematami Struktur danych, Projektowanie baz danych, a może modelowania danych. EDYCJA-> Lub jeszcze lepsze diagramy mapowania relacji między bytami, jak sugerował David Kaczyński! <-EDYCJA Jeśli poprawnie opracujesz projekt danych, Java i interfejs użytkownika będą z niego płynąć w sposób oczywisty i naturalny. Ale jeśli pomylisz się, to żadna ilość Java-kung-fu lub UI-beauty to nie naprawi.

Powodzenia!

GlenPeterson
źródło
2

Skupię się na modelu obiektowym.

Myślę, że ze względu na elastyczność, którą chcesz, prawdopodobnie chcesz podzielić swoje klasy na warstwę wiedzy (być może „definicja” jest lepszym słowem w tym przypadku) i warstwę transakcji. Przez „warstwę” naprawdę rozumiem tylko logiczne rozdzielenie ich w głowie. Warstwa wiedzy zawiera definicję rozłożenia drzewa, a dane w nim pochodzą od projektanta gry, a warstwa danych przechowuje określone wybory dla konkretnej postaci.

Twój poziom wiedzy będzie co najmniej nieco niechlujny, ponieważ starasz się stworzyć fajną grę, a nie matematycznie czysty model.

Próbuję uporządkować to, co do tej pory masz, myślę, że masz klasę SkillDefinition, a także właściwość Parent typu SkillDefinition. Masz również podklasy SkillDefinition (które mogą stać się pozycjami w tabeli DEF_SkillType w bazie danych), aby objąć kilka przypadków.

Wydaje się, że „broń”, „fizyczna i psychiczna” oraz „medycyna” mają tylko tytuł (i umiejętności dziecka).

Wydaje się, że „One Handed”, „Strength” i „Bind Wounds” mają powiązane pole kombi (co oznacza coś w rodzaju tabeli DEF_SkillChoice w bazie danych z kluczem obcym do DEF_Skill). Miecz i łuk wydają się ciągiem zdefiniowanym przez użytkownika (więc nie ma powiązanej tabeli na poziomie wiedzy, ale dane będą przechowywane w warstwie transakcji).

Wydaje się, że z „życiem” jest związana liczba całkowita. Może nie być w stanie współużytkować tej klasy z żadnymi przyszłymi cechami, które wykorzystują liczbę całkowitą, ponieważ istnieje domniemane zachowanie dotyczące sposobu zwiększania liczby całkowitej. W każdym razie obecnie potrzebuje własnej klasy.

„Sword”, „Bow”, „Strength” i „Bind Wounds” wydają się mieć powiązane z nimi poziomy umiejętności progresywnych poniżej drzewa. W przypadku „Sword” i „Bow” poziomy te są naprawdę powiązane z ich umiejętnościami rodzica. Myślę, że potrzebujesz klasy ProgressiveSkillDefinition z uporządkowaną kolekcją wartości prawnych (tabela DEF_SkillLevel z kluczem obcym do DEF_Skill. Na poziomie wiedzy nie jest do końca jasne, jakie reguły modelujesz. Jeśli „biegłość” i „specjalizacja” są zawsze dostępne dla wszystkich broni możesz mieć tabelę DEF_SkillLevel z rekordami „biegłości” i „specjalizacji” posiadającymi obce klucze do rekordu „Broń”.

Obejmuje to, co wiesz na poziomie wiedzy. Poziom transakcji (być może „poziom postaci” byłby lepszą nazwą?) Wskazuje tylko na odpowiedni poziom wiedzy. Tak więc w twoim przykładzie miałbyś obiekt postaci z obiektem umiejętności, który ma kolekcję umiejętności - tylko te, które faktycznie posiada.

Tak więc postać miałaby umiejętność „Biegłość”, której rodzicem jest umiejętność „miecz”, a jej typ to Skill_Level. W bazie danych rekord TRANS_SkillDefinition zawiera klucz obcy do transakcyjnego rekordu umiejętności „miecz” i rekordu DEF_SkillLevel poziomu wiedzy o nazwie „Proficiency”.

Umiejętność biegłości miałaby obiekt nadrzędny umiejętności „miecza” typu Skill_UserNamed. W bazie danych nie miałby to klucza obcego do poziomu wiedzy, ponieważ dla słowa „miecz” nie ma nic specjalnego (to nazwa użytkownika). Ma jednak również klucz obcy do nadrzędnego rekordu transakcji, dzięki czemu można uzyskać więcej informacji za jego pośrednictwem.

Obiekt umiejętności „miecz” ma obiekt nadrzędny „jednoręczny”, ponieważ użytkownik postanowił umieścić „miecz” w kategorii „jednoręcznej”. Jest to obiekt typu SkillCategory. W bazie danych ma obcy klucz do tabeli DEF_SkillChoice dla rekordu „jedną ręką” i brak transakcyjnego elementu nadrzędnego, ponieważ wszystkie dodatkowe dane dotyczące tej umiejętności są przechowywane na poziomie wiedzy.

Podczas konstruowania drzewa początkowego dla nowej postaci należy zapytać tylko o poziom wiedzy. Aby wypełnić wybory dokonane dla postaci, wymagany jest poziom transakcyjny.

Będziesz potrzebował kodu, aby przetłumaczyć model obiektowy na drzewo iz powrotem. Mam nadzieję, że powinno być jasne, co należy zrobić - każdy typ w warstwie wiedzy będzie miał powiązany zestaw elementów sterujących w drzewie, który pobierze dane odpowiednie dla tego typu.

Później możesz chcieć klas dla każdego wyboru w rekordach SkillCategory (jeśli „Specjalizacja” ma z tym związane zachowanie, kod musi gdzieś iść), ale nie potrzebujesz tego jeszcze dla tego drzewa, a ten projekt będzie kompatybilny z tym. Musisz tylko mieć fabrykę, która wykorzystuje informacje o poziomie wiedzy do zbudowania odpowiedniego obiektu.

psr
źródło
Jeśli jest to niejasne lub nie odpowiada na pytanie, daj mi znać. To duży temat i w pewnym momencie musiałem przestać.
psr
To jest właściwie najbliższa odpowiedź na to, czego chcę, co jest naturalne w kodzie dla emulowanego systemu i co może działać. W tej chwili wszystkie moje umiejętności pochodzą od abstrakcyjnego SkillComponent (AbSkillComponent, ponieważ nie mogę znaleźć dobrej konwencji nazewnictwa dla klas abstrakcyjnych), i mam RootSkillComponent, SkillComponent i niektóre interfejsy do zrobienia listy rozwijanej i części UserNamed. Muszę podziękować za dodanie tego, w jaki sposób odnosi się to do bazy danych, co odkładam na teraz, ale warto o tym pomyśleć. Ta odpowiedź jest bardzo dobra i na pewno powiew świeżego powietrza.
Pureferret
@Pureferret - chyba zostawiam odpowiedź taką, jaka jest wtedy - nie byłem pewien, czy wiedziałem, czego szukasz.
psr
1

W końcu zawsze kończymy na zarządzaniu strukturami hierarchicznymi - czy to hierarchią klas programu, czy samym programem zbudowanym z różnych modułów łączących cię z „wewnętrznym światem” (GUI, połączenie DB, logika biznesowa związana z danymi itp.) . Ale to jest filozofia, jak powinna działać w twoim przypadku?

W tym drzewie masz węzły, każdy element jest „instancją obiektu”; podczas gdy ich zachowanie (gdzie można je umieścić, listę dozwolonych węzłów potomnych itp.) jest wspólne dla niektórych zestawów, takich jak „klasy”. Tak, to jest jak kod programu. Jeśli znasz wystarczająco odbicie Java, możesz nawet użyć klas POJO i hierarchii dziedziczenia, aby zbudować ten komponent z kontenerem IoC lub mechanizmem fabrycznym do zbudowania rzeczywistych instancji. Ale myślę, że tego nie chcesz, ponieważ jest to hakowanie ciężkiego języka, więc ...

Najpierw utwórz obiekt „klasy”, który będzie opisywał zachowanie elementów. Zawiera identyfikator klasy, nazwy „pola” oraz dozwolone typy i liczbę przedmiotów itp. Przykład: klasa „root” to „Właściwości gracza”, mają pola „Fizyczne / umysłowe”, „Medyczne”, „Broń”. Ten typ jest „ostateczny”: w tej chwili nie chcesz mieć różnych typów graczy. Wskazówka: później możesz to zrobić, używając tych samych narzędzi do obsługi „potworów innych niż ludzie” ... :-)

Pole „Medycyna” to

  • „singleton”: gracz nie może mieć wielu informacji „medycznych”
  • typ potomny jest ustalony, można tu użyć tylko obiektu typu „Medyczny”
  • wymagane: kiedy tworzysz gracza, musi on mieć pole „medyczne”

Wręcz przeciwnie: Członek broni nie jest wymagany, należy go utworzyć, gdy do gracza zostanie dodana pierwsza broń. Oznacza to: kiedy „edytujesz” swój „obiekt” (obecnie odtwarzacz) i chcesz zezwolić na dodanie do niego nowego elementu, nie powinieneś ograniczać wyboru rzeczywistymi właściwościami instancji (która teraz nie zawiera „broni” ”), ale pokaż wszystkie pola definicji klasy i leniwie utwórz nowe pole (węzeł potomny) przy pierwszym użyciu. Stworzy to rozszerzalne środowisko. Później możesz dodać pole „Znajomi” z wieloma graczami ... eee ... referencjami (patrz później).

Postępuj zgodnie z procesem z rzeczywistymi „klasami”. Pomoże ci dopracować swoje pomysły, na przykład: wydaje się, że lepiej jest rozdzielić typy broni (miecze, sztylety, łuki, ...), jakoś radzić sobie z amunicją (wiedząc, że być może gracz NIE ma łuku, ale może zbierać strzały, ale używając niektóre bronie wymagają amunicji i dekrementacji, niektóre z nich można znaleźć, inne zostały zgubione ...) w klasie „Broń”: łatwiej jest przeprowadzić ankietę, a także pokazać, czy gracz niesie tylko ten przedmiot, czy też może go użyć ( ma umiejętności). Z drugiej strony: z pewnością zmienisz tę strukturę w miarę rozwoju gry.

Utwórz globalnie dostępny „sklep klasowy”, który zainicjujesz, gdy rozpocznie się gra, i podaj definicje klas, gdy ktoś odwoła się do ich nazwy. W tym przypadku obiekty klasy def muszą być niezmienne.

„Obiekty” są łatwiejsze: można je uzyskać z tej samej klasy głównej, która zawiera odwołanie do definicji klasy oraz ogólny dostęp do pól. Być może użyj HashMap, aby zatrzymać te dzieci, identyfikowane przez nazwę pola. Pamiętaj: niektóre z tych pól zawierają pojedynczy obiekt, inne zestaw obiektów. Te przypadki są oczywiście zmienne.

Teraz interfejs. Najpierw powinieneś sprawdzić samouczek JTree ... i teraz powinno być oczywiste. Każdy „obiekt” może być reprezentowany przez DefaultMutableTreeNode, „userObject” węzła powinien być twoim obiektem (myślę, że toString () tego węzła jest wyświetlana jako etykieta węzła, ale możesz utworzyć niestandardowy formatator komórek). Ilekroć otwierasz węzeł, przeglądasz pola obiektu i tworzysz węzły potomne pod rodzicem (jeśli chcesz to zrobić dynamicznie) - lub przeglądasz całe drzewo i budujesz strukturę TreeNode, gdy wyświetlasz JTree (wskazówka: tam to konstruktor JTree z parametrem TreeNode).

Po wybraniu węzła w drzewie masz instancję Object. Według jego klasy, możesz wyświetlić odpowiedni panel edytora lub ogólny panel generowany przez definicję klasy (np .: panele kart z polami, edytory pola rzeczywistego według deklaracji pola: przycisk, który tworzy dziecko odpowiedniego typu of pozwala wybrać jedną z dostępnych klas oraz pola edytora dla tego wystąpienia, takie jak właściwości broni). Po zmodyfikowaniu struktury musisz odświeżyć samo drzewo - TreeModel i jego ogień ... funkcje zmiany są Twoimi przyjaciółmi.

Wygląda dobrze? Czy zbyt skomplikowany? To niewielki ułamek historii. Nie rozmawiałem o tym

  • hierarchia definicji klasy lub klasyfikacja. Lepiej skorzystaj z jednej z nich, jeśli będziesz wspierać dodawanie różnych klas do tego samego pola (jak różne rodzaje mieczy). Profesjonalista w kategoryzacji: klasa może mieć wiele kategorii, a nie stałe drzewo dziedziczenia, dobre rzeczy, gdy chcesz zebrać „wszystkie umiejętności” gracza, gdy wydajesz XP na doskonalenie umiejętności ... :-)
  • obsługa trwałości: musisz stworzyć ogólne rozwiązanie do przechowywania hierarchii obiektów na zewnątrz, np. w pliku właściwości lub pliku JSON. Użyj formatu czytelnego dla człowieka, BEZ serializacji binarnej, jeśli chcesz utrzymać mózg w dobrej formie.
  • przechowywanie instancji: wkrótce zrozumiesz, że „świat” twojej gry lepiej jest trzymać w jednym miejscu. Pewien miecz NIE jest własnością twojego gracza, ale byt na świecie w twojej grze (gracz może go zgubić, ktoś może go znaleźć itp.), Więc wiele z tych „obiektów” w twoim drzewie jest faktycznie ODNIESIENIAMI do bytów (podczas gdy inne, takie jak zdrowie gracza, są tak naprawdę tylko atrybutami). Będziesz musiał rozdzielić dwa typy, mieć globalną pamięć dla instancji, które mogą rozpoznawać odwołania. Pozwoli to również zaoszczędzić czas podczas szeregowania stanu gry, a wiele podmiotów odnosi się do tego samego innego podmiotu (np. „Lokalizacja” wielu graczy w tej samej świątyni).
  • (i wspominając o prawdziwym młynku mózgowym: podobieństwo pamięci klasowej i pamięci instancji; fakt, że deklaracja typu może być instancjami samych obiektów w taki sam sposób, jak komponenty programu, aktywne okna, sesje użytkownika itp. To jest ziemia takich maniaków jak ja.)

W każdym razie mam nadzieję, że możesz skorzystać z tej sesji rozgrzewki.

Lorand Kedves
źródło
1

Nie dam ci długiej odpowiedzi, ale już wcześniej spotkałem się z taką sytuacją i szczerze mówiąc, zrezygnowałem z prób wykorzystania dowolnej istniejącej struktury danych. Po prostu stworzyłem własny obiekt, który mógłby akceptować nowych rodziców i dzieci, podobnie jak Węzeł XML.

Jednak w twoim przypadku myślę, że użycie klasy Xml pomoże. Następnie możesz mieć właściwości dla każdego węzła, które informują cię, czy dana klasa jest umiejętnością, i możesz łatwo uzyskać rodziców i dzieci z dowolnego węzła, którego chcesz użyć w polu kombi lub w inny sposób.

Ponadto chciałbym dodać, że nie powinieneś uciekać od myśli o dużej ilości tekstów / ciągów. Gry zwykle wymagają sztucznej inteligencji, a sztuczna inteligencja zwykle wymaga dużej ilości tekstów.

Chibueze Opata
źródło
Ta gra nie jest odtwarzana przez program, po prostu ma stałe dane i logikę. Z pewnością zajrzę do XML-a. Dzięki!
Pureferret,