使用pygame进行多线程处理,程序崩溃

2024-02-24

大家好,提前感谢您的帮助。我刚刚发现了 pygame (一个 python 库),我想用它玩一下,但我遇到了一个问题。我尝试在代码中使用线程,但每次启动程序时都会崩溃。

我已经隔离了问题并且我知道它是thread_1这会导致崩溃,因为当我将其注释掉时,一切都会恢复正常。我尝试更改函数的代码thread_1,但它仍然崩溃。我很确定这不是函数的内容animateTitle这会导致崩溃,但我使用线程的方式。

import pygame

from pygame.locals import *

from threading import Thread


def encadre(screen):  
    pygame.draw.line(screen, (250, 250, 250), (230, 140), (520, 140), 3)
    pygame.draw.line(screen, (250, 250, 250), (230, 190), (520, 190), 3)
    pygame.draw.line(screen, (250, 250, 250), (230, 140), (230, 190), 3)
    pygame.draw.line(screen, (250, 250, 250), (520, 140), (520, 190), 3)


def initRoad(screen):  
    pygame.draw.line(screen, (250, 250, 250), (30, 0), (30, 500))
    pygame.draw.line(screen, (250, 250, 250), (100, 0), (100, 500))
    pygame.draw.line(screen, (250, 250, 250), (650, 0), (650, 500))
    pygame.draw.line(screen, (250, 250, 250), (720, 0), (720, 500))
    drawLines(screen)


def drawLines(screen): 
    i = 0
    while i <= 49:
        pygame.draw.line(screen, (250, 250, 250), (65, i * 10), (65, (i + 1) * 10))
        pygame.draw.line(screen, (250, 250, 250), (685, i * 10), (685, (i + 1) * 10))
        i = i + 3


def initText(screen, text1):  
    text1pos = text1.get_rect()
    text1pos.x = 235
    text1pos.y = 150
    screen.blit(text1, text1pos)

    font1 = pygame.font.Font(None, 30)
    text1 = font1.render("PLAY", 1, (10, 10, 10))
    text1pos = text1.get_rect()
    text1pos.x = 210
    text1pos.y = 310
    screen.blit(text1, text1pos)

    font1 = pygame.font.Font(None, 30)
    text1 = font1.render("QUIT", 1, (10, 10, 10))
    text1pos = text1.get_rect()
    text1pos.x = 490
    text1pos.y = 310
    screen.blit(text1, text1pos)


def animateRoad(screen):  # not done
    pygame.draw.line(screen, (130, 130, 130), (65, 0), (65, 500))
    pygame.draw.line(screen, (130, 130, 130), (685, 0), (685, 500))


def animateTitle(screen, text1): 
    text1pos = text1.get_rect()
    while True:
        pygame.draw.rect(screen, (130, 130, 130), (235, 150, 283, 35))
        pygame.display.flip()
        pygame.time.wait(500)
        text1pos.x = 235
        text1pos.y = 150
        screen.blit(text1, text1pos)
        pygame.display.flip()
        pygame.time.wait(1000)


def loop(surface1, surface2):
    while True:
        for event in pygame.event.get():

            if event.type == QUIT:
                return

            if event.type == pygame.MOUSEBUTTONDOWN:
                if surface1.topleft[0] <= pygame.mouse.get_pos()[0] <= surface1.topright[0]:
                    if surface1.topleft[1] <= pygame.mouse.get_pos()[1] <= surface1.bottomleft[1]:
                    print('play')

                if surface2.topleft[0] <= pygame.mouse.get_pos()[0] <= surface2.topright[0]:
                    if surface2.topleft[1] <= pygame.mouse.get_pos()[1] <= surface2.bottomleft[1]:
                    return

    pygame.display.flip()
    pygame.time.wait(10)


def main():
    pygame.init()
    screen = pygame.display.set_mode((750, 500))
    pygame.display.set_caption('Infinite circle run')

    background = pygame.Surface(screen.get_size())  
    background = background.convert()
    background.fill((130, 130, 130))
    screen.blit(background, (0, 0))

    encadre(screen)
    initRoad(screen)

    surface1 = pygame.Rect(193, 290, 85, 50) 
    button1 = pygame.draw.rect(screen, (0, 0, 240), surface1)
    surface2 = pygame.Rect(472, 290, 85, 50)  
    button2 = pygame.draw.rect(screen, (240, 0, 0), surface2)

    font1 = pygame.font.Font(None, 50)
    text1 = font1.render("Infinite circle run", 1, (0, 240, 0))
    initText(screen, text1)  

    pygame.display.flip()

    thread_1 = Thread(target=animateTitle(screen, text1), daemon=True)
    thread_2 = Thread(target=loop(surface1, surface2))
    # thread_3 = Thread(target=animateRoad(screen))

    thread_1.start()
    thread_2.start()
    # thread_3.start()


if __name__ == '__main__':
    main()

线程会导致许多问题,一般的经验法则是如果没有必要就避免它们。它们使您的程序变得不确定,更难调试,更难测试,更难维护并且速度更慢(大多数时候)。在您的程序中,没有理由使用线程。相反,你应该按顺序做事。 Pygame 将在必要时隐式创建线程(例如在处理pygame.mixer)

为什么它不起作用,是因为 pygame 期望所有事件处理都会发生在设置视频模式的线程中 https://wiki.libsdl.org/SDL_PollEvent(pygame 使用 SDL2,因此该链接)。您无法在另一个线程中处理它们,并且由于您没有(正确地)处理它们,操作系统会认为您的程序已经崩溃。


我做了一个例子来展示一种制作动画的方法。这个概念是你告诉 pygame 在一定时间后,你想要发布一个事件。当该事件出现在您的事件循环中时,您就要做一些事情。

在你的情况下,你告诉 pygame 发布DRAW_TEXT_EVENT500 毫秒后当此事件出现在您的事件循环中时,您首先告诉 pygame 不要发布DRAW_TEXT_EVENT不再,但要发帖CLEAR_TEXT_EVENT1000毫秒后。然后你绘制文本。

1000ms后,CLEAR_TEXT_EVENT将出现在您的事件循环中。现在你做基本上相同的事情,但是禁用CLEAR_TEXT_EVENT并告诉 pygame 发布DRAW_TEXT_EVENT500毫秒后。

我对你的代码没有做太多改变。我在顶部为事件添加了 2 个定义。我已经删除了你的功能loop and animateTitle,并将它们放入游戏循环中。最后,我在中添加了游戏循环main功能。

import pygame
from pygame.locals import *

# Events that we're going to post.
DRAW_TEXT_EVENT  = pygame.USEREVENT + 1
CLEAR_TEXT_EVENT = pygame.USEREVENT + 2


def encadre(screen):
    pygame.draw.line(screen, (250, 250, 250), (230, 140), (520, 140), 3)
    pygame.draw.line(screen, (250, 250, 250), (230, 190), (520, 190), 3)
    pygame.draw.line(screen, (250, 250, 250), (230, 140), (230, 190), 3)
    pygame.draw.line(screen, (250, 250, 250), (520, 140), (520, 190), 3)


def initRoad(screen):
    pygame.draw.line(screen, (250, 250, 250), (30, 0), (30, 500))
    pygame.draw.line(screen, (250, 250, 250), (100, 0), (100, 500))
    pygame.draw.line(screen, (250, 250, 250), (650, 0), (650, 500))
    pygame.draw.line(screen, (250, 250, 250), (720, 0), (720, 500))
    drawLines(screen)


def drawLines(screen):
    i = 0
    while i <= 49:
        pygame.draw.line(screen, (250, 250, 250), (65, i * 10), (65, (i + 1) * 10))
        pygame.draw.line(screen, (250, 250, 250), (685, i * 10), (685, (i + 1) * 10))
        i = i + 3


def initText(screen, text1):
    text1pos = text1.get_rect()
    text1pos.x = 235
    text1pos.y = 150
    screen.blit(text1, text1pos)

    font1 = pygame.font.Font(None, 30)
    text1 = font1.render("PLAY", 1, (10, 10, 10))
    text1pos = text1.get_rect()
    text1pos.x = 210
    text1pos.y = 310
    screen.blit(text1, text1pos)

    font1 = pygame.font.Font(None, 30)
    text1 = font1.render("QUIT", 1, (10, 10, 10))
    text1pos = text1.get_rect()
    text1pos.x = 490
    text1pos.y = 310
    screen.blit(text1, text1pos)


def animateRoad(screen):  # not done
    pygame.draw.line(screen, (130, 130, 130), (65, 0), (65, 500))
    pygame.draw.line(screen, (130, 130, 130), (685, 0), (685, 500))



