Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Legend

Alter Hase

  • »Legend« ist der Autor dieses Themas

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

1

14.08.2017, 12:02

Inputhandling > Wie bekomme ich am elegantesten die Events zum If oder Command?

Hallo zusammen,

es gibt ja schon einen Thread zum Inputhandling, der sich darum dreht, wie man einen Tastendruck am besten verarbeitet.
Ich frage mich, wie bekomme ich am elegantesten den Tastendruck zu der Stelle, der das Event verarbeitet?

Aktuell habe ich eine Klasse mit einem C# Event, an das man sich anhängen kann. Das bedeutet, dass sich jede Stelle, die
Tastendrücke verarbeiten will, an das Event an der Instanz meiner Input-Klasse anhängt. Und das finde ich etwas mühsam,
da ich Referenzen auf die Inputklasse ziemlich wild im Code verstreut habe, auch wenn ich das schon durch einen IoC-Container
reduziere.

Ich überlege daher, ob ein Eventaggregator Sinn macht. Ich muss dann aber sicherstellen, dass sich die Konsumenten der Events
rechzeitig abmelden. Ein Beispiel: Ich habe aktuell ein Level offen und die normale Spiellogik kümmert sich um die Verarbeitung
der Benutzereingaben. Jetzt mache ich ein Ingamemenü auf und jetzt übernimmt das Menü die Verarbeitung der Eingaben und das normale
Spiel soll die Eingabe nicht mehr mitbekommen! So eine Aufteilung an die richtigen Empfänger übernimmt aber kein Eventaggregator,
so dass mir diese Lösung auch nicht 100% zu passen scheint.

Also, wo liegt mein Denkfehler? Ich hab zwei 80% Lösungen aber komme nicht auf die 100% Lösung.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Wirago

Alter Hase

Beiträge: 1 193

Wohnort: Stockerau

Beruf: CRM Application Manager

  • Private Nachricht senden

2

14.08.2017, 12:35

Zitat

Jetzt mache ich ein Ingamemenü auf und jetzt übernimmt das Menü die Verarbeitung der Eingaben und das normale
Spiel soll die Eingabe nicht mehr mitbekommen!


Ich verwende für so etwas einfache GameStates (Playing, Paused, etc.)
Während im Playing GameState alle Befehle ausgeführt werden, werden im Pause Status nur die zur Verfügung stehenden Optionen getriggert.

Sieht im Groben etwa so aus:

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
if (curGameState == GameState.Paused)
{
    if (mouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released)
    {
        string actionToBeTriggered = inputHandler.HandleMouseclick(mousePosition);

        if (actionToBeTriggered == "quit")
            Exit();

        if (actionToBeTriggered == "resume")
            curGameState = GameState.Playing;

        if (actionToBeTriggered == "load")
            gameStorage.InitiateLoad();

        if (actionToBeTriggered == "save")
            gameStorage.InitiateSave();
    }
}


Nachdem das Menü nur diese 4 Möglichkeiten bietet (eine für Optionen kommt wohl noch dazu) habe ich auf irgendwelche Event-Patterns etc. verzichtet.
Wenn dann Spiel läuft, werden die Befehle für Aktionsleisten oder Benutzen des Inventars mit berücksichtigt. Nachdem das im Pause-Menü nicht möglich sein soll, werden die einfach weg gelassen.

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

3

14.08.2017, 13:47

Ein Beispiel: Ich habe aktuell ein Level offen und die normale Spiellogik kümmert sich um die Verarbeitung
der Benutzereingaben. Jetzt mache ich ein Ingamemenü auf und jetzt übernimmt das Menü die Verarbeitung der Eingaben und das normale
Spiel soll die Eingabe nicht mehr mitbekommen!
Erinnerst du dich noch an meinen Vorschlag, eine grosse Tabelle für alle Aktionen, in der dann steht welche Tasten diese die Aktion ausloesen können? Die Tabelle erweiterst du einfach um eine Spalte, die beschreibt wann diese Aktion ausgeführt werden kann. Wenn man den Inputhandler nun nach Aktion X fragt, kann schaut er in der Tabelle nach und überprüft halt nicht nur ob die zugewiesene Taste gedrueckt ist, sondern auch diese Bedingung noch dazu. IsPressed(Jump) liefert im Menu nun immer ein false.

equinox

Frischling

Beiträge: 56

Beruf: Student

  • Private Nachricht senden

4

14.08.2017, 19:09

Du könntest auch eine Verarbeitungsreihenfolge der Events garantieren. D.h. Gui-Elemente haben eine höhere Prioriät als beispielsweise Ingame Elemente und "klauen" sich die Events. Solltest du einen Event-Queue haben könntest du dann beispielsweise das Event daraus entfernen, wenn es von einem GUI-Element verarbeitet wurde. Libgdx bietet im groben ein ähnliches Inputhandling an. Allerdings würde ich eher zu den States oder halt zu TGGC Lösung tendieren, weil halt einfacher zu machen.

Legend

Alter Hase

  • »Legend« ist der Autor dieses Themas

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

5

15.08.2017, 10:23

Ah, das Chain of Responsibility-Pattern. Daran hatte ich bislang genausowenig wie an die Tabelle von TGGC gedacht.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

15.08.2017, 11:18

Aber CoR würde das Problem an sich doch auch nicht unbedingt beheben. Die normalen Bearbeiter müssten beim Wechsel ins Menü zumindest ausgehangen werden. Ich würde einfach erst mal zu den Gamestates raten. Der Vorschlag von TGGC ist an sich auch gut, die Tabelle könnte aber relativ groß und unübersichtlich werden. Vor allem wenn für alle Spielzustände und Möglichkeiten Bedingungen modelliert und eingetragen werden. Warum nicht einfach den benötigten Code in den Gamestate schieben und fertig? So kannst du hinterher jeden Zustand für sich gesondert betrachten, behältst die Übersicht und es ist einfach umzusetzen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Legend

Alter Hase

  • »Legend« ist der Autor dieses Themas

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

7

15.08.2017, 12:18

Stimmt, ich müsste ja den Anfang der Kette manipulieren und nicht das Ende, da das neue Menü die höchste Priorität genießen soll. Und das ist nicht toll für das CoR.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

8

15.08.2017, 12:27

Die Bearbeiter könnten in einer Priority Queue liegen und das Menü könnte dann eine möglichst große Priorität haben. Fände ich aber nicht besonders schön da das am Ende schwierig zu überblicken ist. Direkte Cuts wie bei normalen Statemachines finde ich da etwas schöner.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

equinox

Frischling

Beiträge: 56

Beruf: Student

  • Private Nachricht senden

9

15.08.2017, 21:38

Ah, das Chain of Responsibility-Pattern. Daran hatte ich bislang genausowenig wie an die Tabelle von TGGC gedacht.

Ah danke, jetzt hab ich endlich mal einen Namen dafür :)

Werbeanzeige