如何在python中从循环外部结束循环

如何在python中从循环外部结束循环,python,loops,pygame,Python,Loops,Pygame,我正在用python 3.8.3制作一个pygame游戏, 在我的游戏中,我有一个起始屏幕,在这个while循环中: def game_intro(): 简介=正确 mixer.music.load(“musicIntro.mp3”) 混音器。音乐。设置音量(0.02) 混音器。音乐。播放(-1) 而简介: 对于pygame.event.get()中的事件: 如果event.type==pygame.QUIT: pygame.quit() 退出 如果event.type==pygame.KEYD

我正在用python 3.8.3制作一个pygame游戏, 在我的游戏中,我有一个起始屏幕,在这个while循环中:

def game_intro():
简介=正确
mixer.music.load(“musicIntro.mp3”)
混音器。音乐。设置音量(0.02)
混音器。音乐。播放(-1)
而简介:
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
pygame.quit()
退出
如果event.type==pygame.KEYDOWN:
如果event.key==pygame.K_返回:
简介=错误
屏幕。blit(startscherm_img,bordrect)
时钟滴答(30)
按钮(“开始”,302517,94,44,donkerOranje,lichtOranje,“开始”)
按钮(“音乐”,553517,94,44,donkerOranje,lichtOranje,“切换音乐”)
按钮(“退出”,803517,94,44,donkerOranje,lichtOranje,“退出”)
pygame.display.flip()
游戏介绍()
我正在调用上面定义的按钮函数:

def按钮(消息、x、y、w、h、ic、ac、动作=无):
mousePos=pygame.mouse.get_pos()
click=pygame.mouse.get_pressed()
如果x+w>mousePos[0]>x和y+h>mousePos[1]>y:
pygame.draw.rect(屏幕,ac,(x,y,w,h))
如果单击[0]==1并执行操作!=无:
如果操作==“切换音乐”:
PAUSE.toggle()
睡眠时间(0.3)
elif操作==“退出”:
pygame.quit()
睡眠时间(0.3)
elif操作==“开始”:
睡眠时间(0.3)
简介=错误
其他:
pygame.draw.rect(屏幕,ic,(x,y,w,h))
smallText=pygame.font.SysFont(“包豪斯93”,30)
textSurf,textRect=text\u objecten(msg,smallText)
textRect.center=((x+(w/2)),(y+(h/2)))
screen.blit(textSurf,textRect)
它基本上只是检查鼠标在特定区域内的点击,以及是否检测到它执行代码

现在在我的开始屏幕上,我有一个开始按钮,我希望它结束游戏_intro()循环,但是尝试
intro=False
不会产生任何结果。 尝试
break
不起作用,因为它必须在循环本身中

所以我的问题是:如何让这个开始按钮真正结束游戏的循环


p.S我对Python非常陌生

尽管我已经有一段时间没有使用Python了,但你可以尝试将循环作为新线程运行,然后在作为线程手动完成后将其杀死。老实说,将intro设置为false应该会起作用,我会先进行一些调试,以实际检查intro是否设置为false。虽然在进一步阅读您的代码时,我注意到您实际上调用了函数game_intro()两次,这将导致您循环,因为变量intro是在函数的一侧定义的,因此调用函数game_intro()将重置循环,因此可能会在最后删除调用,因为您已经在while循环中进行了调用。另一个选项是在函数cheers的外侧定义变量intro

,据我所知,您在函数
按钮
内设置了
intro=False
,但在
游戏介绍
函数内还有一个名为
intro
的变量。尽管它们具有相同的名称,但Python将它们视为不同的变量

为了有效地将
intro
变量从一个函数更改为另一个函数,您需要将
intro
变量设置为全局变量,或者将
intro
变量作为两个函数之间的参数传递

备选案文1:

intro = True

def button(msg,x,y,w,h,ic,ac,action=None): 
    global intro
    mousePos = pygame.mouse.get_pos() 
    click = pygame.mouse.get_pressed() 
    if x+w > mousePos[0] > x and y+h > mousePos[1] > y: 
        pygame.draw.rect(screen, ac, (x,y,w,h)) 
        if click[0] == 1 and action != None: 
            if action == "toggleMusic": 
                PAUSE.toggle()
                time.sleep(0.3)
            elif action == "quit": 
                pygame.quit()
                time.sleep(0.3)
            elif action == "start": 
                time.sleep(0.3)
                intro = False

def game_intro(): 
    global intro
    mixer.music.load("musicIntro.mp3")
    mixer.music.set_volume(0.02) 
    mixer.music.play(-1) 
    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    intro = False
        screen.blit(startscherm_img, bordrect) 
        clock.tick(30)
        button("Start",302,517,94,44,donkerOranje,lichtOranje,"start")
        button("Music",553,517,94,44,donkerOranje,lichtOranje,"toggleMusic")
        button("Quit",803,517,94,44,donkerOranje,lichtOranje,"quit")
        pygame.display.flip() 
game_intro()
备选案文2:

def button(msg,x,y,w,h,ic,ac, intro, action=None): 
    mousePos = pygame.mouse.get_pos() 
    click = pygame.mouse.get_pressed() 
    if x+w > mousePos[0] > x and y+h > mousePos[1] > y: 
        pygame.draw.rect(screen, ac, (x,y,w,h)) 
        if click[0] == 1 and action != None: 
            if action == "toggleMusic": 
                PAUSE.toggle()
                time.sleep(0.3)
            elif action == "quit": 
                pygame.quit()
                time.sleep(0.3)
            elif action == "start": 
                time.sleep(0.3)
                intro = False
    return intro

def game_intro(): 
    intro = True
    mixer.music.load("musicIntro.mp3")
    mixer.music.set_volume(0.02) 
    mixer.music.play(-1) 
    while intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    intro = False
        screen.blit(startscherm_img, bordrect) 
        clock.tick(30)
        intro = button("Start",302,517,94,44,donkerOranje,lichtOranje,intro,"start")
        intro = button("Music",553,517,94,44,donkerOranje,lichtOranje,intro,"toggleMusic")
        intro = button("Quit",803,517,94,44,donkerOranje,lichtOranje,intro,"quit")
            pygame.display.flip() 
game_intro()

你可以做一些OOP。尝试在类中创建它,如下所示:

class Intro:

  def __init__(self):
    self.intro = True

  def game_intro(self): 
    mixer.music.load("musicIntro.mp3")
    mixer.music.set_volume(0.02) 
    mixer.music.play(-1) 
    while self.intro:
        for event in pygame.event.get():
            if event.type == pygame.QUIT: 
                pygame.quit()
                quit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    self.intro = False
        screen.blit(startscherm_img, bordrect) 
        clock.tick(30)
        button("Start",302,517,94,44,donkerOranje,lichtOranje,"start")
        button("Music",553,517,94,44,donkerOranje,lichtOranje,"toggleMusic")
        button("Quit",803,517,94,44,donkerOranje,lichtOranje,"quit")
        pygame.display.flip() 

  def button(self, msg,x,y,w,h,ic,ac,action=None): 
    mousePos = pygame.mouse.get_pos() 
    click = pygame.mouse.get_pressed() 
    if x+w > mousePos[0] > x and y+h > mousePos[1] > y: 
        pygame.draw.rect(screen, ac, (x,y,w,h)) 
        if click[0] == 1 and action != None: 
            if action == "toggleMusic": 
                PAUSE.toggle()
                time.sleep(0.3)
            elif action == "quit": 
                pygame.quit()
                time.sleep(0.3)
            elif action == "start": 
                time.sleep(0.3)
                self.intro = False


obj = Intro()
start = obj.gameintro()
intro
是在实例中使用
self
定义的,因此可以在类中的任何位置调用它。

线程事件

将全局范围变量(两个函数之外)指定为
threading.Event
实例

然后,在想要控制循环时设置并清除该事件

import threading


do_intro_loop = threading.Event


def button(action=None):
  if action == "start":
    do_intro_loop.clear()

def into():
  do_intro_loop.set()
  while do_intro_loop.is_set():
    # show do intro stuff here
    pass

intro()

如果您将其放入一个类中,那么您可以将intro定义为一个字段,并在方法中读取/更新它。我尝试了两种解决方案,但都出现了一个错误:
UnboundLocalError:assignment之前引用的局部变量“intro”
您是对的,选项2中缺少
intro
定义。请使用选项2重试,我编辑了它,现在应该可以工作了。