Seite 1 von 1

Hilfe beim Code

Verfasst: Samstag 9. Januar 2021, 00:30
von JonBach18
Hallo Leute,

ich habe folgendes Problem das nach dem ich den Programm abspielen lasse, kann ich das Spiel ohne Einschränkungen Spielen, aber es zeigt trotzdem an das es ein Fehler gibt. Weiß leider aber nicht wie man es löst. Ich hoffe Ihr könnt mir helfen wie immer :)
Des weitern wollte ich mal nach fragen was Ihr von dem Code denkt und sogar Verbesserungsvorschläge habt. Es geht um das Spiel "Pong"

Danke im Voraus für eure Hilfe! Bedeutet mir echt sehr viel!

Mit freundlichen Grüßen,
Jon

Code: Alles auswählen

# Importieren einer Bibiothek
import pygame
from pygame.locals import *

# Pygame initialisieren
pygame.init()
# Uhr erstellen // weil sonst der Computer es so schnell wie möglich versucht abzuspielen "Bildfrequenz-Limit"
Clock = pygame.time.Clock()
# Bilschirm Größe
screen_width = 1000
screen_height = 500

# Bilschirm ertsllen mit Überschrift
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Pong von Ramon')

# Farbe definieren
bg = pygame.Color("#458B74")
black = (0, 0, 0)
white = (255, 255, 255)
blue = (255, 255, 255)
orange = (255, 140, 0)

# Soounds
plob_sound = pygame.mixer.Sound("pong.ogg")
score_sound = pygame.mixer.Sound("score.ogg")

# define game variables
margin = 50

# define font
basic_font = pygame.font.SysFont("freesansbold.ttf", 60)


# basic_font = pygame.font.SysFont("Helvetica", 60)


# Text erstllen und den text umwandeln in ein Bild und dieses auf das Spielbildschirm bringen
# dafür muss ich eine font (Schriftart) erstellen
def draw_text(text, basic_font, text_col, x, y):
    img = basic_font.render(text, True, text_col)
    screen.blit(img, (x, y))


def draw_board():
    screen.fill(bg)
    pygame.draw.line(screen, white, (0, margin), (screen_width, margin), 4)
    pygame.draw.line(screen, white, (500, margin), (500, 500), 4)
    # Kreis in der Mitte
    pygame.draw.ellipse(screen, white, [400, 180, 200, 200], 4)


# Man kann nicht direkt einen Text schreiben, mann muss es den text in ein Bild konvertieren und diesen mit screen.blit
# auf das "Screen" tun / x und y steht für wo der "Text" am Ende wo es sein soll // font muss noch bestimmt werden //
# text ist der text den man sehen möchte
def draw_text(text, basic_font, text_col, x, y):
    img = basic_font.render(text, True, text_col)
    screen.blit(img, (x, y))


class paddle():
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.rect = Rect(x, y, 10, 150)
        self.speed = 5
        self.ai_speed = 5

    # damit man den Paddle bewegen kann muss man die Tastatur mit einbinden wenn man eine Tast gefrückt hat und wie der Paddle
    # sich zu verhalten hat
    def move(self):
        key = pygame.key.get_pressed()
        # Wenn der UP-Key gedrückt wurde und "Grenzen" einrichten (solange der "Top" größer als margin ist kann man nach oben gehen
        # also unter dem Rand ist
        if key[pygame.K_UP] and self.rect.top > margin:
            self.rect.move_ip(0, -1 * self.speed)
        if key[pygame.K_DOWN] and self.rect.bottom < screen_height:
            self.rect.move_ip(0, self.speed)

    def draw(self):
        pygame.draw.rect(screen, white, self.rect)

    def ai(self):
        # ai to move the paddle automatically
        # move down
        if self.rect.centery < pong.rect.top and self.rect.bottom < screen_height:
            self.rect.move_ip(0, self.ai_speed)
        # move up
        if self.rect.centery > pong.rect.bottom and self.rect.top > margin:
            self.rect.move_ip(0, -1 * self.ai_speed)


class ball():

    def __init__(self, x, y):
        self.reset(x, y)

    def move(self):

        # check collision with top margin
        if self.rect.top < margin:
            pygame.mixer.Sound.play(plob_sound)
            self.speed_y *= -1
        # check collision with bottom of the screen
        if self.rect.bottom > screen_height:
            pygame.mixer.Sound.play(plob_sound)
            self.speed_y *= -1
        if self.rect.colliderect(player_paddle) or self.rect.colliderect(cpu_paddle):
            pygame.mixer.Sound.play(plob_sound)
            self.speed_x *= -1

        # check for out of bounds
        if self.rect.left < 0:
            pygame.mixer.Sound.play(score_sound)
            self.winner = 1
        if self.rect.left > screen_width:
            pygame.mixer.Sound.play(score_sound)
            self.winner = -1

        # update ball position
        self.rect.x += self.speed_x
        self.rect.y += self.speed_y

        return self.winner

    def draw(self):
        pygame.draw.circle(screen, orange, (self.rect.x + self.ball_rad, self.rect.y + self.ball_rad), self.ball_rad)

    def reset(self, x, y):
        self.x = x
        self.y = y
        self.ball_rad = 8
        self.rect = Rect(x, y, self.ball_rad * 2, self.ball_rad * 2)
        self.speed_x = -4
        self.speed_y = 4
        self.winner = 0  # 1 is the player and -1 is the CPU


