Du bist nicht angemeldet.

Werbeanzeige

1

01.07.2014, 09:26

C# Event's und Delegaten. Screen Manager Problem.

Guten Morgen,

ich komme leider nicht weiter wenn es um Delegaten und Events geht auch wenn ich schon etliche Tutorials angeguckt habe.

Ich habe es eben geschafft mit einem Event meine Exit Methode auszuführen aber irgendwie fühlt sich mein Aufbau falsch an.

In dieser Klasse habe ich das Event deklariert und die Methode von OnExit von ScreenManager abonniert.

Dann habe ich in der Update Methode das Event aufgerufen und es hat auch geklappt.

Aber wieso brauche ich Event's? ich könnte auch einfach screenManager.OnExit() aufrufen bzw. würde schon ein Delegate reichen.

Was übersehe ich?


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;

namespace TeamPlatformer
{
    public delegate void ScreenChangeEventHandler();

    public class TeamPlatformer : Game
    {
        public event ScreenChangeEventHandler ExitHandler;

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        ScreenManager screenManager;

        public TeamPlatformer()
            : base()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            screenManager = new ScreenManager(this);
            ExitHandler += screenManager.onExit;

            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        protected override void UnloadContent()
        {

        }

        protected override void Update(GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                ExitHandler();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            base.Draw(gameTime);
        }
    }
}


C#-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace TeamPlatformer
{

    class ScreenManager : DrawableGameComponent
    {
        public ScreenManager(Game game): base(game)
        {
        }

        protected override void LoadContent()
        {
            base.LoadContent();
        }

        protected override void UnloadContent()
        {
            base.UnloadContent();
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);
        }

        public void onExit()
        {
            Game.Exit();
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
        }
    }
}

Sacaldur

Community-Fossil

Beiträge: 2 332

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

2

01.07.2014, 09:38

In deinem Fall scheint das Event-Handling unnötig zu sein (und auch mit Delegates muss man da gar nichts anfangen). Du prüfst im Spiel, ob die Taste zum Beenden gedrückt wurde, löst ggf. das Event aus und der ScreenManager beendet dann das Spiel, statt das das Spiel es selbst erledigt.
Außerdem sollten (wenn möglich) Objekte sich selbst für Events registrieren, in deinem Fall macht es aber die erzeugende Stelle.

In dem Fall wäre es besser, wenn das Spiel im Fall der Fälle (das Spiel wird beendet) die entsprechende Methode des Screenmanagers aufruft und sich dann selbst beendet. Der Screenmanager könnte dan noch Dinge machen, bevor das Spiel tatsächlich beendet wird.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

TrommlBomml

Community-Fossil

Beiträge: 2 143

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

3

01.07.2014, 11:59

Letztendlich sind Events nichts anderes als Funktionsaufrufe durch denjenigen, der das Event bereitstellt. Im Prinzip kannst du dir merken, dass Events und Listener optional sind und nicht zwingend notwendig sind, sich anzumelden. Außerdem kann sich auf einem Event immer mehrere Anmelden.
Wenn du nur einen Listener hast, der auf ein Event reagieren soll, dann ist ein direkter Funktionsaufruf auf ein referenziertes Objekt besser an statt Events zu verwenden. Beim Screenwechsel hast du ja genau genommen immer nur ein aktives Objekt, nämlich den aktiven Screen: Der aktive Screen wird verlassen und ein neuer wird betreten.
Ich verwende Events gegen 0 in meinem Spielecode, weil es einfach zu wenig Anwendungsfälle gibt.

BlueCobold

Community-Fossil

Beiträge: 10 890

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

01.07.2014, 13:02

Ich finde es gibt sogar sehr viele Anwendungsfälle für Events bei Spielen:
- reagiere auf UI-Controls
- reagiere auf Keyboard-Input
- reagiere auf Physik-Events (Kollisionen z.B.)
- reagiere auf Timer
- ...
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

5

01.07.2014, 13:42

Man darf beim Eventsystem nie aus den Augen verlieren was das Ziel ist.
Im Prinzip will man Methodenaufrufe in Events kapseln aber gleichzeitig auch abstrahieren. Also es macht wenig Sinn ein Eventsystem auf das bereits vorhandene zu bauen ohne zu abstrahieren. (Z.B rohe Tastatur-eingaben in ein Event zu packen, dass das Framework ehh schon macht wenig Sinn, aber eine konkrete Aktion in ein Event zu kapseln, indem bei durch die Tastatureingabe ein entsprechendes Event generiert, macht Sinn)
Und ganz wichtig ist die Möglichkeit Events zu filtern, je nach Spielzustand. So kann man die Logik auf den Eventhandler/delegator konzentrieren und muss nicht an 100 Stellen im Code die Logik zusammenschustern.

