• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Jak wyłączyć / zastopować muzykę która gra w tle w grze w języku Python podczas wyjścia z gry.

Object Storage Arubacloud
0 głosów
486 wizyt
pytanie zadane 25 lipca 2020 w Python przez TeaCup Obywatel (1,370 p.)

Witam,

Robiłem tutorial na Youtube o programowaniu gry w Python i Turtle: 

https://www.youtube.com/watch?v=N77-S-NSJVE

Mam taki kod:

def play_sound(sound_file, time=0):
    # Windows
    if platform.system() == "Windows":
        winsound.PlaySound(sound_file, winsound.SND_ASYNC)
    # Linux
    elif platform.system() == "Linux":
        os.system("aplay -q {}&".format(sound_file))
    # Mac
    else:
        os.system("afplay {}&".format(sound_file))

    if time > 0:
        turtle.ontimer(lambda: play_sound(sound_file, time), t=int(time * 1000))

# Play background music
play_sound("background_music.mp3", 119)

I jak uruchamiam grę to ten kod uruchamia między innymi muzykę w tle. Jednak jak wychodzę z gry zamykając okno to ta muzyka dalej gra aż się skończy odtwarzać. 

Moje pytanie to jak wyłączyć tą muzykę po zamknięciu okna z grą?

Dziękuję za pomoc i pozdrawiam.

1 odpowiedź

+1 głos
odpowiedź 26 lipca 2020 przez MsMaciek123 Pasjonat (24,760 p.)

Pomyślmy trochę.

 elif platform.system() == "Linux":
        os.system("aplay -q {}&".format(sound_file))
    # Mac
    else:
        os.system("afplay {}&".format(sound_file))
 

To podejście jest złe, ponieważ uruchamiasz podproces i jak narazie nie masz nad nim kontroli (nie możesz go zamknąć). Tak się po prostu nie robi. Co jak ktoś na Linuxie nie ma polecenia aplay? Muzyka się nie odtworzy.

 

Lepszym rozwiązaniem jest użycie zewnętrznej biblioteki.

https://linuxhint.com/play_sound_python/

Instalacja playsound:

pip3 install playsound

(Jeśli nie masz pip3, użyj pip)

 Użycie:

from playsound import playsound
playsound(SciezkaDoPliku)

Zamiast ścieżki może być po prostu nazwa, jeśli oba pliki znajdują się w tym samym katalogu. Proste, wieloplatformowe, działa i masz pełną kontrolę nad muzyką w grze. Po zamknięciu procesu funkcja się po prostu zakończy i nie będzie muzyki. (Jak się zagłębisz w dokumentację to znajdziesz też jak zatrzymać, podgłośnić itd.)

komentarz 28 lipca 2020 przez TeaCup Obywatel (1,370 p.)

Hej @MsMaciek123,

Nie znalazłem w dokumentacji (https://pypi.org/project/playsound/) możliwość pogłośnienia, czy zatrzymania:

The playsound module contains only one thing - the function (also named) playsound.

It requires one argument - the path to the file with the sound you’d like to play. This may be a local file, or a URL.

There’s an optional second argument, block, which is set to True by default. Setting it to False makes the function run asynchronously.

 

Też jak ją dołączyłem do kodu to statek z gry space invaders przestał strzelać pociskami oraz dźwięk strzału nie działa więc coś ta biblioteka nie działa jak należy.

Zależało mi też na tym bym mógł za pomocą tej biblioteki odtwarzać muzykę w tle i ją powtarzać jak się skończy. Nic takiego nie znalazłem w dokumentacji. 

Może podam tutaj cały kod gry i spróbuj samemu na swoim komputerze:

import turtle
import os
import math
import random
import platform
from playsound import playsound

# if on Windows you need to import winsound, but better to use Mac or Linux
if platform.system() == "Windows":
    try:
        import winsound
    except:
        print("Winsound module not available.")

wn = turtle.Screen()
wn.bgcolor("black")
wn.title("Space Invaders")
wn.bgpic("space_invaders_background.gif")
wn.tracer(0)  # shut down all updates of the screen

# Register the shapes
wn.register_shape("invader.gif")
wn.register_shape("player.gif")

# Drowing Border
border_pen = turtle.Turtle()
border_pen.speed(0)
border_pen.color("white")
border_pen.penup()
border_pen.setposition(-300, -300)
border_pen.pendown()
border_pen.pensize(3)

for side in range(4):
    border_pen.fd(600)
    border_pen.lt(90)

border_pen.hideturtle()

# set the score to zero
score = 0

# write score
score_pen = turtle.Turtle()
score_pen.penup()
score_pen.speed(0)
score_pen.color("white")
score_pen.setposition(-280, 273)
score_pen.hideturtle()
scorestring = "Score: {}".format(score)
score_pen.write(scorestring, False, align="left", font=("Arial", 14, "normal"))

# Player
player = turtle.Turtle()
player.color("green")
player.shape("player.gif")
player.speed(0)
player.penup()
player.setposition(0, -250)
player.setheading(90)
player.speed = 0

# choose the number of enemies
num_of_enemies = 30
# list of enemies
enemies = []

for i in range(num_of_enemies):
    # Create the enemy
    enemies.append(turtle.Turtle())

enemy_start_x = -200
enemy_start_y = 250
enemy_number = 0

for enemy in enemies:
    enemy.color("red")
    enemy.shape("invader.gif")
    enemy.speed(0)
    enemy.penup()
    x = enemy_start_x + (50 * enemy_number)
    y = enemy_start_y
    enemy.setposition(x, y)
    enemy_number += 1
    if enemy_number == 10:
        enemy_start_y -= 50
        enemy_number = 0

enemyspeed = 0.25

# Create a player bullet
bullet = turtle.Turtle()
bullet.color("yellow")
bullet.shape("triangle")
bullet.speed(0)
bullet.hideturtle()
bullet.penup()
bullet.setheading(90)
bullet.shapesize(0.3, 0.3)

bulletspeed = 6

# defining bullter state
# fire - firing
# ready - ready to fire
bulletstate = "ready"


# Move the player left and right
def move_left():
    player.speed = -4


def move_right():
    player.speed = 4


def move_player():
    x = player.xcor()
    x += player.speed
    if x < -280:
        x = -280
    if x > 280:
        x = 280
    player.setx(x)


def fire_bullet():
    global bulletstate
    if bulletstate == "ready":
        playsound("laser.mp3")
        bulletstate = "fire"
        x = player.xcor()
        y = player.ycor() + 10
        bullet.setposition(x, y)
        bullet.showturtle()


# Calculating the distance between 2 turtles
def isCollision(t1, t2):
    distance = math.sqrt(math.pow(t1.xcor() - t2.xcor(), 2) + math.pow(t1.ycor() - t2.ycor(), 2))
    if distance < 15:
        return True
    else:
        return False


def play_sound(sound_file, time=0):
    # Windows
    if platform.system() == "Windows":
        winsound.PlaySound(sound_file, winsound.SND_ASYNC)
    # Linux
    elif platform.system() == "Linux":
        os.system("aplay -q {}&".format(sound_file))
    # Mac
    else:
        os.system("afplay {}&".format(sound_file))

    if time > 0:
        turtle.ontimer(lambda: play_sound(sound_file, time), t=int(time * 1000))


# Keyboard binding
wn.listen()
wn.onkeypress(move_left, "Left")
wn.onkeypress(move_right, "Right")
wn.onkeypress(fire_bullet, "space")

# Play background music
play_sound("background_music.mp3", 119)

# Main Game Loop
while True:
    wn.update()  # poniewaz mamy wn.tracer() musimy tutaj dac update()
    move_player()

    for enemy in enemies:
        # move the enemy
        x = enemy.xcor()
        x += enemyspeed
        enemy.setx(x)

        # turn around if hit wall
        if enemy.xcor() > 280:
            # moves all enemies down
            for e in enemies:
                y = e.ycor()
                y -= 40
                e.sety(y)
            enemyspeed *= -1

        # turn around if hit wall
        if enemy.xcor() < -280:
            # moves all enemies down
            for e in enemies:
                y = e.ycor()
                y -= 40
                e.sety(y)
            enemyspeed *= -1

        # check for collision between bullet and an enemy
        if isCollision(bullet, enemy):
            play_sound("explosion.mp3")
            # reset the bullet
            bullet.hideturtle()
            bulletstate = "ready"
            bullet.setposition(0, -400)
            # reset the enemy
            enemy.setposition(0, 5000)

            # update score
            score += 10
            scorestring = "Score: {}".format(score)
            score_pen.clear()
            score_pen.write(scorestring, False, align="left", font=("Arial", 14, "normal"))

        # check for collision with enemy and player
        if isCollision(enemy, player):
            play_sound("explosion.mp3")
            player.hideturtle()
            enemy.hideturtle()
            print("Game Over")
            break

    # set the bullet in motion
    if bulletstate == "fire":
        y = bullet.ycor()
        y += bulletspeed
        bullet.sety(y)

    # check if bullet is out of screen
    if bullet.ycor() > 275:
        bulletstate = "ready"
        bullet.hideturtle()

Jak zamienisz wywołania funkcji play_sound na playsound powinieneś mieć takie same rezultaty jak ja czyli brak dźwięku i brak strzelania przez statek. 

Czy masz jeszcze jakieś sugestie jak rozwiązać ten problem? Nie wiem czy nie zainstalowałem playsound podwójnie.

Raz go zainstalowałem przez konsole "pip install playsound" ale w kodzie mi nie wykrywało modułu więc po najechaniu myszką na ten moduł rozwinąłem menu i z menu kontekstowego wybrałem zainstaluj playsound. Wtedy zainstalowało go tak że PyCharm go wykrył. 

Dzięki i pozdrawiam.

komentarz 28 lipca 2020 przez TeaCup Obywatel (1,370 p.)

Hej @MsMaciek123,

Zrobiłem mały test:

from playsound import playsound

playsound("laser.mp3")

Niestety mam error przy tym teście:

Traceback (most recent call last):
  File "/Users/macos/Documents/IT/Library/Python/Youtube Courses/Finished Projects/Space Invaders/test.py", line 3, in <module>
    playsound("laser.mp3")
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/playsound.py", line 55, in _playsoundOSX
    from AppKit     import NSSound
ModuleNotFoundError: No module named 'AppKit'

Próbuje zainstalować moduł AppKit poprzez PyCharm z menu kontekstowego i zgłasza mi error:

Nie wiem za bardzo co powinienem teraz zrobić. Czy możesz mi jakoś pomóc?

Pozdrawiam :-).

komentarz 28 lipca 2020 przez MsMaciek123 Pasjonat (24,760 p.)
Mi na linuxie wszystko działa. Spróbuj użyć innej biblioteki (https://realpython.com/playing-and-recording-sound-python/). Po prostu sprawdź która działa i tej użyj.

Podobne pytania

+1 głos
0 odpowiedzi 222 wizyt
pytanie zadane 24 marca 2021 w C i C++ przez Tymek Sandelewski56 Początkujący (330 p.)
0 głosów
1 odpowiedź 208 wizyt
pytanie zadane 1 czerwca 2023 w Python przez wojtek_programista Nowicjusz (170 p.)

92,543 zapytań

141,386 odpowiedzi

319,499 komentarzy

61,929 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...