Dungeon-CampusMinden / Dungeon

The "Dungeon" is a tool to gamify classroom content and integrate it into a 2D Rogue-Like role-playing game.
MIT License
15 stars 36 forks source link

Core: Modellierung der KeyboardConfig überdenken #1544

Open Flamtky opened 2 months ago

Flamtky commented 2 months ago

Ich finde es ja schon unnötig 3 KeyboardConfig Dateien zu haben. Einmal haben wir die:

Jetzt habe ich noch die Implementierung von der Maussteuerung und den Cursor-Tasten. Sollen die jetzt neben den anderen Bewegungs-Tasten in game oder doch lieber in Dungeon weil da auch die HeroFactory ist wo das überhaupt auch erst verwendet wird? Später kommt auch noch die Steuerung von dem UI für die Maus.

Um zum Punkt zu kommen. Warum überhaupt die Steuerung in game definieren wenn doch eh die erst in Dungeon benutzt wird? So wäre es doch sinnvoll Game's KeyboardConfig zu verschieben und mit reinzumergen in z.B. Dungeon's KeyboardConfig

Flamtky commented 2 months ago

@cagix Was ist deine Meinung dazu?

cagix commented 2 months ago

Mir fehlt ehrlich gesagt der Überblick. Im Prinzip bin ich komplett bei Dir, aber am Ende braucht das vielleicht doch irgendwer irgendwo? Und so lange die DSL nicht de-integriert ist und noch so fies tief in core und contrib verankert ist, traue ich mich nicht an ein Refactoring ...

Edit: @Flamtky Ein wenig liegt es auch an der nachträglichen Trennung eines Gesamtprojekts in ein absolutes "Bare"-Framework (core), wo man die minimale Basis für ein eigenes Spiel hat und alles restliche selbst implementieren muss, und ein eher direkt nutzbares, darauf aufbauendes Framework (contrib). Damit man in core dann überhaupt was machen kann, braucht es natürlich auch ein minimale Eingabekonfiguration. Die wird dann in/für contrib dann nochmal aufgebohrt.

Flamtky commented 2 months ago

Damit man in core dann überhaupt was machen kann, braucht es natürlich auch ein minimale Eingabekonfiguration.

Stimme ich zu, aber das Movement wird erst im dungeon umgesetzt, in der HeroFactory. Sollte man nicht dann vlt die Factory mit in core reinverschieben? Zumindest eine Art Standard Movement für einen Spieler? Ansonsten soll ich dann die Maus und die Cursor-Tasten Tastenbelegungen in Dungeon festlegen?

cagix commented 2 months ago

Damit man in core dann überhaupt was machen kann, braucht es natürlich auch ein minimale Eingabekonfiguration.

Stimme ich zu, aber das Movement wird erst im dungeon umgesetzt, in der HeroFactory. Sollte man nicht dann vlt die Factory mit in core reinverschieben? Zumindest eine Art Standard Movement für einen Spieler?

Ja, vermutlich. Davon abgesehen gefällt mir die Art der Umsetzung nicht mal ansatzweise. Man will eigentlich ein Enum haben, welches man überschreiben kann - das gibt es aber so in Java nicht. Nur die vorliegende Umsetzung ist einfach nur schräg.

Ansonsten soll ich dann die Maus und die Cursor-Tasten Tastenbelegungen in Dungeon festlegen?

Konsequent wäre, das in Dev-Dungeon zu machen 🤪 Aber das macht es nicht besser. Insofern ja, packe es mit nach contrib, außer Du hast eine bessere Lösung :)

tgrothe commented 2 months ago

Klingt eher nach einer simplen (String-/Char-/Key-...) Map (und Methoden zum Ändern/Hinzufügen) ... Eine Map, die die Zuordnungen vordefiniert, und noch eine Map, in der die aktuellen Zuordnungen gespeichert werden. Aber das ist nur (schnell, nicht gründlich) von oben betrachtet.

cagix commented 2 months ago

Klingt eher nach einer simplen (String-/Char-/Key-...) Map (und Methoden zum Ändern/Hinzufügen) ... Eine Map, die die Zuordnungen vordefiniert, und noch eine Map, in der die aktuellen Zuordnungen gespeichert werden. Aber das ist nur (schnell, nicht gründlich) von oben betrachtet.

Wir haben drei Stufen:

  1. Es gibt die Key-Code aus libGDX (tatsächlich vom Typ int), die sollten nochmal gekapselt werden, damit es nach außen keine libGDX-Abhängigkeiten in der API gibt.
  2. Dann braucht es die Zuordnung Key zu Action in der PlayerComponent, um tatsächlich irgendwas auszuführen.
  3. Damit (2) nicht hard coded ist und die Tasten per Konfiguration wechselbar sind, gibt es sowas wie eine Übersetzung, also Konstanten, die auf einen bestimmten Key-Code zeigen. Diese Konstanten werden dann in (2) statt der tatsächlichen Keys genutzt.

Und (3) soll nun noch dynamisch passieren, also per Einlesen aus einem File oder per Konfiguration aus der DSL oder per Konfiguration in einer Java-Klasse für ein konkretes Spiel.

Damit der Code kompilierbar ist, brauchen wir sowas wie Konstanten. Das schreit eigentlich nach Enum - da könnte man auch die Werte (Key-Codes) gut verpacken. Nur muss das (a) zur Compile-Zeit feststehen und (b) kann man das nicht erweitern (Enums können nicht voneinander ableiten). Einfach nur einen Satz Konstanten ala public static final FOO = ... zu definieren ist auch nicht besonders hilfreich, weil dann die Typsicherheit fehlt (die Konstanten haben keinen gemeinsamen Obertyp).

Mir fehlt grad ein wenig die Fantasie, wie mir Maps da helfen könnten. Ich kann zwar eine Map<KeyKonstante, libGDX-Key-Code> definieren, aber ich habe dann immer noch das Problem mit der Definition und Erweiterung der Konstanten selbst.

tgrothe commented 2 months ago

Mir fehlt grad ein wenig die Fantasie, wie mir Maps da helfen könnten. Ich kann zwar eine Map<KeyKonstante, libGDX-Key-Code> definieren, aber ich habe dann immer noch das Problem mit der Definition und Erweiterung der Konstanten selbst.

Ganz grob hatte ich an so etwas gedacht (aber vielleicht falsch beschrieben):

import com.badlogic.gdx.Input;

import java.util.HashMap;
import java.util.Map;

public class KeyRegistryExample {
    private static Map<Integer, String> keyActionMap = new HashMap<>();
    private static Map<String, Integer> actionKeyMap = new HashMap<>();

    static {
        // Default key bindings
        // Hint: See com.badlogic.gdx.Input.Keys.toString for a list of key names
        addKeyAction("Up", "moveUp");
        addKeyAction("Down", "moveDown");
        addKeyAction("Left", "moveLeft");
        addKeyAction("Right", "moveRight");
    }

    public static void addKeyAction(String keyName, String action) {
        addKeyAction(Input.Keys.valueOf(keyName), action);
    }

    private static void addKeyAction(int key, String action) {
        keyActionMap.put(key, action);
        actionKeyMap.put(action, key);
    }

    public static String getKeyForAction(String action) {
        return Input.Keys.toString(actionKeyMap.get(action));
    }

    public static String getActionForKey(String keyName) {
        return keyActionMap.get(Input.Keys.valueOf(keyName));
    }
}

Also, man speichert für die ~256 möglichen Keys Strings. Damit wäre libgbx gekapselt und wir könnten eine "Standardbelegung" vorgeben. Als "Action" habe ich hier im Beispiel einfach auch Strings verwendet.

cagix commented 2 months ago

Also, man speichert für die ~256 möglichen Keys Strings. Damit wäre libgbx gekapselt und wir könnten eine "Standardbelegung" vorgeben. Als "Action" habe ich hier im Beispiel einfach auch Strings verwendet.

@tgrothe ich glaube, so einfach wird das nicht. im code sollten konstanten für die tasten nutzbar sein, die einen gemeinsamen typ haben, und deren einsatz vom compiler geprüft wird. dieses stringbasierte nachschlagen in maps finde ich furchtbar, das muss auch bei den texturen/animationen noch deutlich besser werden.

die map für die verknüpfung taste/aktion haben wir an sich ja bereits - aktuell werden die konstanten für die tasten vom programmierer eines konkreten spiels selbst definiert und dann in der playercomponent mit einer action verknüpft.


das problem ist nur, dass die tasten nicht in core einmal durchdekliniert werden. vielleicht sollte man das machen - dann kann man auch ein enum nehmen. die zuordnung taste/enum-konstante zu aktion passiert ja in der playercomponent - weiss grad wirklich nicht, warum da aktuell so viele zwischenebenen drin sind.

cagix commented 1 month ago

Duplikat von Enge Verwandtschaft mit/zu #1529!!