def main():
    pygame.init()
    screen = pygame.display.set_mode((750, 500))
    pygame.display.set_caption('Infinite circle run')

    background = pygame.Surface(screen.get_size())
    background = background.convert()
    background.fill((130, 130, 130))
    screen.blit(background, (0, 0))

    encadre(screen)
    initRoad(screen)

    surface1 = pygame.Rect(193, 290, 85, 50)
    button1 = pygame.draw.rect(screen, (0, 0, 240), surface1)
    surface2 = pygame.Rect(472, 290, 85, 50)
    button2 = pygame.draw.rect(screen, (240, 0, 0), surface2)

    font1 = pygame.font.Font(None, 50)
    text1 = font1.render("Infinite circle run", 1, (0, 240, 0))
    initText(screen, text1)

    pygame.display.flip()

    pygame.time.set_timer(DRAW_TEXT_EVENT, 500)

    text1pos = text1.get_rect()

    # GAME LOOP
    while True:

        for event in pygame.event.get():
            if event.type == QUIT:
                return
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if surface1.topleft[0] <= pygame.mouse.get_pos()[0] <= surface1.topright[0]:
                    if surface1.topleft[1] <= pygame.mouse.get_pos()[1] <= surface1.bottomleft[1]:
                        print('play')
                elif surface2.topleft[0] <= pygame.mouse.get_pos()[0] <= surface2.topright[0]:
                    if surface2.topleft[1] <= pygame.mouse.get_pos()[1] <= surface2.bottomleft[1]:
                        return

            elif event.type == DRAW_TEXT_EVENT:
                pygame.draw.rect(screen, (130, 130, 130), (235, 150, 283, 35))
                pygame.time.set_timer(DRAW_TEXT_EVENT,  0)     # Disable the event.
                pygame.time.set_timer(CLEAR_TEXT_EVENT, 1000)  # Post event after 1000ms.
            elif event.type == CLEAR_TEXT_EVENT:
                text1pos.x = 235
                text1pos.y = 150
                screen.blit(text1, text1pos)
                pygame.time.set_timer(CLEAR_TEXT_EVENT, 0)    # Disable the event.
                pygame.time.set_timer(DRAW_TEXT_EVENT,  500)  # Post event after 500ms.

        # Only call once each frame!
        pygame.display.flip()


if __name__ == '__main__':
    main()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用pygame进行多线程处理,程序崩溃 的相关文章

  • Java 和/C++ 在多线程方面的差异

    我读过一些提示 多线程实现很大程度上取决于您正在使用的目标操作系统 操作系统最终提供了多线程能力 比如Linux有POSIX标准实现 而windows32有另一种方式 但我想知道编程语言水平的主要不同 C似乎为同步提供了更多选择 例如互斥锁
  • 使用 imblearn 管道进行交叉验证之前或之后是否发生过采样?

    在对训练数据进行交叉验证以验证我的超参数之前 我已将数据分为训练 测试 我有一个不平衡的数据集 并且想要在每次迭代中执行 SMOTE 过采样 因此我使用以下方法建立了一个管道imblearn 我的理解是 将数据分成k折后应该进行过采样 以防
  • Python 2.7:支持一个端口上多个连接的流式 HTTP 服务器

    我正在寻找一个标准的Python 2 7包 提供一个同时执行的HTTP服务器流媒体同一端口号上的连接 嘿 各位版主 请停止将我的问题标记为想要以非流媒体方式提供服务的问题的重复项 例如 python 中的多线程 Web 服务器 https
  • Django 2.0 haystack 更新索引,重建索引抛出错误

    我使用 django 2 0 和 haystack whoosh 作为搜索 我按照文档中的说明进行配置 发生的问题是当我跑步时 manage py rebuild index它显示此错误 Traceback most recent call
  • ValueError:没有为“dense_input”提供数据

    我正在使用以下简单的代码使用tensorflow加载csv并使用keras执行建模 无法弄清楚这个错误 import tensorflow as tf train dataset fp tf keras utils get file fna
  • 如何使用 python 的 http.client 准确读取一个响应块?

    Using http client在 Python 3 3 或任何其他内置 python HTTP 客户端库 中 如何一次读取一个分块 HTTP 响应一个 HTTP 块 我正在扩展现有的测试装置 使用 python 编写 http clie
  • 使用 Python 3 动态插入到 sqlite

    我想使用 sqlite 写入多个表 但我不想提前手动指定查询 有数十种可能的排列 例如 def insert sqlite tablename data list global dbc dbc execute insert into tab
  • 带有空格的 Firestore 文档字段名称在 Python 中与 .where() 一起使用时会返回错误

    使用 Firebase 的 Cloud Firestore 在 Python 3 7 中编写一个非常简单的程序 在程序中 我使用 where 下拉集合的一部分 然后使用 for 循环对其进行迭代 当任何带有空格的字段名称被传递到 where
  • 更改QLineEdit的ClearButton图标

    我想在Windows 10 1909 64位 上的Python 3 8和PyQt5 5 15 0 上更改我的QLineEdit的ClearButton图标 稍后我想在Linux上运行代码 我尝试应用此处找到的代码 如何在 QLineEdit
  • 如何检测并找出程序是否陷入死锁?

    这是一道面试题 如何检测并确定程序是否陷入死锁 是否有一些工具可用于在 Linux Unix 系统上执行此操作 我的想法 如果程序没有任何进展并且其状态为运行 则为死锁 但是 其他原因也可能导致此问题 开源工具有valgrind halgr
  • 生成二叉树的所有从根到叶的分支

    抱歉 如果这是一个常见问题 但我还没有找到适合我的特定问题的答案 我正在尝试实施一个walk方法将二叉树从根节点遍历到每个叶节点 每当到达叶节点时都会生成根到叶路径 例如 遍历表示为的二叉树 a b d c 会产生 a b c a d 我的
  • 在不支持线程的程序加载的共享库中使用 C++11 多线程

    我目前正在尝试在共享库中使用 C 11 多线程 该库加载到 Linux 上的主程序 用 C 编写 中 这是一个大型模拟程序的一部分 我无法更改有关库加载的任何内容或更改一般的主程序 主程序是用 gcc 4 1 2 编译的 我没有它的源代码
  • 芹菜中未处理的异常冻结了工人

    我通过 redis 后端在 docker 中运行 celery 我有 芹菜搅拌容器 芹菜工人容器 Redis容器 celery 工作容器生成 6 个工作进程 如果 celery 任务遇到异常 工作人员 所有工作人员 将停止使用作业 我尝试稍
  • 如何从下面的html中提取数据?

    我想要从中提取数据的 Html 是 div class infoMessageInner p span class ng binding Fiber r best lld till adressen Tj nsterna kan du be
  • falcon,AttributeError:“API”对象没有属性“create”

    我正在尝试测试我的猎鹰路线 但测试总是失败 而且看起来我把所有事情都做对了 my app py import falcon from resources static import StaticResource api falcon API
  • bs4 `next_sibling` VS `find_next_sibling`

    我在使用时遇到困难next sibling 并且类似地与next element 如果用作属性 我不会得到任何返回 但如果用作find next sibling or find next 然后就可以了 来自doc https www cru
  • VB - 以隐式方式链接 DLL

    我正在开发 VB6 图形界面 并且需要隐式链接到 DLL 这样做的动机来自于我上一个问题 https stackoverflow com questions 5194573 有问题的 DLL 使用静态 TLS declspec thread
  • Android:如何使用后台线程?

    我开发了一个应用程序 它从互联网获取内容并相应地在设备的屏幕上显示它 该程序运行得很好 就是有点慢 加载并显示内容大约需要 3 4 秒 我想将获取内容并将其显示在后台线程中的所有代码放在一起 当程序执行这些功能时 我想显示一个进度对话框 你
  • 我可以在我的机器上同时安装 python 2.7 和 3.5 的tensorflow吗?

    目前我通过 Anaconda 在我的机器 MAC OX 上安装了 Python 2 7 Python 3 5 Tensorflow for Python 3 5 我也想在我的机器上安装 Tensorflow for Python 2 7 当
  • Meteor.setTimeout 和 Meteor.methods 之间的并发

    在我的 Meteor 应用程序中实现回合制多人游戏服务器 客户端通过发布 订阅接收游戏状态 并且可以调用 Meteor 方法sendTurn将回合数据发送到服务器 他们无法直接更新游戏状态集合 var endRound function g

