1

我是 Pygame 的新手,所以我仍在为整个“事件”概念而苦苦挣扎。

基本上,我目前的挑战是:

  1. 让 pygame.event.get() 在主循环之外工作,这样我就可以让玩家从游戏的一个部分继续到下一个部分(例如,通过按空格键)。

  2. 想办法在主线程中组织游戏的不同功能,这样它们就不会只是不断地循环和相互覆盖。

我了解主循环在许多游戏中的重要性,但是当游戏涉及从一个事件转移到下一个事件时,我无法理解如何在这个游戏中使用它(这是一个相对简单的基于文本的游戏,你可以通过不同的菜单并选择要进行的选项)。由于主循环是一个while循环,它里面的一切都在不断重复,那么我怎么可能从一个屏幕转到下一个屏幕而不会无限地相互冲突呢?

例如,我有一个介绍性序列(一个 Intro() 函数),它应该首先运行,然后允许您通过按空格键继续实际游戏。我在实际的主循环之前放置了 Intro() 函数以防止它循环。但是,pygame.event.get() 在其中不起作用(请记住,我已经在主循环中有这样一个事件“for”循环),我希望能够通过点击进入游戏本身空格键。

如果有人能启发我并给我上逻辑和线程方面的课程,那就太好了。

谢谢。

4

1 回答 1

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管理场景之间的过渡的方法。此外,您可能希望拥有某种游戏状态对象,以便在场景中传递(例如,在游戏结束场景中显示您从游戏场景中获得的分数)。

于 2013-09-09T07:54:14.907 回答