@Patsche: Du sagst genau das machst Du und zeigst dann Code in dem Du genau das *nicht* machst.
Da gibt es `spielfigur_1_x`, `spielfigur_1_y`, `schlaegerbreite_spieler1`, und `schlaegerhoehe_spieler1` und das ganze noch mal für Spieler 2, statt jeweils nur 1 `Rect` mit den ganzen Informationen pro Spieler.
Durch die vielen Variablen bleibt nichts flexibel. Was wird denn unflexibel wenn man die sinnvoll zusammenfasst? Es wird übersichtlicher. Und verständlicher wenn man nicht mit Einzelwerten rechnet, wo man sich erst klar machen muss welchen Punkt an oder in einem Rechteck man da letztlich anspricht. Die Zusammenhänge muss man sich ja im Moment aus den Zahlen zusammenreimen. Übrigens auch ein Punkt: Vermeiden von ”magischen” Zahlen die dann auch noch voneinander abhängen. Die 50 ist ja 50 weil es die Hälfte von 100 ist, die wiederum die Schlägerhöhe. Dann sollte da aber nicht 50 stehen, sondern Schlägerhöhe durch zwei. Das ist verständlicher, und wenn man mal die Schlägerhöhe ändert, muss man nicht von Hand daraus abegleitete Zahlen ändern.
Aus:
Code: Alles auswählen
spielfigur_1_farbe = BLAU
spielfigur_1_x = 20
spielfigur_1_y = aufloesung.current_h / 2 - 50
spielfigur_1_bewegung = 0
schlaegerbreite_spieler1 = 20
schlaegerhoehe_spieler1 = 100
punktespieler1 = 0
leben = 3
spielfigur_2_farbe = LILA
spielfigur_2_x = aufloesung.current_w - 40
spielfigur_2_y = aufloesung.current_h / 2 - 50
spielfigur_2_bewegung = 0
schlaegerbreite_spieler2 = 20
schlaegerhoehe_spieler2 = aufloesung.current_w
punktespieler2 = 0
Wird dann:
Code: Alles auswählen
spielfigur_1_farbe = BLAU
spielfigur_1_rect = pygame.Rect(0, 0, SCHLAEGERBREITE, SCHLAEGERHOEHE)
spielfigur_1_rect.midleft = SCHLAEGERBREITE, screen_rect.centery
spielfigur_1_bewegung = 0
punktespieler1 = 0
leben = 3
spielfigur_2_farbe = LILA
spielfigur_2_rect = pygame.Rect(0, 0, SCHLAEGERBREITE, SCHLAEGERHOEHE)
spielfigur_1_rect.midright = (
screen_rect.right - SCHLAEGERBREITE,
screen_rect.centery,
)
spielfigur_2_bewegung = 0
punktespieler2 = 0
Keine ”magischen” Zahlen mehr. Und die `Rect`-Objekte kann man dann im weiteren für die Position, für's Zeichnen, und für Kollisionstests verwenden. Mit dem Ball kann man das gleiche machen und dort auch die Bewegungskomponenten zu einem `pygame.Vector2`-Objekt zusammenfassen. Dann sieht das so aus:
Code: Alles auswählen
#!/usr/bin/env python3
import random
import pygame
ROT = (255, 0, 0)
LILA = (200, 80, 200)
BLAU = (80, 80, 200)
SCHLAEGERBREITE, SCHLAEGERHOEHE = 20, 100
BALL_DURCHMESSER = 40
def main():
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
screen_rect = screen.get_rect()
spielfigur_1_farbe = BLAU
spielfigur_1_rect = pygame.Rect(0, 0, SCHLAEGERBREITE, SCHLAEGERHOEHE)
spielfigur_1_rect.midleft = SCHLAEGERBREITE, screen_rect.centery
spielfigur_1_bewegung = 0
punktespieler1 = 0
spielfigur_2_farbe = LILA
spielfigur_2_rect = pygame.Rect(0, 0, SCHLAEGERBREITE, SCHLAEGERHOEHE)
spielfigur_2_rect.midright = (
screen_rect.right - SCHLAEGERBREITE,
screen_rect.centery,
)
spielfigur_2_bewegung = 0
punktespieler2 = 0
ball_farbe = ROT
abstand = BALL_DURCHMESSER + 10
ball_rect = pygame.Rect(
abstand,
random.randint(abstand, screen_rect.width - abstand),
BALL_DURCHMESSER,
BALL_DURCHMESSER,
)
ball_bewegung = pygame.Vector2(5, 5)
mehrspieler = False
leben = 3
ballwechsel = 0
pygame.draw.rect(screen, spielfigur_1_farbe, spielfigur_1_rect)
pygame.draw.rect(screen, spielfigur_2_farbe, spielfigur_2_rect)
pygame.draw.ellipse(screen, ball_farbe, ball_rect)
...
if spielfigur_1_rect.colliderect(ball_rect):
print("Zusammenstoß P1")
ball_bewegung.x = -ball_bewegung.x
ball_rect.left = spielfigur_1_rect.right
ballwechsel += 1
if pygame.joystick.get_count() == 1:
joystick_0.rumble(0, 1, 200)
if spielfigur_2_rect.colliderect(ball_rect):
print("Zusammenstoß P2")
ball_bewegung.x = -ball_bewegung.x
ball_rect.right = spielfigur_2_rect.left
ballwechsel += 1
if pygame.joystick.get_count() >= 1:
joystick_1.rumble(0, 1, 200)
Immer noch zu viele einzelne Variablen. Zeit die Spieler und den Ball mindestens von den Daten in jeweils einer Klasse zusammenzufassen:
Code: Alles auswählen
#!/usr/bin/env python3
import random
import pygame
ROT = (255, 0, 0)
LILA = (200, 80, 200)
BLAU = (80, 80, 200)
SCHLAEGERBREITE, SCHLAEGERHOEHE = 20, 100
BALL_DURCHMESSER = 40
class Spieler:
def __init__(self, farbe):
self.farbe = farbe
self.rect = pygame.Rect(0, 0, SCHLAEGERBREITE, SCHLAEGERHOEHE)
self.bewegung = 0
self.punkte = 0
class Ball:
def __init__(self, farbe, rect):
self.farbe = farbe
self.rect = rect
self.bewegung = pygame.Vector2(5, 5)
def main():
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
screen_rect = screen.get_rect()
spieler_a = Spieler(BLAU)
spieler_a.rect.midleft = SCHLAEGERBREITE, screen_rect.centery
spieler_b = Spieler(LILA)
spieler_b.rect.midright = (
screen_rect.right - SCHLAEGERBREITE,
screen_rect.centery,
)
abstand = BALL_DURCHMESSER + 10
ball = Ball(
ROT,
pygame.Rect(
abstand,
random.randint(abstand, screen_rect.width - abstand),
BALL_DURCHMESSER,
BALL_DURCHMESSER,
),
)
mehrspieler = False
leben = 3
ballwechsel = 0
pygame.draw.rect(screen, spieler_a.farbe, spieler_a.rect)
pygame.draw.rect(screen, spieler_b.farbe, spieler_b.rect)
pygame.draw.ellipse(screen, ball.farbe, ball.rect)
...
if spieler_a.rect.colliderect(ball.rect):
print("Zusammenstoß P1")
ball.bewegung.x = -ball.bewegung.x
ball.rect.left = spieler_a.rect.right
ballwechsel += 1
if pygame.joystick.get_count() == 1:
joystick_0.rumble(0, 1, 200)
if spieler_b.rect.colliderect(ball.rect):
print("Zusammenstoß P2")
ball.bewegung.x = -ball.bewegung.x
ball.rect.right = spieler_b.rect.left
ballwechsel += 1
if pygame.joystick.get_count() >= 1:
joystick_1.rumble(0, 1, 200)
Eine offensichtliche Methode die man bei beiden Klassen jetzt hinzufügen könnte, wäre das sie sich selbst auf ein `Surface` malen können:
Code: Alles auswählen
class Spieler:
def __init__(self, farbe):
self.farbe = farbe
self.rect = pygame.Rect(0, 0, SCHLAEGERBREITE, SCHLAEGERHOEHE)
self.bewegung = 0
self.punkte = 0
def draw(self, screen):
pygame.draw.rect(screen, self.farbe, self.rect)
class Ball:
def __init__(self, farbe, rect):
self.farbe = farbe
self.rect = rect
self.bewegung = pygame.Vector2(5, 5)
def draw(self, screen):
pygame.draw.ellipse(screen, self.farbe, self.rect)
...
spieler_a.draw(screen)
spieler_b.draw(screen)
ball.draw(screen)