Ein Eventsystem ist vor allem dann sinnvoll, wenn das Projekt ne gewisse Komplexität besitzt. Es macht das Projekt flexibler und besser Steuerbar und vereinfacht das Debugging.
Neben dem was BC an Eventtypen genannt hat hab ich meist noch solches Sachen: (Bezogen auf ein Point & Click Adventure.)


Movement
Dialogsteuerung
Screensteuerung
NPC Aktionen

Was nicht darein gehört sind performancekritische Dinge, wie Phyiskberechnung, Rendering, AI etc.

Zitat von »Chad Fowlder«

Leider hat die Software-Branche viele flache Spezialisten hervorgebracht, die die Bezeichnung Spezialist nur als Entschuldigung dafür verwenden, nur eine Sache zu kennen.

BlueCobold

Community-Fossil

Beiträge: 10 890

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

01.07.2014, 13:45

Was ich auch schon hatte war, dass die KI und das Pathfinding Events auslösen, wenn:
- Monster/Spieler in Sichtweite kommt
- Monster/Spieler einen Wegpunkt erreichen
- Ein Weg spontan blockiert wird
- Monster/Spieler stirbt
- Monster/Spieler Schaden nimmt
- Monster/Spieler spawnt
- Monster/Spieler gewisse Skills oder Items einsetzt
- ...

Das ließ sich dann prima mit dem Scripting für Quests zusammen nutzen, indem man sehr unterschiedliche Aktionen für KI-gesteuerte Gegner erstellen konnte, einfach nur basierend auf den Aktionen von Spielern oder anderen (oder sogar denselben) NPCs. Für solche Sachen ist Polling eine totale Katastrophe und Events absolut perfekt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

7

01.07.2014, 13:56

Was man noch erwähnen sollte ist, dass Events tendenziell gut sind um Eventbearbeitung zu einem späteren Zeitpunkt parallelisierbar zu machen.
In Spielen vllt. erstmal weniger interessant, in der Serverprogrammierung aber dann wieder.

Zitat von »Chad Fowlder«

Leider hat die Software-Branche viele flache Spezialisten hervorgebracht, die die Bezeichnung Spezialist nur als Entschuldigung dafür verwenden, nur eine Sache zu kennen.

TrommlBomml

Community-Fossil

Beiträge: 2 143

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

8

01.07.2014, 14:14

Ich finde es gibt sogar sehr viele Anwendungsfälle für Events bei Spielen:
- reagiere auf UI-Controls
- reagiere auf Keyboard-Input
- reagiere auf Physik-Events (Kollisionen z.B.)
- reagiere auf Timer


Input würde ich bis heute lieber Zustandsabfragen lösen, glaube da bin ich etwas Rückständig :P. Für Timer habe ich auch immer nur eine Action als Parameter im Konstruktor verwendet, weil sich meistens eh nur eine Instanz dafür interessiert hat. Physik mache ich kaum, daher hab ich keine Erfahrung. Selbst auf UI-Control-Events wie Click reagiert doch meist eh nur ein Listener.
Oder Sagen wir mal so: Bei mir ist bisher der nutzen von Events nicht wirklich wichtig gewesen, Action/Func reicht.

Sacaldur

Community-Fossil

Beiträge: 2 332

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

9

01.07.2014, 14:56

An der Stelle sollte man zwischen dem allgemeinen Mechanismus der Events und der konkreten Umsetzungsmöglichkeit in C# unterscheiden.
Du verwendest in dem Fall Events, die aber auf einen einzigen Callback beschränkt sind. Es sind aber immernoch Events.

Und nochmal allgemein zusammengefasst:
Events werden zu bestimmten Zeitpunkten ausgelöst und haben das Ausführen einer beliebigen Anzahl von Callbacks zur Folge. Wie bereits geschrieben hat das genau den Hintergrund, dass dadurch an anderen Stellen das Polling (ständige Abfragen auf Zustandsänderungen) eingespart wird.

Bzgl. Input hat sich in einem anderen Thread bereits ergeben, dass Man beim Input abhängig von der jeweiligen Situation arbeiten sollte. Hat man etwas, was diskrete Zustände aufweist und somit auch eine abzählbare Menge möglicher Events (Tasten und Buttons), sind Events häufig besser geeignet, hat man aber einen sich potenziell permanent verändernden Input (Analog-Stick), wäre ein Polling besser geeignet. Man muss auch bedenken, dass man sehr wahrscheinlich eine Abstraktionsebene bei der Input-Verarbeitung hat, welche auch aus 2 Tasten (A und D oder W und S) ein anderes Ergebnis errechnen kann (2 Achsen, ggf. mit Interpolation).
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

BlueCobold

Community-Fossil

Beiträge: 10 890

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

01.07.2014, 15:16

Selbst auf UI-Control-Events wie Click reagiert doch meist eh nur ein Listener.
Ändert nichts daran, dass es Events sind. In den meisten Anwendungsfällen gibt es tatsächlich nur einen einzigen Interessenten an einem Event.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige