我是Pygame的新手,所以我仍然在努力解决整个“事件”概念。
基本上,我目前面临的挑战是:
让pygame.event.get()在主循环之外工作,这样我就可以允许玩家从游戏的一个部分进入下一个部分(例如按空格键)。
找出一种在主线程中组织游戏的不同功能的方法,这样它们就不会一直反复循环并相互覆盖。
我理解主循环在许多游戏中是如何至关重要的,但是当游戏涉及从一个事件移动到另一个事件时,我无法理解如何在这个游戏中使用它(这是一个相对简单的基于文本的游戏,其中您将浏览不同的菜单并选择要进行的选择)。由于主循环是一个while循环,所以其中的所有内容都不断重复,所以我怎样才能从一个屏幕到另一个屏幕,而屏幕无法相互冲突?
例如,我有一个介绍性序列(一个Intro()函数),该序列应该先于其他任何东西运行,然后让你通过点击空格键继续进行实际游戏。我已经在实际主循环之前放置了Intro()函数以防止它循环。但是,pygame.event.get()在其中不起作用(请记住,我已经在主循环中有“for”循环这样的事件),我希望能够通过点击进入游戏本身空格键。
如果有人能够启发并给我一个逻辑和线程的教训,那将是很棒的。
感谢。
答案 0 :(得分:3)
坚持使用一个主循环,如果你真的不需要它们,不要使用线程。
你已经发现你的游戏包含不同的屏幕(让我们称之为Scene
,所以我们不要把它与我们绘制东西的实际屏幕混淆,所以下一个合乎逻辑的步骤是将它们从主循环中分离出来。
假设您有以下场景:
然后你应该为每个人创建一个类,然后负责绘图/事件处理/本节中的任何需要。
一个简单的例子:
import pygame
pygame.init()
class Scene(object):
screen = None
class Intro(Scene):
def __init__(self):
self.c = (32, 32, 100)
def draw(self):
Scene.screen.fill(self.c)
def update(self):
# since scenes are classes, they have a state that we can modify
r,g,b = self.c
r += 1
g += 1
b += 2
if r > 255: r = 0
if g > 255: g = 0
if b > 255: b = 0
self.c = r, g, b
def handle(self, event):
# move to Menu-scene when space is pressed
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
# returning a scene from handle or update changes the current scene
return Menu()
class Menu(Scene):
def draw(self):
# draw menu
Scene.screen.fill((200, 200, 100))
def update(self):
pass
# do something
def handle(self, event):
# handle menu input
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_a:
return Game()
if event.key == pygame.K_b:
return Intro()
class Game(Scene):
pass # implement draw update handle
Scene.screen = pygame.display.set_mode((800, 600))
scene = Intro()
while True:
if pygame.event.get(pygame.QUIT): break
for e in pygame.event.get():
scene = scene.handle(e) or scene
scene = scene.update() or scene
scene.draw()
pygame.display.flip()
这样,您就拥有一个主循环,但游戏的不同部分由单独的类管理。在上面的简单示例中,每个场景都知道在某个事件上要激活的其他场景,但这不是必需的。您可以创建某种SceneHandler
来管理场景之间的过渡。此外,您可能希望拥有某种想要传递场景的游戏状态对象(例如,在游戏场景中显示游戏场景中的点数)。