###Todo### - Pse-Lambda-das-Spiel/LambdaDasSpiel GitHub Wiki

Generell: UML-Diagramme + Dokumentation + Entwurfsentscheidungen + Sequenzdiagramme falls nötig

UPDATE: Wenn etwas fertiggestellt ist oder derjenige denkt, es sei fertiggestellt, dann bitte ein "done" hintendrin


  • Undo-Button im Editor-Modus (latex)
  • generateNewColor(in alpha conversion)
  • Änderung Drag&Drop Funktionalität

Frage: Ist es erlaubt (/soll man es so machen) von wegen MVC, dass man z.B. die stage erst beim Aufruf initialisiert. Also erst durch show(). Ich bin praktisch davon ausgegangen, dass z.B. eine Profiländerung per Observer alle VC updaten muss. Oder z.B. der Münzenstand im Hauptmenü. Ich dachte er sollte permanent per Observer vom Profil aktualisiert werden. Kann man das auch praktisch erst durch beim Aufrufen machen? Wenn ja würd ich ziemlich viel von dem Observer-Scheiß bei mir nicht brauchen. Antwort bitte :) Ohne zu wissen wie wir das machen, kann ich mein Zeug nicht wirklich beenden.

UPDATE

LevelModel:

  • Level Einschränkungen: mögliche Red Strategien, Anfangsterm, benutzbare Elemente (Variable, Abstraktion, Applikation/Klammern) müssen auch noch im LevelModel gespeichert sein
  • keine Klammern hinter Status in der Notiz public enum Status mein fehler
  • LambdaTerm muss LambdaRoot sein, Wurzel eines gültigen Terms ist immer eine LambdaRoot geändert
  • lieber eine eigene Methode zum Laden der Level (inklusive Progress). Entweder nur Meta-Daten im Ladebildschirm laden und Level erst wenn sie gestartet werden. Oder alle Level komplett im Ladebildschirm zu Beginn laden.
  • Level brauchen keine setter-Methoden für Dinge, die direkt aus der Datei geladen werden. Da kann die static lade-Methode die privaten Member-Variablen vom Level direkt ansprechen. Oder per private Konstruktor. Setter werden ja vom Shop aus aufgerufen
  • Haben wir eine eigene Musik-Datei pro Level? Das braucht ziemlich viel Speicherplatz und Arbeit, besser wenn wir pro Difficulty eine Musik/ Hintergrundbildschirm haben. Musik und Hintergrundbilder, die man im Shop kaufen kann, werden doch eh nur in der Sandbox verwendet oder? Sonst brauchen wir auch keine verschiedene Musik pro Difficulty. Musik und Image für Sandbox, ansonsten ein Image und Sound pro Schwierigkeitsgrad
  • LevelStatus als private Member-Variable und ne getter-Methode dazu Überleg grad, ob man das überhaupt benötigt, oder ob man mit dem Fortschrittsinteger vom Profil einfach hochzählen kann
  • Es gibt nicht nur ein Sprite, sondern verschiedene Sprites für Lämmer mit/ ohne Zauberstab und Edelsteine. Die sind aber auch nicht level-spezifisch sondern müssen iwo anders gehandhabt werden. das Sprite war eigentlich auch für die Sandbox gedacht, aber ja, auch da sollte man ja mehrere ändern können :s
  • Sandbox ist eine eigene Instanz vom Level-Typ, die im Progamm gehardcoded wird. Alle anderen Level werden in json Dateien gespeichert. D.h. das Sandbox-LevelModel muss irgendwo instanziiert werden und auch ansprechbar sein. Am einfachsten ist es, wenn das einfach Teil der levels-Liste ist. Was meinst mit "teil der Levels-Liste? Hatte mir gedacht, dass die Sandbox immer der Head ist
  • Tutorial-Nachrichten sind auch mit dem Level verbunden, d.h. die müssen auch iwie im LevelModel vorkommen Also? String? Image? hatten wir da was festgelegt?

LevelViewController: geändert

  • nenn es mal LevelSelectionController oder so, sonst hört es sich so an, also ob das die View zu einem einzigen Level wäre
  • sollte Unterklasse von Controller sein

ProfileModel:

  • benötigt ShopModel anstatt purchased[] (soll man die Coins auch ins ShopModel verlegen?)
  • ProfileModelObserver dazu? und entsprechend ein ProfileView, welches genau ein Profil anzeigt (für was den ProfileView?, habs jetzt ohne gemacht)
    --- Mach doch am besten ne eigene View Klasse, die genau ein Profil im ProfileSelection Menü anzeigt (vll inklusive Controller Zeugs). Das ist dann gut gekapselt und auch einfacher aufrufbar vom ProfileSelectionVC, da erstellst du nur mehrere dieser ProfileViewController und die regeln dann alles selber.

ProfileManager:

  • Profil-Editierung muss nicht das gesamte Profil ersetzen, sondern braucht nur die konkreten Variablen im ProfilModel ändern welche dann übers Observable Muster an die View weitergegeben werden (Wird nur beim Namen gemacht. Sorgt dafür das jedes Profil einen eindeutigen Namen hat)

