问题描述
运行时错误:线程只能启动一次
一个带有正确图像的窗口弹出,但它被冻结并且屏幕立即崩溃。我认为该线程无法在 while 循环中工作,但如果是这种情况,我将如何修复代码。
import pygame
import random
import time
import threading
pygame.init()
#Creates a window for the game
screen = pygame.display.set_mode((1200,720))
#Names the window
pygame.display.set_caption("Pigeon Shootout")
#crosshair location
cx = 550
cy = 300
#pigeon1 location
p1x = 1000
p1y = 400
#pigeon2 location
p2x = 600
p2y = 400
#pigeon3 location
p3x = 200
p3y = 400
#Names images
Background = pygame.image.load('Background.png')
Crosshair = pygame.image.load('Crosshair.png')
Pigeon = pygame.image.load('Pigeon.png')
def pigeon_spawn():
#Generates random number than spawns pigeon acordingly
num = random.randint(1,3)
if num == 1:
screen.blit(Pigeon,(p1x,p1y))
elif num == 2:
screen.blit(Pigeon,(p2x,p2y))
else:
screen.blit(Pigeon,(p3x,p3y))
time.sleep(5)
#Puts pigeon_spawn run separately
pig = threading.Thread(target=pigeon_spawn)
run = True
while run == True:
#imputs background and crosshair
screen.blit(Background,(0,0))
screen.blit(Crosshair,(cx,cy))
#starts pigeon_spawn
pig.start()
#enables you to quit when you press the x at the top
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#makes crosshair move with the arrow keys
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
cy -= 1
if keys[pygame.K_DOWN]:
cy += 1
if keys[pygame.K_LEFT]:
cx -= 1.5
if keys[pygame.K_RIGHT]:
cx += 1.5
screen.blit(Crosshair,cy))
pygame.display.update()
pygame.quit()
解决方法
如果您真的想在一个单独的线程中一遍又一遍地运行函数 pigeon_spawn
中的代码,为什么不将该代码放入一个循环中,以便线程永不退出?
如果你真的需要一遍又一遍地启动一个新线程,你希望每次都创建一个新的 Thread 对象。只需将线程的创建移动到 while
循环中:
while run == True:
...
threading.Thread(target=pigeon_spawn).start()
...
,
你的方法行不通。您不能在线程中blit
带有 Surface 指示符的 Surface。整个场景需要在应用循环中不断重绘。添加一个变量 pigeon_pos
变量,用于在全局命名空间中存储 Pigeon
位置。在交易中循环更改变量。 blit
应用程序循环中的 Pigeon
。在循环之前启动线程一次:
pigeon_pos = (p1x,p1y)
run = True
def pigeon_spawn():
global pigeon_pos
while run:
pigeon_pos = random.choice([(p1x,p1y),(p2x,p2y),(p3x,p3y)])
print(pigeon_pos)
time.sleep(5)
#Puts pigeon_spawn run seperatly
pig = threading.Thread(target=pigeon_spawn)
#starts pigeon_spawn
pig.start()
while run == True:
#enables you to quit when you press the x at the top
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#makes crosshair move with the arrow keys
keys = pygame.key.get_pressed()
cx += keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
cy += keys[pygame.K_DOWN] - keys[pygame.K_UP]
#imputs background and crosshair
screen.blit(Background,(0,0))
screen.blit(Crosshair,(cx,cy))
screen.blit(Pigeon,pigeon_pos)
pygame.display.update()
,
运行时错误:线程只能启动一次
简单的意思就是一个线程只能启动一次,不能启动两次。
import threading
import time
def function():
print("Hello!")
time.sleep(3)
print("Bye")
#Starts thread1
thread1 = threading.Thread(target=function)
thread1.start()
#Starts thread2
thread2 = threading.Thread(target=function)
thread2.start()
#Tries to start thread 2,but it is already started,so it will give a RunTimeError
thread2.start()
控制台:
Hello!
Hello!
Traceback (most recent call last):
File "C:\Users\Lukas\Desktop\test322.py",line 16,in <module>
thread2.start()
File "C:\Users\Lukas\AppData\Local\Programs\Python\Python39\lib\threading.py",line 865,in start
raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
Bye
Bye