Sound lähd nicht als DIST

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
tft
User
Beiträge: 16
Registriert: Montag 22. März 2021, 19:06

Hallo,

Nachfolgend ein ganz simpler Testcode für pygame. In der Pyton Umgebung ist noch Panda3D mit Python 3.7 Instaliert.
Ich benutze PyCharm und es ist ein Windows 10 System.

Wenn ich jetzt in der Console diesen befehl eingeb ,> python setup.py bdist_apps , so wird eine DIST erzeugt.
Das Problem ist die Pfad Angabe beim Mixer. Aber nicht wenn ich das über PyCharm starte.

Jemand ne Idee.

Code: Alles auswählen

import pygame

pygame.init()

crash_sound = pygame.mixer.Sound("FH.ogg")
pygame.mixer.Sound.play(crash_sound)

display_width = 1000
display_height = 300
black = (0, 0, 0)
white = (255, 255, 255)
red = (200, 0, 0)
green = (0, 200, 0)
bright_red = (255, 0, 0)
bright_green = (0, 255, 0)
block_color = (53, 115, 255)

gameDisplay = pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('PyGame Testumgebung')
clock = pygame.time.Clock()

def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()

def quitgame():
    pygame.quit()
    quit()

def button(msg,x,y,w,h,ic,ac,action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x+w > mouse[0] > x and y+h > mouse[1] > y:
        pygame.draw.rect(gameDisplay, ac,(x,y,w,h))
        if click[0] == 1 and action != None:
            action()
    else:
        pygame.draw.rect(gameDisplay, ic,(x,y,w,h))
    smallText = pygame.font.SysFont("comicsansms",20)
    textSurf, textRect = text_objects(msg, smallText)
    textRect.center = ( (x+(w/2)), (y+(h/2)) )
    gameDisplay.blit(textSurf, textRect)

def test_loop():

    gameExit = False

    while not gameExit:

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

        gameDisplay.fill(white)
        largeText = pygame.font.SysFont("comicsansms", 80)
        TextSurf, TextRect = text_objects("Pygame Testumgebung", largeText)
        TextRect.center = ((display_width / 2), (display_height / 2)-50)
        gameDisplay.blit(TextSurf, TextRect)

        button("Quit", 550, 200, 100, 50, red, bright_red, quitgame)

        pygame.display.update()
        clock.tick(15)

test_loop()
quit()

Benutzeravatar
__blackjack__
User
Beiträge: 14032
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tft: Da kommt deutlich zu oft die eigentlich nicht existierende `quit()`-Funktion vor. Der sollte genau 0 mal vorkommen. Wenn dann `sys.exit()` aber das auch nur wenn mindestens potentiell ein anderer Rückgabecode als 0 an den Aufrufer des Programms übermittelt werden soll. Sonst ist das in der Regel einfach nur ein Versuch sich um einen sauberen Programmablauf zu drücken. Auch `pygame.quit()` sollte nur einmal im Code stehen, an einer Stelle an der der Programmablauf auf jeden Fall vorbei kommt.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

`gameDisplay` und `clock` sind dann keine globalen Variablen mehr und müssen sauber an die Funktionen übergeben werden, die das benötigen.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

Methoden werden auf Objekten aufgerufen und nicht auf der Klasse mit dem Objekt als Argument.

`gameExit` wird nicht verwendet. Statt das so umständlich zu umschreiben, ist ``while True:`` deutlich einfacher.

`largeText` ist ein guter Name für grossen Text, weniger für eine grosse Schriftart.

Der Name `text_objects()` beschreibt keine Tätigkeit, ist also kein guter Name für eine Funktion. Ich sehe da auch nicht ganz den Mehrwert, denn statt in der Funktion, kann man ja auch an beliebiger anderer Stelle das `Rect`-Objekt von dem `Surface` abfragen.

Namen sollte auch nicht kryptisch abgekürzt werden. Nicht `surf` wenn man `surface` meint, oder `msg` wenn man `message` meint. ``def button(msg,x,y,w,h,ic,ac,action=None):`` ist beispielsweise eine ziemlich unübersichtliche Signatur. Wobei eine Schaltfläche auch eher einen Text statt einer Nachricht darstellt. Und `x`, `y`, `w`, und `h` nicht nur prima ein `Rect`-Objekt beschreiben, sondern man das/dessen Funktionalität auch prima gebrauchen kann.

Man kann den Code an einigen Stelle einfacher und leichter verständlich schreiben wenn man `Rect`-Objekte verwendet, statt Komponenten davon selbst zu berechnen.

`button` ist ein guter Name für einen Button, aber nicht für eine Funktion die einen Button zeichnet.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3
import pygame

FONT_NAME = "comicsansms"

DISPLAY_WIDTH = 1000
DISPLAY_HEIGHT = 300
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (200, 0, 0)
GREEN = (0, 200, 0)
BRIGHT_RED = (255, 0, 0)
BRIGHT_GREEN = (0, 255, 0)
BLOCK_COLOR = (53, 115, 255)


def render_text(font, text):
    return font.render(text, True, BLACK)


def draw_button(surface, text, rect, color, hover_color, action=lambda: None):
    is_mouse_over = rect.collidepoint(pygame.mouse.get_pos())

    pygame.draw.rect(surface, hover_color if is_mouse_over else color, rect)
    text_surface = render_text(pygame.font.SysFont(FONT_NAME, 20), text)
    surface.blit(text_surface, text_surface.get_rect(center=rect.center))

    if is_mouse_over and pygame.mouse.get_pressed()[0]:
        return action()

    return False


def test_loop(screen, clock):
    screen_rect = screen.get_rect()

    font = pygame.font.SysFont(FONT_NAME, 80)
    text_surface = render_text(font, "Pygame Testumgebung")
    text_rect = text_surface.get_rect(center=screen_rect.move(0, -50).center)

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return

        screen.fill(WHITE)
        screen.blit(text_surface, text_rect)
        if draw_button(
            screen,
            "Quit",
            pygame.Rect(550, 200, 100, 50),
            RED,
            BRIGHT_RED,
            lambda: True,
        ):
            return

        pygame.display.update()
        clock.tick(15)


def main():
    pygame.init()

    crash_sound = pygame.mixer.Sound("FH.ogg")
    # crash_sound = pygame.mixer.Sound("test.ogg")
    crash_sound.play()

    screen = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
    pygame.display.set_caption("PyGame Testumgebung")
    clock = pygame.time.Clock()
    test_loop(screen, clock)


if __name__ == "__main__":
    main()
Das mit dem Abbruch per Flag/Rückgabewert ist nicht so wirklich gut, aber wenn man das mit Schaltflächen und Aktionen verallgemeinern will, wird man das sowieso anders, objektorientiert lösen. Und `get_pressed()` für die Maustasten ist auch keine gute Idee, weil man so Clicks verpassen kann. Man sollte nicht versuchen an der Ereignisschleife vorbei zu programmieren, sondern *dort* Tastendrücke etc. registrieren.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
tft
User
Beiträge: 16
Registriert: Montag 22. März 2021, 19:06

Hallo,

danke für deine sehr ausführlichen Erläuterungen. Es macht halt einen Unterschied ob man sich mit einer Sprache länger befasst hat.

............. aber das erklärt leider nicht mein Problem. Es kommt weiterhin diese Meldung.

pygame 2.1.2 (SDL 2.0.18, Python 3.7.9)
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "__main__", line 76, in <module>
File "__main__", line 65, in main
FileNotFoundError: No file 'sfx/FH.ogg' found in working directory 'C:\Users\turgu\Desktop\DrivingSchoolEvergarden'.


Gruss der alte man aus Antalya alias TFT
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na die Fehlermeldung sagt es doch: die Datei ist nicht relativ zum Arbeitsverzeichnis zu finden. Das Arbeitsverzeichnis ist ein Pfad, der IRGENDWO stehen kann. Wenn man sowas robust machen will, benutzt man die __file__-Variable. Die zeigt auf die Python-Datei, die ausgehführt wird. Wird hier auch andauern diskutiert, einfach mal suchen.
tft
User
Beiträge: 16
Registriert: Montag 22. März 2021, 19:06

Hallo,
die Variable __file__ funktioniert nicht. Aber mittlerweile habe ich das Problem gefunden. Hat eine ganze Nacht und viel Experimente und viel lesen erfordert.
Die Fehlermeldung ist einfach nicht richtig. Es müsste heissen ...... .ogg nicht von mixer.sound im Compilierten zustand unterstützt. Aber eigentlich sollte es auch im Interpreter Modus nicht funktionieren......... Von der logig her schon nachvollziehbar. Aber ...... na ja. Hab das Problem jetzt im griff. Was mich hat ärgert. das es im Interpreter läuft. Und als DIST nicht. Das bedeutet das ich ständig testen muss ob meine schreibereien auch als DIST funktioniert.

Gruss vom alten mann, jetzt auch wider in Antalya, alias TFT
Benutzeravatar
sparrow
User
Beiträge: 4536
Registriert: Freitag 17. April 2009, 10:28

Ich denke, die Fehlermeldung ist exakt richtig. Und ich wette, sie verschwindet, wenn du die Datei an die Stelle kopierst, an der sie in der Fehlermeldung gesucht wird.
tft
User
Beiträge: 16
Registriert: Montag 22. März 2021, 19:06

nein ..... eben nicht. Habe ich bereits alles versucht. Leider haben wir nicht die Möglichkeit diese Wette zu verifizieren. Und bei Verwendung einer Wav Datei funktioniert es. Also kann es nicht an dem Datei Pfad liegen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Halte ich für unwahrscheinlich. Es gibt keinen nachvollziehbaren Grund, warum ein Decoder wie OGG nur ohne dist tut. Der ist immer einfach dabei. Wahrscheinlich ist eher,dass du dich eben mit deinen Pfaden verheddert hast. Du zeigst ja nicht, was du mit __file__ probiert hast. Und auch nicht, wie du dein Programm aufrufst, etc.
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Für den Fall das es eventuell übersehen wurde.
Die Fehlermeldung lautet: FileNotFoundError: No file 'sfx/FH.ogg' found in working directory 'C:\Users\turgu\Desktop\DrivingSchoolEvergarden'.

Der Pfad wo die Datei sein müsste wäre für mich daher: 'C:\Users\turgu\Desktop\DrivingSchoolEvergarden\sfx\FH.ogg'

Ist dem so?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
Antworten