Pygame错误,音乐无法正常播放,因为它只是循环播放开始部分

问题描述 投票:1回答:1

我正在Pygame上开发一款基本的射击游戏(我正在学习教程。)我决定添加背景音乐以保持良好状态。代码(很长!):

import pygame
from pygame import image as sprite

pygame.init()

dow = pygame.display.set_mode((1000, 700))

pygame.display.set_caption("PY.Touhou")

clock = pygame.time.Clock()
rightSprites = [sprite.load('ness-right1.png'),
                pygame.image.load('ness-right2.png'),
                pygame.image.load('ness-right3.png'),
                pygame.image.load('ness-right4.png'),
                pygame.image.load('ness-right5.png'),
                pygame.image.load('ness-right6.png'),
                pygame.image.load('ness-right7.png'),
                pygame.image.load('ness-right8.png')
                ]
leftSprites = [
    sprite.load('ness-left1.png'),
    sprite.load('ness-left2.png'),
    sprite.load('ness-left3.png'),
    sprite.load('ness-left4.png'),
    sprite.load('ness-left5.png'),
    sprite.load('ness-left6.png'),
    sprite.load('ness-left7.png'),
    sprite.load('ness-left8.png')
]

scene = pygame.image.load('bg.png')
idle = pygame.image.load('ness-idle.png')


class Player(object):
    def __init__(self, x_pos, y_pos, w, h):
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.w = w
        self.h = h
        self.velocity = 15
        self.JUMPbool = False
        self.atleft = False
        self.atright = False
        self.steps = 0
        self.jumpheight = 12
        self.hitbox = (self.x_pos + 50, self.y_pos, 73, 227)
        self.still = True

    def move(self):
        if self.steps + 1 >= 24:
            self.steps = 0

        if not self.still:

            if self.atleft:
                dow.blit(leftSprites[self.steps // 4], (self.x_pos, self.y_pos))
                self.steps += 1

            elif self.atright:
                dow.blit(rightSprites[self.steps // 4], (self.x_pos, self.y_pos))
                self.steps += 1

        else:
            if self.atright:
                dow.blit(rightSprites[1], (self.x_pos, self.y_pos))
            else:
                dow.blit(leftSprites[1], (self.x_pos, self.y_pos))
        self.hitbox = (self.x_pos + 50, self.y_pos, 73, 227)
        # pygame.draw.rect(dow, (0, 0, 255), self.hitbox, 2)


class IceBullet(object):
    def __init__(self, x_pos, y_pos, radius, color, direction):
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.radius = radius
        self.color = color
        self.direction = direction
        self.velocity = 8 * direction

    def summon(self):
        pygame.draw.circle(dow, self.color, (self.x_pos, self.y_pos), self.radius)


class EnemyCirno(object):
    erightSprites = [sprite.load('e-right%s.png' % pic) for pic in range(1, 9)]
    eleftSprites = [sprite.load('e-left%s.png' % pic) for pic in range(1, 9)]

    def __init__(self, x_pos, y_pos, w, h, ending):
        self.x_pos = x_pos
        self.y_pos = y_pos
        self.w = w
        self.h = h
        self.ending = ending
        self.path = [self.x_pos, self.ending]
        self.hitbox = (self.x_pos + 50, self.y_pos, 73, 227)
        self.steps = 0
        self.health = 20
        self.isAlive = True
        self.velocity = 4

    def summon(self):
        self.move()
        if self.isAlive:
            if self.steps + 1 >= 24:
                self.steps = 0
            if self.velocity > 0:
                dow.blit(self.erightSprites[self.steps // 4], (self.x_pos, self.y_pos))
                self.steps += 1
            else:
                dow.blit(self.eleftSprites[self.steps // 4], (self.x_pos, self.y_pos))
                self.steps += 1
            pygame.draw.rect(dow, (255, 10, 0), (100, 110, 400, 20))
            pygame.draw.rect(dow, (5, 255, 10), (100, 110, 200 - (20 * (10 - self.health)), 20))
            enemy_health = italicStyle.render('Enemy Health', 1, (255, 0, 0))
            dow.blit(enemy_health, (100, 150))
            self.hitbox = (self.x_pos + 50, self.y_pos, 73, 227)
        # pygame.draw.rect(dow, (0, 0, 0), self.hitbox, 2)

    def move(self):
        if self.velocity > 0:
            if self.x_pos + self.velocity < self.path[1]:
                self.x_pos += self.velocity
            else:
                self.velocity = self.velocity * -1
                self.steps = 0
        else:
            if self.x_pos - self.velocity > self.path[0]:
                self.x_pos += self.velocity
            else:
                self.velocity = self.velocity * -1
                self.steps = 0

    def hit(self):
        if self.health > 1:
            self.health -= 0.50
            hit = pygame.mixer.Sound('hit.wav')
            hit.play()
        else:
            self.isAlive = False
            dead = pygame.mixer.Sound('death_sound.wav')
            dead.play()


# Main starting loop.
letterStyle = pygame.font.SysFont('Bookman Old Style', 50)
italicStyle = pygame.font.SysFont('Bookman Old Style', 30, False, True)
cirno = Player(300, 470, 160, 233)
score = 0
evilCirno = EnemyCirno(50, 470, 160, 233, 800)
maxShots = 0
bullets = []
running = True
while running is True:
    clock.tick(24)
    pygame.time.delay(10)
    music = pygame.mixer.music.load('main_theme.wav') # And here is where the bug begins!
    pygame.mixer.music.play()
    for events in pygame.event.get():
        if events.type == pygame.QUIT:
            running = False
    key = pygame.key.get_pressed()


    def update_screen():
        dow.blit(scene, (0, 0))
        textdisplay = letterStyle.render('Score: ' + str(score), 1, (0, 255, 255))
        won = italicStyle.render("Enemy defeated!", 1, (10, 255, 19))
        dow.blit(textdisplay, (50, 30))
        if not evilCirno.isAlive:
            dow.blit(won, (100, 150))
        cirno.move()
        evilCirno.summon()
        for shot in bullets:
            shot.summon()

        pygame.display.update()


    if maxShots > 0:
        maxShots += 1
    if maxShots > 5:
        maxShots = 0
    for shot in bullets:
        if evilCirno.isAlive:
            if shot.y_pos - shot.radius < evilCirno.hitbox[1] + evilCirno.hitbox[3] and shot.y_pos + shot.radius > \
                    evilCirno.hitbox[1]:
                if shot.x_pos + shot.radius > evilCirno.hitbox[0] and shot.x_pos - shot.radius < evilCirno.hitbox[0] + \
                        evilCirno.hitbox[2]:
                    evilCirno.hit()
                    score += 50
                    bullets.pop(bullets.index(shot))

        if 1000 > shot.x_pos > 0:
            shot.x_pos += shot.velocity
        else:
            bullets.pop(bullets.index(shot))

    if key[pygame.K_z] and maxShots == 0:
        shoot = pygame.mixer.Sound('bullet.wav')
        shoot.play()
        if cirno.atleft:
            facing = -1
        else:
            facing = 1
        if len(bullets) < 5:
            bullets.append(
                IceBullet(round(cirno.x_pos + cirno.w // 2), round(cirno.y_pos + cirno.h // 1.2), 20, (0, 0, 255),
                          facing))

        maxShots = 1

    if key[pygame.K_LEFT] and cirno.x_pos > cirno.velocity:  # Will stop ASAP when reached
        cirno.x_pos -= cirno.velocity
        cirno.atleft = True
        cirno.atright = False
        cirno.still = False

    elif key[
        pygame.K_RIGHT] and cirno.x_pos < 1000 - cirno.velocity - cirno.w:  # If it goes past this, it will stop ASAP, as well
        cirno.x_pos += cirno.velocity
        cirno.atright = True
        cirno.atleft = False
        cirno.still = False
    else:
        cirno.steps = 0
        cirno.still = True
    if not cirno.JUMPbool:
        if key[pygame.K_UP]:
            cirno.JUMPbool = True
            cirno.steps = 0

    else:
        if cirno.jumpheight >= -12:  # What to do if pygame.K_SPACE is pressed down.

            cirno.y_pos -= (cirno.jumpheight * abs(cirno.jumpheight)) * 0.5
            cirno.jumpheight -= 1
        else:
            cirno.jumpheight = 12
            cirno.JUMPbool = False

    update_screen()

pygame.quit()

到目前为止,音乐和声音实际上都在播放。尽管问题在于它只是一遍又一遍地循环播放音乐的开始部分(这只是头几秒钟),所以您得到的只是听起来像是坏了的MP3播放器。(作为参考,音乐是1:45。更奇怪的是,我看到人们毫无问题地使用它。)有什么办法可以解决这个错误?感谢您的帮助:)

python python-3.x pygame python-3.7
1个回答
1
投票

您在这里看到错误了吗?

while running is True:
    [...]
    music = pygame.mixer.music.load('main_theme.wav')
    pygame.mixer.music.play()

正在重新加载并重新播放,以重新播放代码主循环中的音乐。那就是游戏的每更新一次[[frame],>在主循环外加载和播放音乐:

music = pygame.mixer.music.load('main_theme.wav') pygame.mixer.music.play() while running is True: [...]

然后您的代码也可以调用mixer.get_busy() function,以查看音乐是否已停止,并对此进行处理。

您可能还想研究PyGame声音混合器通道,因此您的声音效果会与背景音乐正确混合。

© www.soinside.com 2019 - 2024. All rights reserved.