随机推荐

  • 单击单元格时的操作

    H 我是 VBA 新手 这可能是一个太简单的问题 但我正在努力使用 VBA 当单元格 1 1 被点击时 因为它有1 消息框会显示 hi Sub test click action when cell 1 1 is clicked and i
  • 如何动态更改黑莓标签字段的字体颜色?

    我有一个标签字段和三个按钮 名称分别为红色 黄色 蓝色 如果我单击红色按钮 则标签字段字体颜色应更改为红色 同样 如果我单击黄色按钮 则字体颜色应更改为黄色 同样 根据按钮颜色 标签字段中的字体颜色应发生变化 谁能告诉我该怎么做 Label
  • Laravel Session 检测到一个域、多个数据库

    我读过几篇文章 主题 例如this https stackoverflow com questions 31847054 how to use multiple databases in laravel this https medium
  • Git 存储库太大

    我有一个项目 其中包含大约 12MB 的代码和资产 我一直在使用 Git 跟踪它 并且刚刚注意到我的 git文件夹现在刚刚超过 1 83GB 它由几个小文件组成 然后是一个包文件 约占该文件夹的 1 82GB 我已经跑了git gc agg
  • 检测android中home按钮的点击事件(应用程序启动器图标)

    如何识别android中应用程序启动器图标中的点击事件 一旦用户单击此图标 我需要转到主屏幕 例如 假设这是清单文件
  • WPF 中的图像可见性问题 - 按下按钮时不显示

    我正在用 C 开发一个 WPF 应用程序 其中有一个按钮可以切换图像的可见性 我已按照说明进行操作并实现了以下代码来处理按钮单击 XAML
  • 保存到服务器后图像质量下降。

    我正在捕获图像 并将其保存到服务器路径中 它工作正常 捕获的图像看起来质量不错 但将图像保存到服务器后 其质量下降 这是我的代码 这是我的活动 import java io BufferedReader import java io Byt
  • 无法在 android studio 的模拟器中启动 AVD。参数无效

    我在 Android Studio 2 1 2 中遇到模拟器问题 当我尝试启动 AVD 时 我收到一条消息 无法在模拟器中启动 AVD Output 哈克斯已启用 该虚拟机所需的内存超出了驱动程序限制 Hax ram size 0x6000
  • 如何并行化行式 Pandas 数据帧的 apply() 方法

    我有以下代码 import pandas as pd import time def enrich str str val1 f str 1 val2 f str 2 val3 f str 3 time sleep 3 return val
  • 使用 JSONDecoder 解码 PascalCase JSON

    我需要用大写首字母 又名 PascalCase 或 UppperCamelCase 解码 JSON 如下所示 Title example Items hello world 所以我创建了一个符合以下条件的模型Codable struct M
  • 如何使用 codeigniter 表单助手添加属性

    我找不到这个问题的答案 假设我使用代码点火器表单助手输出一个输入字段 echo form input username username 如何添加属性 例如class or id对此input filed 您可以传递一个关联数组 其中包含您
  • 我应该在长时间运行的 AsyncTask 中使用 getApplicationContext 还是 Activity.this

    我有一个长时间运行的异步任务 它将一些数据发送到我的服务器 然后停止 整个过程可能涉及一些请求和响应 我必须从数据库读取数据 发送数据并处理响应并相应地更新我的数据库 我正在使用内容提供程序从数据库读取和更新数据 现在要使用内容提供程序 我
  • 将数组除以值的有效方法是什么?

    只是想知道 将数组除以标量的最有效方法是什么 我可以清楚地循环它 但在我的情况下效率是最重要的 常见的琐碎方式 var array 2 var array 1 original data var divisor my scalar for
  • Windows C++ 服务启动时 ucrtbase.dll 出现故障

    所以我开发这个程序已经有一段时间了 它的目的是充当我们 IT 团队的资产管理器 将来可能会更多 我有 2 项服务 我们现在将其称为 Manager 和 IAM 管理器 负责所有服务 目前只有库存资产管理器 称为 IAM 的所有管理工作 例如
  • 未授予 Google Drive API 读取权限

    我正在尝试使用 Google Drive API 从 Google Drive 下载随机文件 尽管运行代码后我收到一条错误消息 用户尚未授予应用程序 app code 对文件 文件名 的读取权限 如何授予该文件的读取权限 我在互联网上和 A
  • 无法使用 Dockerfile 命令更新 Openssl.cnf 文件

    我正在开发一个基于 NET 5 构建的应用程序 我们生成 docker 映像 最近 我使用作为基础的自定义 Docker 映像之一遇到问题 我的应用程序中很少有外部端点 但出现 SSL 证书错误 在对这个问题进行了一些研究之后 我发现ope
  • 如何在 Silverlight 中设置 TextBox 的行为风格?

    在 Xaml 中 我可以为文本框添加自定义行为 例如
  • 如何获取“t”的值,以便我的函数“h(t)=epsilon”为固定的“epsilon”?

    继这个问题之后 如果我已经生成了m 1000随机向量x 0均匀分布在随机矩阵 GOE 的球体和特征向量上 make this example reproducible set seed 101 n lt 500 Sample GOE ran
  • 如何使用 Yarn 升级所有范围内的软件包?

    是否可以升级我的依赖项部分中的所有特定范围的包package json通过使用 Yarn 包管理器 例如 yarn upgrade scope 这将升级所有范围内的包yarn lock and package json file https
  • 使用pygame进行多线程处理,程序崩溃

    大家好 提前感谢您的帮助 我刚刚发现了 pygame 一个 python 库 我想用它玩一下 但我遇到了一个问题 我尝试在代码中使用线程 但每次启动程序时都会崩溃 我已经隔离了问题并且我知道它是thread 1这会导致崩溃 因为当我将其注释