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

LeBusch

Frischling

  • »LeBusch« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student B.Sc. Informatik

  • Private Nachricht senden

1

19.03.2014, 20:07

[C#] Umsetzung von Menü-Klasse

Moin,

Ich bräuchte Euren Rat bei der Erstellung von Menüs für eines meiner Projekte. Und zwar habe ich vor, mehrere Menüs zu implementieren, die die grundlegenden Funktionen (Hoch, Runter, Auswahl, Auflistung der Elemente) von einer Klasse "Menu" erben. Die Klassen für die Menüs selbst (Pausenmenü, Startbildschirm usw.) wollte ich jedoch statisch deklarieren, damit ich aus den übrigen Klassen (Steuerung usw.) Zugriff auf die Menüs habe. Allerdings beißen sich Vererbung und statische Klassen scheinbar.

C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public static class Pausemenu : Menu
{
  [...]
}

public class Menu
{
  private int _selection;

  public void Up()
  {
   [...]
  }

  public void Down()
  {
   [...]
  }
}

Versuche ich jetzt aber, von außerhalb "Pausemenu.Up()" aufzurufen, bekomme ich folgende Meldung: "Für das nicht statische Feld, die Methode oder die Eigenschaft "Menu.Up()" ist ein Objektverweis erforderlich.". Ist soweit auch logisch, weil ich die Basisklasse nirgendwo initialisiert habe. Ich wüsste aber ehrlich gesagt auch nicht, wo. Kann mir eventuell jemand auf die Sprünge helfen? Danke!

Grüße,
LeBusch

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »LeBusch« (19.03.2014, 20:13) aus folgendem Grund: Typo


Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

2

19.03.2014, 20:12

Ich glaube du willst ein Singleton implementieren: http://msdn.microsoft.com/en-us/library/ff650316.aspx
Wobei man über Singletons allgemein eine Diskussion führen könnte. Das Pattern ist nicht ohne Nachteile.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

LeBusch

Frischling

  • »LeBusch« ist der Autor dieses Themas

Beiträge: 81

Beruf: Student B.Sc. Informatik

  • Private Nachricht senden

3

19.03.2014, 20:27

Ich glaube du willst ein Singleton implementieren: http://msdn.microsoft.com/en-us/library/ff650316.aspx
Du meinst, dass ich je ein Singleton für das jeweilige Menü erstelle, das dann eine Klasse verwaltet, die wiederum von "Menu" erbt?

Strike

Frischling

Beiträge: 36

Wohnort: Wien 1200 und Techelsberg 9212

Beruf: Junior Software-Entwickler & Software Testing

  • Private Nachricht senden

4

19.03.2014, 21:27

Naja, so schlecht sind Singletons nicht.

Du darfst sie halt nur dann einsetzen wenn du sie wirklich brauchst.
Also wenn das Element/Objekt/die Klasse nur einmal vorkommen soll.

Bei einer Menüklasse ist das vielleicht nicht so sinnvoll da du sie für mehrere Menüs verwenden willst. ^^

NachoMan

Community-Fossil

Beiträge: 3 885

Wohnort: Berlin

Beruf: (Nachhilfe)Lehrer (Mathematik, C++, Java, C#)

  • Private Nachricht senden

5

19.03.2014, 21:42

Du übergibst dem jeweiligen Menü einfach alles was es braucht. Da brauchst du keine statische, faktisch Globale "Zugriffsstelle". Von dem konkreten Menü sollte nur die Klasse etwas wissen, die sie instanziiert.
"Der erste Trunk aus dem Becher der Erkenntnis macht einem zum Atheist, doch auf dem Grund des Bechers wartet Gott." - Werner Heisenberg
Biete Privatunterricht in Berlin und Online.
Kommt jemand mit Nach oMan?

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

6

19.03.2014, 22:00

Ich glaube du willst ein Singleton implementieren: http://msdn.microsoft.com/en-us/library/ff650316.aspx
Du meinst, dass ich je ein Singleton für das jeweilige Menü erstelle, das dann eine Klasse verwaltet, die wiederum von "Menu" erbt?

Jep, das wäre die Konsequenz. Wobei man genauer wohl sagen würde, dass jedes Singleton ein Objekt verwalten würde. ;)

Aber NachoMan's Weg ist wohl eigentlich besser, von daher solltest du wohl eh den einschlagen ...
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

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

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

7

19.03.2014, 22:59


Also wenn das Element/Objekt/die Klasse nur einmal vorkommen soll.


Um Gottes Willen Nein. Wenn etwas nur einmal vorkommen darf. Von sollen ist bei einem korrekten singleton nicht die Rede.

Toemsel

Treue Seele

Beiträge: 310

Wohnort: OÖ

Beruf: Student und Programmierer

  • Private Nachricht senden

8

20.03.2014, 00:16

Du kannst kein Objekt einer statischen Klasse erstellen ;)
Entferne einfach das static und erstelle eine static Variable.

C#-Quelltext

1
2
public static Menu PauseMenu;
PauseMenu = new Pausemenu();


Auch Vererbung bei statischen Klassen macht keinen Sinn und lässt der Compiler eh nicht zu.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

9

20.03.2014, 09:53

Wie bereits geschrieben wurde, sind Singletons für Fälle gedacht, in denen bei der Erzeugung von 2 Instanzen das Universum in sich zusammenstürzen würde (bspw. weil es dadurch zu einer Division durch 0 kommen würde ;D).
Aber mal Spaß bei Seite: Wenn es lediglich zu einer Exception kommen würde, wäre das (meiner Meinung nach) kein ausreichender Grund für ein Singleton

