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

1

06.02.2008, 22:04

Eventverarbeitung: So wie's im Buch steht oder anders

Sorry dass ich schon wieder frag :)

Diesmal ist es allerdings eher eine Designfrage

Das Spiel lässt sich jetzt auch mit Joystick steuern, wobei ich hier ein Designproblem sehe.

Die Beispielanwendung nutzt die Eventqueue (ProcessEvents in Game) nur um auf Escape oder SDL_QUIT zu lauschen. Die Bewegung und das Schießen wird ja jeweils durch die Player::Update() aufgerufen und es sind eigene Funktionen (ProcessMoving, ProcessShooting).

In der Doku zur SDL steht jetzt aber, dass für Joystickereignisse die Eventqueue benutzt werden sollte (ich hatte es bisher ienfach über Methodenaufrufe (z.B. SDL_JoystickGetButton(m_Joystick.GetSDL_Joystick(), 0)) gelöst.

Die Eventqueue behandelt nun eigentlich die Hauptschleife des Programms und meines Erachtens ist es sinnvoller die Bewegung und das Schießen auch nur dann aufzurufen wenn ein entsprechendes Ereignis eingetroffen ist. Dafür müsste der Code aber ungefaähr so abgeändert werden

C-/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
/ ProcessEvents
//

// Aufgabe: Events bearbeiten

//

void CGame::ProcessEvents ()
{
  SDL_Event Event;

  // Gab es ein Event?

  if (SDL_PollEvent (&Event))
  {
    // Ja, also schauen welches

    switch (Event.type)
    {
      // Beenden?

      case (SDL_QUIT):
      {
        m_bGameRun = false;
      } break;
      // Wurde eine Taste gedrückt?

      case (SDL_KEYDOWN):
      {
          switch (Event.key.keysym.sym)
          {
            case (SDLK_ESCAPE):
            {
                // Ja, also Spiel beenden

                m_bGameRun = false;
            } break;
          }
      } break; // SDL_KEYDOWN

      case SDL_JOYAXISMOTION: 
      {
          if ( ( Event.jaxis.value < -3200 ) || (Event.jaxis.value > 3200 ) ) 
          {
              if( Event.jaxis.axis == 0) 
              {
                  cout << "links rechts" << endl;
                  m_pPlayer->MoveX(Event.jaxis.value) // <-------------- Hier

              }

              if( Event.jaxis.axis == 1) 
              {
                  cout << "hoch runter" << endl;
                  m_pPlayer->MoveY(Event.jaxis.value)  // <-------------- Hier

              }
          }
      }break; // SDL_JOYAXISMOTION

      case SDL_JOYBUTTONDOWN: 
      {
          if ( event.jbutton.button == 0 ) 
          {
              m_pPlayer->Shoot()  // <--------------------------- Hier

          }
      }break;
    }
  }

} // ProcessEvents

Die Eventqueue löst also die Aktionen aus.

Ist dieses Vorgehen sinnvoll (im Sinne sauberer Programmierung)?
Ich komme ja eigentlich aus dem Java-Lager und da gibts halt andere Möglichkeiten.

Bin natürlich auch für andere Vorschläge (Patterns o.ä.) offen.

Danke

2

06.02.2008, 22:38

Hmmmm

Ich habs grad mal teshalber ungefähr so umgebaut. Es funktioniert alles und die Aufrufe sind einfach, allerdings stocken die Animationen. Halte ich den Joystick z.B. an einer Stelle, so bleibt auch die Animation stehen. Eine minimale Bewegung und es tut sich wieder was

EDIT: Mist! Bewege ich den Joystick schnell hin und her für eine Weile und stoppe dann, so "schwingt" das Schiff noch nach

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

3

06.02.2008, 22:43

Also das deine Animation anhält, könnte auch daran liegen, dass du die nur animierst, wenn du den Yoystick bewegst.
Eventuell solltest du eine noch etwas einbauen, dass die Animation in eine "Grundstellung" geht, wenn du nichts machst.

4

06.02.2008, 23:09

Die ist ja eigentlich schon drin. Der Joystick hat eine Deadzone und wenn der Knüppel sich dazwischen befindet wird die Animation zurück zur Ausgangsposition durchgeführt.

So wie es ausschaut, wird die Eventqueue unterschiedlich aktualisiert und es wird keine Event mehr ausgelöst wenn der Knüppel still steht (z.B ganz Links).

Schade, muss ich es wohl doch über direkte Methodenaufrufe machen, was den COde aber unleserlicher macht, weil ich überall noch abprüfen muss ob ein Joystick überhaupt initialisiert (angeschlossen) wurde. So wie es jetzt ist, ist das halt nicht nötig (deswegen auch die Idee dazu)

5

13.02.2008, 13:22

Niemand ein Idee, oder eine Best-Practise zur Hand?

Ich hab inzwischen wieder auf ProcessMoving und ProcessShooting in Player umgestellt, aber so ganz zufrieden bin ich damit nicht.

Beneroth

Alter Hase

Beiträge: 969

Wohnort: Schweiz

Beruf: Software Entwickler

  • Private Nachricht senden

6

14.02.2008, 09:33

Wenn du ProcessMoving und ProcessShooting benutzt stottern die Animationen nicht?
Das Problem sollte ja generel da sein, der Unterschied ist nur in der Eventabfrage, oder?


@Eventhandling: Ich habe bei mir eine Klasse Eventhandler und EventListener erstellt. EventListener-Objekte können sich beim Eventhandler registrieren, dieser hat für jeden benötigten Event eine Liste und geht diese beim Auftreten des Events durch und ruft auf jedem Listener eine Funktion auf.
Ich glaube dass ist schön OOP, allerdings wirds so schon ein bisschen komplexer und man sollte einiges sich überlegen und berücksichtigen beim Design. Dafür ist die Verwendung später einfacher.

@Animationen / Rendering:
Du sollst nicht nur rendern wenn ein Event ausgelöst worden ist, sondern immer. Mach dir ne Animationsklasse oder sowas, die selber das zeitbasierend das Bild ändert wenn nötig. Wenn Du willst kannst du dazu auch einen RenderHandler-System schreiben, ähnlich wie beim EventHandler einfach nur fürs Rendering.

In jedem Frame verarbeitest du dann zuerst alle Events und führst darauf basierende Änderungen durch. Dann renderest du alles (bzw. alles was sich vom Rendering her ändert!)

Hoffe konnte Dir so einen Tipp geben ;)

7

14.02.2008, 10:21

Danke, das hilft schon mal. Listener kenn ich aus Java.

Ich hatte nur gedacht dass diese SDL-Eventbehandlung schon etwas in der Richtung ist.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

8

15.02.2008, 13:21

Ich habe mir mal ein anderes Konzept "ausgedacht".
Ich weiss nicht, ob es wirklich was taugt, aber in der Theorie scheint es ganz nett zu sein. ;)

Ich werde es mal so ausprobieren,dass jedes Objekt selber schaut, welche Events (vor allem Eingaben) gemacht wurden und dann sich so verhält, wie man es sich wünscht.
Dann kann man einfach umschalten, welches "Fokus" hat und dann reagieren alle dijeningen, die "Fokus" haben. Diesen Ansatz habe ich mir vor allem für ein GUI-System überlegt. Da so die einzelnen Elemente recht einfach verschoben werden können.
Aber eben, habe es noch nicht ausprobiert und weiss daher nicht, ob es wirklich in der Praxis was taugt. ;)

Werbeanzeige