Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Pygame的线程问题_Python_Multithreading_Pygame_Python 2.x - Fatal编程技术网

Python Pygame的线程问题

Python Pygame的线程问题,python,multithreading,pygame,python-2.x,Python,Multithreading,Pygame,Python 2.x,我正在开发一个用于学习的小游戏。我已经为标题屏幕创建了一个简单的动画。由于代码中还有一个全屏功能,我想创建一个标题屏幕: 显示动画 当按键被激活时变为全屏 在激活全屏之前继续动画 为了做到这一点,我求助于线程。然而,这是我第一次尝试多线程,我不知道我做错了什么。结果是一个未确定的错误 标题屏幕的代码如下所示: try: GameAnimation = threading.Thread(target=GameTitleAnimation, (Window, WindowDimensions

我正在开发一个用于学习的小游戏。我已经为标题屏幕创建了一个简单的动画。由于代码中还有一个全屏功能,我想创建一个标题屏幕:

  • 显示动画
  • 当按键被激活时变为全屏
  • 在激活全屏之前继续动画
  • 为了做到这一点,我求助于
    线程
    。然而,这是我第一次尝试多线程,我不知道我做错了什么。结果是一个未确定的错误

    标题屏幕的代码如下所示:

    try:
        GameAnimation = threading.Thread(target=GameTitleAnimation, (Window, WindowDimensions, FontDictionary, CurrentVersion))
        GameAnimation.start()
    except:
        print "There was an error while loading the screen. Press one key to exit the program."
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                Quit()
            if event.type == pygame.KEYDOWN:
                if event.key == K_ESCAPE:
                    Quit()
                elif event.key == K_f:
                    Fullscreen(Window, WindowDimensions)
                else:
                    return
    
    动画的代码是:

    TitleWhite = [255, 255, 255, 0]
    Black = BASE_BLACK
    TitleLetters = ("R", "O", "G", "U", "E", " ", "H", "U", "N", "T", "E", "R")
    Title = FontDictionary["TitleFont"][1].render("ROGUE HUNTER", False, TitleWhite)
    TextWidth = Title.get_width()
    TextHeight = Title.get_height()
    TitleXPosition = (WindowDimensions[0] - TextWidth) / 2
    TitleYPosition = (WindowDimensions[1] / 2) - (TextHeight / 2)
    for letter in TitleLetters:
        if letter == " ":
           TitleXPosition += CurrentLetterWidth
        else:
            while TitleWhite[3] < 100:
                TitleWhite[3] += 1
                CurrentLetter = FontDictionary["TitleFont"][1].render(letter, False, TitleWhite)
                CurrentLetter.set_alpha(TitleWhite[3])
                Window.blit(CurrentLetter, (TitleXPosition, TitleYPosition))
                time.sleep(0.008)
                try: 
                    pygame.display.update()
                except Exception:
                    traceback.print_exception
            TitleWhite[3] = 0
            CurrentLetterWidth = CurrentLetter.get_width()
            TitleXPosition += CurrentLetterWidth
    FadeInSurface = pygame.Surface((WindowDimensions[0], WindowDimensions[1]))
    FadeInSurface.fill(TitleWhite)
    OpacityRounds = 1
    while TitleWhite[3] < 100.0:
        TitleWhite[3] = 1.1 ** OpacityRounds
        FadeInSurface.set_alpha(TitleWhite[3])
        Window.blit(FadeInSurface, (0, 0))
        OpacityRounds += 1
        pygame.display.update()
        time.sleep (0.015)
    time.sleep(0.7)  
    TitleXPosition = (WindowDimensions[0] - TextWidth) / 2
    Version = FontDictionary["BodyFont"][1].render(CURRENT_VERSION, False, TitleWhite)
    VersionHeight = Version.get_height()
    VersionWidth = Version.get_width()
    VersionXPosition = (WindowDimensions[0] - VersionWidth) / 2
    VersionYPosition = TitleYPosition + TextHeight
    while True:
        pygame.draw.rect(Window, Black, (0, 0, WindowDimensions[0], WindowDimensions[1]), 0)
        Window.blit(Title, (TitleXPosition, TitleYPosition))
        Window.blit(Version, (VersionXPosition, VersionYPosition))
        pygame.display.update()
    
    TitleWhite=[255,255,255,0]
    黑色=基色\黑色
    标题文字=(“R”、“O”、“G”、“U”、“E”、“E”、“H”、“U”、“N”、“T”、“E”、“R”)
    Title=FontDictionary[“TitleFont”][1]。渲染(“盗贼猎人”,False,TitleWhite)
    TextWidth=Title.get_width()
    text高度=标题。获取高度()
    TitleXPosition=(窗口尺寸[0]-文本宽度)/2
    TitleYPosition=(窗口尺寸[1]/2)-(文本高度/2)
    对于标题文字中的字母:
    如果字母==“”:
    TitleXPosition+=CurrentLetterWidth
    其他:
    而标题白色[3]<100:
    标题白色[3]+=1
    CurrentLetter=FontDictionary[“TitleFont”][1]。呈现(字母,False,TitleWhite)
    CurrentLetter.set_alpha(标题白色[3])
    窗口位(当前字母,(标题位置,标题位置))
    睡眠时间(0.008)
    尝试:
    pygame.display.update()
    除例外情况外:
    traceback.print\u异常
    标题白色[3]=0
    CurrentLetterWidth=CurrentLetter.get_width()
    TitleXPosition+=CurrentLetterWidth
    FadeInSurface=pygame.Surface((WindowDimensions[0],WindowDimensions[1]))
    FadeInSurface.fill(标题白色)
    浑浊度=1
    而标题白色[3]<100.0:
    标题白色[3]=1.1**OpacityRounds
    FadeInSurface.set_alpha(标题白色[3])
    窗口blit(FadeInSurface,(0,0))
    不透明度指数+=1
    pygame.display.update()
    睡眠时间(0.015)
    睡眠时间(0.7)
    TitleXPosition=(窗口尺寸[0]-文本宽度)/2
    Version=FontDictionary[“BodyFont”][1]。呈现(当前版本,False,TitleWhite)
    VersionHeight=Version.get_height()
    VersionWidth=Version.get_width()
    VersionXPosition=(WindowDimensions[0]-VersionWidth)/2
    VersionYPosition=标题位置+文本高度
    尽管如此:
    pygame.draw.rect(窗口,黑色,(0,0,WindowDimensions[0],WindowDimensions[1]),0)
    窗口位置(标题,(标题位置,标题位置))
    blit(版本,(VersionXPosition,VersionYPosition))
    pygame.display.update()
    

    如果有人能帮我,我将非常感激。我快疯了。

    这是一大块需要调试的代码

    我不熟悉pygame或python线程,但在我看来,您需要包含一些调试行,以确定在游戏动画线程期间错误发生的确切位置(如果它在那里发生的话)

    类似这样的模式有助于确定问题的根源:

    import logging
    
    logging.info("start animation initialization")
    ...
    logging.info("begin animation loop")
    ...
    logging.info("end animation loop")
    

    没有理由在代码中使用线程。这只会使您的代码更难阅读、更难调试和更容易出错

    通常,你希望在游戏中有某种状态,你可以用它来决定一帧中应该发生什么。您可以找到一个基于类的示例

    处理这个问题的另一种方法(有点类似于您的代码)是使用协同路由

    查看动画代码,不要调用
    pygame.display.update()
    ,而是将控件返回主循环。主循环将处理事件、帧限制和绘图,然后将控制权交还给协程(它跟踪自己的状态)

    下面是一个简单的黑客示例:

    import pygame
    import pygame.freetype
    
    pygame.init()
    size = (640, 480)
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()
    
    def game_state(surf):
        rect = pygame.Rect(200, 200, 32, 32)
        while True:
            events = yield
            pressed = pygame.key.get_pressed()
            x = 1 if pressed[pygame.K_RIGHT] else -1 if pressed[pygame.K_LEFT] else 0
            rect.move_ip(x*5, 0)
            pygame.draw.rect(surf, pygame.Color('dodgerblue'), rect)
            yield
    
    def title_state(surf):
        text = 'Awesome Game'
        colors = [[255, 255, 255, 20] for letter in text]
        font = pygame.freetype.SysFont(None, 22)
        font.origin = True
        while True:
            for color in colors:
                color[3] += 33
                if color[3] > 255: color[3] = 0
                x = 200
                for (letter, c) in zip(text, colors):
                    bounds = font.get_rect(letter)
                    font.render_to(surf, (x, 100), letter, c)
                    x += bounds.width + 1
    
                font.render_to(surf, (180, 150), 'press [space] to start', pygame.Color('grey'))
                events = yield
                yield
    
    def main():
        title = title_state(screen)
        game = game_state(screen)
        state = title
    
        while True:
            events = pygame.event.get()
            for e in events:
                if e.type == pygame.QUIT:
                    return
                if e.type == pygame.KEYDOWN:
                    if e.key == pygame.K_ESCAPE:
                        return
                    if e.key == pygame.K_SPACE:
                        state = game if state == title else title
                    if e.key == pygame.K_f:
                        if screen.get_flags() & pygame.FULLSCREEN:
                            pygame.display.set_mode(size)
                        else:
                            pygame.display.set_mode(size, pygame.FULLSCREEN)
    
            screen.fill(pygame.Color('grey12'))
            next(state)
            state.send(events)
            pygame.display.update()
            clock.tick(60)
    
    if __name__ == '__main__':
        main()
    
    看看主循环是如何干净和简单的,所有的游戏状态都是在协同过程中处理的。代码的标题屏幕部分不关心全屏与否,也不关心如何切换到全屏,主循环也不关心标题屏幕协同程序的功能。我们不需要线程

    实际上,它与我上面链接的基于类的示例没有什么不同,但是使用协同程序可以轻松实现标题屏幕动画


    基本上,你有一个无休止的循环,你改变了一些状态(比如字母的颜色),然后通过调用
    yield

    来说“现在画这个!”。一般性评论:如果你阅读并开始遵循“结果是一个未确定的错误”意味着什么(或者什么都没有)发生了,对吗?当您尝试运行代码时,会发生什么?请不要只发布代码片段,而是提供一个我们可以复制、粘贴和测试而无需修改的方法。--此外,您通常不必在pygame中使用多线程。如果您更全面地解释您的目标和问题,我们可能会提供替代解决方案。