# create paddles
player_paddle = paddle(screen_width - 40, screen_height // 2)
cpu_paddle = paddle(20, screen_height // 2)

# create pong ball
pong = ball(screen_width - 60, screen_height // 2 + 50)


def game_to_five():
    player_score = 0
    opp_score = 0

    live_ball = False
    winner = 0
    speed_increase = 0

    run = True
    while (player_score < 5 and opp_score < 5) and run:

        Clock.tick(60)

        draw_board()
        draw_text('OPP: ' + str(opp_score), basic_font, white, 20, 15)
        draw_text('P1: ' + str(player_score), basic_font, white, screen_width - 115, 15)
        draw_text('TEMPO: ' + str(abs(pong.speed_x)), basic_font, white, screen_width // 2 - 100, 15)

        # draw paddles
        player_paddle.draw()
        cpu_paddle.draw()

        if live_ball == True:
            speed_increase += 1
            winner = pong.move()
            if winner == 0:
                # draw ball
                pong.draw()
                # move paddles
                player_paddle.move()
                cpu_paddle.ai()
            else:
                live_ball = False
                if winner == 1:
                    player_score += 1
                elif winner == -1:
                    opp_score += 1

        # print player instructions
        if live_ball == False:
            if winner == 0:
                draw_text('Zum Starten klicken', basic_font, black, 300, screen_width // 2 - 300)
            if winner == 1:
                draw_text('YOU SCORED!', basic_font, black, 355, 160)
                draw_text('CLICK ANYWHERE TO START', basic_font, black, 200, 200)
            if winner == -1:
                draw_text('CPU SCORED!', basic_font, black, 355, 160)

                draw_text('CLICK ANYWHERE TO START', basic_font, black, 200, 200)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False
            if event.type == pygame.MOUSEBUTTONDOWN and live_ball == False:
                live_ball = True
                pong.reset(500, 250)
            # screen_width - 60, screen_height // 2 + 50)

        if speed_increase > 500:
            speed_increase = 0
            if pong.speed_x < 0:
                pong.speed_x -= 1
            if pong.speed_x > 0:
                pong.speed_x += 1
            if pong.speed_y < 0:
                pong.speed_y -= 1
            if pong.speed_y > 0:
                pong.speed_y += 1

        pygame.display.update()

    new_game = False
    while not new_game:

        draw_board()
        draw_text('OPP: ' + str(opp_score), basic_font, white, 20, 15)
        draw_text('P1: ' + str(player_score), basic_font, white, screen_width - 115, 15)
        draw_text('TEMPO: ' + str(abs(pong.speed_x)), basic_font, white, screen_width // 2 - 100, 15)

        if player_score == 5:
            draw_text('PLAYER WON!', basic_font, black, 355, 160)
        elif opp_score == 5:
            draw_text('CPU WON!', basic_font, black, 355, 160)
        draw_text('CLICK ANYWHERE TO CONTINUE', basic_font, black, 200, 200)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                pong.reset(500, 250)
                new_game = True

        pygame.display.update()


# create game loop
    while True:
        game_to_five()

pygame.quit()

Re: Hilfe beim Code

Verfasst: Samstag 9. Januar 2021, 00:35
von JonBach18
Das ist der Fehlercode der angezeigt wird:

Traceback (most recent call last):
File "/Users/xxxxxxxxxxxxr/PycharmProjects/Python/666.py", line 245, in <module>
game_to_five()
File "/Users/xxxxxxxxxxxxr/PycharmProjects/Python/666.py", line 240, in game_to_five
pygame.display.update()
pygame.error: video system not initialized

Re: Hilfe beim Code

Verfasst: Samstag 9. Januar 2021, 09:22
von ThomasL
Du rufst pygame.quit() im Code auf und danach wird dann aber noch pygame.display.update() aufgerufen. Das wirft dann den Fehler.
Das pygame.quit() sollte daher nur ganz zuletzt im Code aufgerufen werden.

Code: Alles auswählen

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()

Re: Hilfe beim Code

Verfasst: Samstag 9. Januar 2021, 09:34
von Dennis89
Hallo,

Kommentare sind dazu da, um so beschreiben wieso ein Code ausgeführt wird. In den Kommentaren sollte nicht dass stehen, was man aus den Code-Zeilen schon lesen kann. Beispiel:

Code: Alles auswählen

# Bilschirm Größe
screen_width = 1000
screen_height = 500
Dieser wie auch andere Kommentare sind nicht nötig um den Programmablauf zu verstehen.

Ich habe noch nie 'pygame' genutzt, deswegen habe ich kurz in die Dokumentation geschaut, hier steht:
This module contains various constants used by pygame. Its contents are automatically placed in the pygame module namespace.
Das heißt für mich, wenn du 'pygame' importierst ist es nicht nötig, zusätzlich noch die Konstanten von 'pygame' mit 'pygame.locals' zu importieren.
Dann solltest du dir die *-Importe im Allgemeinen nicht angewöhnen. Dass bedeutet nämlich, dass du dir alle Namen, die im importierten Modul vorhanden sind, in dein Programm holst. Da keiner das Modul auswendig lernt, kann es zu Namenskonflikten mit deinen verwendeten Namen und den *-Importen kommen. Die Fehlersuche ist dann auch nervig.
Grundsätzlich schreibt man KONSTANTEN in Python groß, variablen_schreibt_man klein und wenn nötig mit Unterstrich, Funktionen ebenso. Klassen werden in der MixCase Schreibweise geschrieben.
Das ist hier nachzulesen:
https://www.python.org/dev/peps/pep-0008/

Normal haben Python-Programme eine Funktion 'main' in dieser wird der Programmablauf gestartet und gesteuert. Der Aufbau sollte dann diese Form erhalten:

Code: Alles auswählen

import xyz

class MixCase():
    def __init___():
        pass
            
    def do_something():
        pass
            
def main():
    MixCase.do_something()
    
if __name__ == '__main__':
    main()
Das war jetzt nur Allgemeines, die Details überlasse ich denen, die das besser können. Ich bin selbst in den Anfängen.

Grüße
Dennis