ProfileSelection:

  • muss die Profilidentifizierung über den Namen als string gehen? das geht besser über eine Referenz zu einer ProfileModel Klasse, da gibts pro Profil ja auch nur genau eine Klasse (Kann ich ändern. Seh aber eigentlich keinen Grund dafür, außer vllt. dass es "schöner" aussieht)
    --- Also du müsstest dann halt die ganze Liste durchgehen und die Strings vergleichen, selbst mit ner Map muss der da evtl Vergleiche oder Berechnungen durchführen (ist zwar nicht viel, aber trotzdem nicht nötig). Wann braucht man getProfile(name: String) überhaupt? Wenn ich das richtig sehe läd doch jeder VC die Profil-Info, die es benötigt, über ProfileManager.getManager().getCurrentProfile().get...() selber, es interessiert ja nur das aktuelle Profil.
    --- Ja, getProfile braucht man nicht. Die Liste müsste man ja trotzdem immer durch gehen, um auch sicherzustellen, ob das Profil das man bei setProfile angibt auch wirklich eins von den in der profiles- Liste ist. So wie ich es gemacht hab, kann man halt praktisch nichts falsch machen. (2 Profile mit gleichem Namen, mehr profile als erlaubt etc.)

ShopItemModel:

  • wie/ wann werden die geladen?
  • wie kann man sie vom Editor- und Reduktionsmodus aus ansprechen? sie werden in die Sandbox gesetzt (Setter vom Level)

ShopItemViewController:

  • bekommt selber ein Event, wenn es geklickt wurde, und aktiviert/ kauft sich dann selber. Also braucht die Funktionalität dazu nicht im ShopViewController stehen
  • Unterklasse von Actor (libgdx-Klasse. Schau dir dazu am besten den scene2d Kram vom libgdx an)
  • müsste im Konstruktor das ShopItemModel bekommen, welches es anzeigt

DropDownMenuViewController:

  • brauchst du garnicht mit generics machen. Es interessiert das Dropdownmenu ja nicht von welchem Typ die ShopItems sind, die es anzeigt. Alle Funktionalität der items die vom Dropdownmenu aus also erreichbar sein muss, muss dann in der ShopItemModel Klasse stehen und nicht in den konkreten Unterklassen.
  • bekommt im Konstruktor mitgeteilt, welche Items es anzeigen soll, und eine Beschreibung ("Musik" usw)
  • update Methode wofür? copy&paste fehler

ShopModel:

  • den Status der Items über nen Array zu regeln ist nicht so elegant, wenn viele Zellen unbenutzt bleiben, weil es Lücken in den ItemIds gibt. Also entweder werden die item ids von 0-n hochgezählt unabhägig davon, welchen Typ es hat (finde ich besser), oder du musst ne Map machen, die ids auf status mapped.
  • du brauchst nicht mehrere Member-Variablen für verschiedene Dropdownmenüs, sondern am besten eine Liste von dropdownmenus. Es ist ja außer bei der Initialisierung nicht wichtig, was für items das dropdownmenü anzeigt, weil die Items die Funktionalität selber haben.
  • Laden der Meta-Daten zu den ShopItems fehlt noch
  • +ItemStatus wofür?
  • wenn du hier ne Liste von ShopItemModels machst, dann brauchst du auch kein Array für den Status der Items, wenn das ShopItemModel ne Member-Variable status hat.

ShopViewController:

  • Kauf und Aktivier Funktionalität besser in den Shop-Items selber.

StatistikModel:

  • english(done)
  • resetStatistic wird wo benötigt?(da war gedacht dass wir im Statistikmenü ein Button reset hinzufügen)
    --- Ok, das muss dann noch im entsprechenden Kapitel im Entwurfsheft angemerkt werden.
  • auch List anstatt ArrayList(done)
  • StatistikModel muss global verfügbar sein und einfach editierbar sein, z.B. playTime hinzufügen über nur eine Methode(alle statistiken sind über setMethoden editierbar)
    --- set Methoden braucht man doch garnicht, innerhalb des Spielablaufs werden solche Werte immer nur erhöht. Das Initialisieren der Werde passiert ja eh innerhalb der Klasse, da brauch man also auch keine setter. Es ist umständlich dann für eine Änderung zwei verschiedene Methoden aufrufen zu müssen.
  • es müssen auch alle Statistiken hier stehen, die wir haben wollen. Also z.B. verzauberte Lämmer usw. In der Implementierungsphase geht das nicht mehr(wozu braucht man Anzahl der verzauberten Lämmer ??? welche Statistiken fehlen noch ? )
  • successRate kannst du nicht einfach so abspeichern, sondern #versuche insgesamt und #versuche bestanden. getSuccessRate gibt dann den quotienten wieder.(done)
  • Liste von bestandenen Leveln ist überflüssig, da reicht ein einzelner Integer( done ,levelId verwendet anstatt level )
  • Observable/ Observer Kram fehlt, StatistikViewController muss dass ja iwie anzeigen(in Bearbeitung)
  • update/ toMainmenu s.o. (in Bearbeitung)