Die andere Eigenschaft von Singletons ist es, dass global auf diese zugegriffen werden kann. Der daraus resultierende Nachteil ist, dass Abhängigkeiten erhöht werden. Würde der Inputmanager die Menüs direkt über Inputs informieren wollen, müsste dieser jedes einzelne Menü kennen, um die entsprechenden Methoden aufrufen zu können. Auch wird so die Möglichkeit des automatisierten Testens schwer beeinträchtigt oder so stark erschwert, dass es sich "nicht lohnt", Testfälle zu schreiben. (Ein Testfall würde das Initialisieren des gesamten Systems erfordern und es müsste ausnahmslos jede mögliche Konstellation durchgetestet werden.)
Es wird zwar damit argumentiert, dass man sich so das Durchreichen von Objekten und somit von Parametern spart. Würde man aber mal nicht auf diese Parameter verzichten, würde man überhaupt erst sehen, welche Objekte sich gegenseitig kennen müssen, um richtig zu funktionieren (-> die Abhängigkeiten würden nicht mehr verschleiert werden). Man sollte also nicht gegen die Anzahl der Parameter etwas machen (dann wäre man einfach nur faul, da man sich lediglich Schreibarbeit spart), sondern sein Design überdenken.


Abgesehen davon gibt es aber auch noch andere Schwächen an dem bisherigen Vorgehen:
Der InputManager sollte sich grundsätzlich nur um das Auslesen des Inputs und ggf. noch um die Übersetzung kümmern. (Übersetzen kann sich auf die "Bezeichner" beziehen, sodass die Taste "W" und die Pfeiltaste nach oben intern als "Hoch" gehandhabt werden, als auch auf die Werte/Wertebereiche, sodass bspw. 2 Tasten zu einer internen "Achse" übersetzt werden, wie es bspw. von Unity gemacht wird.)
Der InputManager darf ansonsten nur die (übersetzten) Eingaben über direktes Abrufen oder über Callbacks liefern.
Die Objekte (bspw. der Charakter des Spielers oder das UI), die die Eingaben benötigen, sind evtl. nicht zu jedem Zeitpunkt aktiv (das Menü wurde geöffnet -> der Charakter soll sich nicht mehr bewegen).

Ruft ein entsprechendes Objekt die Eingaben selbst ab, müsste es auch selbst entscheiden können, ob es gerade aktiv ist und die Eingaben abrufen und verwenden darf. Entweder muss es die Stelle kennen, die dies entscheiden kann, oder es muss bei Änderungen der Aktivität immer informiert werden. Ggf. wird der entsprechende Code nicht aufgerufen, wenn das Objekt nicht aktiv ist (siehe Unity und die Update-Methode).
Erhält das Objekt direkt entsprechende Events gilt das Gleiche wie bei einem direkten Abrufen, nur dass in jeden Fall eine Prüfung durchgeführt werden _muss_.

Beim indirekten Abrufen verhält es sich fast genauso wie beim direkten Abrufen, nur dass die weiterleitende Stelle (das Spiel, der GameState, die Spielwelt, ...) mitgeteilt bekommen könnte, welches Objekt sich gerade über Eingaben informieren möchte und ggf. andere Werte zurückliefern. Abhängig von der Implementierung kann es durchaus notwendig sein, dass nicht der Standardwert des jeweiligen Inputs (i. d. R. 0) zurückliefert, sondern den letzten, bevor der Zustand des Inputs sich verändert hat. Wenn ein Spieler seinen Schuss auflädt, versehentlich das Pausenmenü öffnet, es wieder schließt und zwischenzeitlich die Schusstaste nicht losgelassen hat, will er nicht, dass sich der Schuss bereits löst.
Bei indirekten Callbacks verhält es sich ähnlich wie im oberen Fall, nur dass nicht jedes Mal das Objekt sich selbst weiterreichen muss. Hier besteht aber das Problem, dass die weiterleitende Stelle sich merken muss, über welchen Zustandswechsel (Menüaufruf) zuletzt informiert wurde, damit beim nächsten Zustandswechsel (fortsetzen des Spiels) über Änderungen informiert werden kann, die in der Zwischenzeit passiert sind. Das versehentliche öffnen und sofortige Schließen des Menüs ist kein Problem, wird die Taste danach aber nicht mehr gedrückt, muss darüber informiert werden, sobald das Menü geschlossen wird.
Wenn die Callbacks weitergeleitet werden, gibt es weiterhin den Vorteil, dass das jeweilige Objekt nicht aktiv die Callbacks einem anderen übergeben muss, sondern bspw. über eine definierte Schnittstelle die abgehorchten Inputs und zugehörigen Callbacks zur Verfügung stellen kann, die von der weiterleitenden Instanz ausgewertet werden können.

(Vielleicht gibt es auch noch andere Herangehensweisen für das Weiterleiten/Abrufen des Inputs, die mir gerade nicht eingefallen sind...)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Strike

Frischling

Beiträge: 36

Wohnort: Wien 1200 und Techelsberg 9212

Beruf: Junior Software-Entwickler & Software Testing

  • Private Nachricht senden

10

20.03.2014, 11:13

Zitat

Um Gottes Willen Nein. Wenn etwas nur einmal vorkommen darf. Von sollen ist bei einem korrekten singleton nicht die Rede.
Bitte vielmals um Entschuldigung, du hast natürlich recht. ^^ Für einen gewissenhaften Programmierer ist das aber das selbe. :crazy:
Aber unter normalen Umständen stimmt dein Argument. Die Wortklauberei errinert mich an meinen Programmierlehrer xD
Irgendwie vermiss ich ihn :(

Werbeanzeige