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中使用多线程。如果您更全面地解释您的目标和问题,我们可能会提供替代解决方案。