Generell:

  • Zu jeder Unterklasse von Observable braucht es ein eigenes Observer-Interface, das entsprechende update-Methoden enthält. Das Observer-Interface ist dann der Generics-Typ im Observable. Bsp: ReductionModel kann überwacht werden mit einem Interface ReductionModelObserver, deshalb ist ReductionModel eine Unterklasse von Observable<'ReductionModelObserver>
  • Wenn ihr mit Latex-Dokumentationen anfangt, dann auf alle möglichen Exceptions achten. Vll auch ne eigene Exception-Unterklasse erstellen wenn nötig.
  • Kopiert einfach die Formatierung von der Latex-Dokumentation, die schon da ist, und passt das dann so an wie ihr es braucht, dann ist es einheitlich.

Frage: Wenn jetzt z.B. Profil oder Sprache geändert wird muss das (praktisch überall) geupdatet werden. Dann muss ich in den Klassen alle GUI-Elemente, die so verändert werden, als globale Variable hinschreiben (um sie in der update Methode noch ansprechbar zu machen)? Seh ich das so richtig?
--- Sprache usw können eh nur geändert werden, wenn man sich ausloggt. D.h. dann könnte man bei jedem Einloggen die ViewController neu instanziieren oder eben ne extra updateLanguage Methode hinzufügen. Die normale update-Methode in den verschiedenen VCs war ja zum Übergang zwischen den VCs gedacht und ist garnicht static. D.h. man könnte auch bei jedem update-Aufruf schauen ob das Profil geändert wurde und dann entsprechend die GUI-Elemente anpassen.
--- Ah, sorry. Ich hab normale Attribute gemeint nichts mit static und mit update meinte ich jetzt die notify Methoden. Dass dann praktisch jeder VC den ProfileModelObserver implementiert. Heißt z.B. der Settings-vc hat ne SettingsModel-Variable und die einzelnen Label und so. Beim changedProfile(p)-Aufruf würde es dann settings.removeObserver(this);settings=p.getSettings; settings.addObserver(this) aufrufen (und halt noch die Anzeige anpassen). Hab ich so gedacht. Man könnte aber auch alles nochmal neu laden.(könnte evtl. zu lange dauern, da man ja praktisch das komplette Spiel neu startet)
--- Du meinst ProfileManagerObserver, oder? Sonst würde die Referenz in den VCs zum ProfileModel beim Profilwechsel verloren gehen. Dann passen wir noch alle VCs darauf an.
--- Ja, meinte ich. Aber mit neu laden würde es halt auch gehen und würde uns Arbeit sparen, da man in den Diagrammen und so nicht alle Labels usw. angeben müsste. Und zu dem was du beim StatistikModel zu globalen ansprechbar gesagt hast: Das würd ja dann wenns fertig ist auch eine Variable im ProfileModel. Das würde man dann wohl auch (wo es häufig gebraucht wird) als Variable in die Klasse schreiben und bei changedProfile einfach durch das des neuen Profils ersetzten. (Ach ja, soll man eigentlich bei den observer Methoden Parameter übergeben? z.B. bei changedProfile das neue Profil als Parameter. Macht es einfacher da man das ja sowieso haben will. Aber in MVC soll ja glaub das View die Sachen selbst anfordern)
--- Jo es gibt aber auch verschiedene MVC Typen und der Betreuer meinte auch, dass MVC garnicht so genau definiert ist. Also ist es denke ich ok wenn wir das so machen.
--- Äh.. ich glaub ich machs doch ohne die Parameter. Das ist ja nur eine Zeile mehr und z.B. changedProfile muss ja beim Settings-VC das SettingsModel nicht nur ersetzen, sondern halt auch noch die Anzeige updaten. Dafür könnte man dann die ObserverMethoden vom SettingsModel aufrufen, für die man dann wieder den Parameter selbst holen müsste. Ohne Parameter würde das wesentlich schöner gehen. Man könnte dann auch zum initialisieren des Ganzen im Konstruktor einfach changedProfile() verwenden. (und in dem Fall sogar Code-Zeilen sparen)

Und noch was: Methoden von Interfaces müssen ja nochmal in die implementierenden Klassen geschrieben werden(muss ich noch machen). Kann man davon ausgehen, dass alle eine leere default Implementierung haben, sodass man z.B. update-Methoden, die man nicht benötigt, nicht hinschreiben muss? Oder wie soll ich das machen?
--- Wenn du das so bei der Beschreibung im Entwurfsheft angibst, sollte das kein Problem sein. Ist auch in einigen Fällen so schon im Heft, also "In der Standard-Implementierung ...". Sonst kann man immernoch im UML-Diagramm ne Notiz hinzufügen, aber Notizen würde ich eher nur so wenige wie möglich machen.