[Pygame] Objektorientierte Steuerung von 2 Klassen gleichzeitig

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Benutzeravatar
Patsche
User
Beiträge: 43
Registriert: Samstag 23. Oktober 2021, 00:17

__blackjack__ hat geschrieben: Samstag 22. Juli 2023, 22:47 aber in dem 4 Spieler und 4 Äpfel Szenario hat man keine 8 Namen und schreibt man keine 16 Kollisionstest, sondern hat eine Liste mit Spielern und eine Liste mit Äpfeln und zwei Schleifen die dann alle Äpfel gegen alle Spieler testet.
So?

Code: Alles auswählen

coins = [Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20)),
        Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20)),
        Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20)),
        Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20)),
        Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20)),
        Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20)),
        Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20))]
Und in der Schleife dann:

Code: Alles auswählen

  for coin in coins:
     coin.update(window)

Code: Alles auswählen

for coin in coins:
    if player.rect.colliderect(coin.rect):
        print("GESAMMELT")
Dürfte man das auch zusammenlegen? Also so?

Code: Alles auswählen

for coin in coins:
    coin.update(window)
    if player.rect.colliderect(coin.rect):
        print("GESAMMELT")
Oder noch mehr:

Code: Alles auswählen

for coin in coins:
    coin.update(window)
    if player.rect.colliderect(coin.rect):
        print("GESAMMELT")
        coin.collected = True
        if coin.collected:
            coins.remove(coin)
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Das erzeugen eher so:

Code: Alles auswählen

  coins = [
      Coin(pygame.Rect(random.randint(20, 700), random.randint(20, 500), 20, 20))
      for _ in range(7)
  ]
Ob man solche Schleifen zusammenlegen kann, kommt ein bisschen darauf an was `update()` konkret bedeutet und ob das dann logisch einen Unterschied machen kann wenn man erst alle aktualisiert und danach auf Kollisionen prüft, oder ob man bei jedem einzelnen Objekt aktualisiert und gleich auf Kollision prüft. Hier dürfte das keinen Unterschied machen.

Der Punkt auf den man hier im konkreten Beispiel beachten muss, ist die Situation wenn zwei Spieler gleichzeitig mit der gleichen Münze kollidieren. Oder das man sicherstellt, dass das nicht passieren kann, zum Beispiel falls Spielerkollisionen die Spieler ”killen”, dann muss man *das* einfach vor dem Kollisionstest mit den Münzen machen und dort kollidierte Spieler aus dem Spiel nehmen.

Man könnte sich hier übrigens auch an `pygame.sprite` orientieren. Das bietet die Möglichkeit Spielobjekte zu Gruppen zusammenzufassen und auch schon Funktionen um Kollisionen zwischen einzelnen Sprites mit einer Gruppe oder zwei Gruppen von Sprites zu ermitteln.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ah, da war noch ein Beitrag auf der Seite davor. Hätte ich fast übersehen. 😱

Erst der einfachste Teil: Das Bild gehört mit in die Spieler (oder Münze) Klasse. Das ist ja wie die Position etwas was sehr eng zu dem durch die Klasse beschriebenen Objekt gehört. `pygame.sprite.Sprite` hat auch `image` und `rect` als Attribute.

Die Steuerung gehört sowohl in den Spieler als auch in das Spiel. Im Spiel wird die Ereigniswarteschlange abgearbeitet, und das reagiert ja auf Ereignisse wie „Benutzer hat das x in der Fensterleiste zum beenden geklickt“, und die Spieler müssen irgendwie über ihre Tasten informiert werden. Da kann man alles mögliche machen. Vom auffangen der Ereignisse in einer Liste und die dann an die Spielerobjekte weitergeben, damit die dann auch noch mal in einer Schleife darüber gehen können um die auszuwerten. Dann muss die Hauptschleife gar nichts über die Objekte wissen. Oder die Hauptschleife weiss alles über die Objekte und worauf sie wie reagieren müssen und macht das alles. Letzteres wäre aus OOP-Sicht nicht gut. Und dann gibt es noch was dazwischen. Das die Hauptschleife beispielsweise die Tastenzuordnung zwischen Taste und Spieler/Bewegungsrichtung kennt, und die entsprechenden Spielerobjekte darüber informiert in welche Richtung sie sich bewegen sollen, diese Umsetzung der Bewegung dann aber im Objekt stattfindet. Dann muss die Hauptschleife beispielsweise nichts über die Position oder Geschwindigkeit wissen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten