试图弄清楚如何跟踪 Pygame 事件并组织游戏的功能 [英] Trying to figure out how to track Pygame events and organize the game's functions

查看:13
本文介绍了试图弄清楚如何跟踪 Pygame 事件并组织游戏的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm new to Pygame, so I'm still struggling with the whole "events" concept.

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

Basically, my current challenge is to:

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

  1. Get pygame.event.get() working outside of the main loop so that I can allow for the player to proceed from one part of the game to the next (by pressing spacebar, for instance).

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

Figure out a way to organize the different functions of the game in the main thread so that they don't just keep looping over and over and overriding each other.

我了解主循环在许多游戏中的重要性,但是当游戏涉及从一个事件移动到下一个事件时,我无法理解如何在该游戏中使用它(这是一个相对简单的基于文本的游戏,其中您浏览不同的菜单并选择要进行的选项).由于主循环是一个while循环,其中的所有内容都不断重复,那么我如何从一个屏幕转到另一个屏幕而不会使屏幕彼此无限冲突?

I understand how the main loop is crucial in many games, but I can't grasp how I could use it in this game when the game involves moving from one event to the next (it's a relatively simple text-based game where you go through different menus and select choices to progress). Since the main loop is a while loop, everything within it keeps repeating over and over, so how is it possible for me to go from one screen to the next without the screens infinitely clashing with each other?

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

For instance, I have an introductory sequence (an Intro() function) that is supposed to run first before anything else and then allow you to proceed to the actual game by hitting the spacebar. I have placed the Intro() function before the actual main loop to prevent it from looping. However, pygame.event.get() doesn't work inside it (bear in mind that I already have such an event "for" loop in the main loop), and I want to be able to progress to the game itself by hitting the spacebar.

如果有人能启发我并给我上一堂逻辑和线程课,那就太好了.

It would be great if someone can enlighten me and give me a lesson in logic and threading.

谢谢.

推荐答案

坚持一个主循环,如果你真的不需要线程,不要使用它们.

Stick with a single main loop, and don't use threads if you don't really need them.

您已经发现您的游戏由不同的屏幕组成(我们称它们为Scene,这样我们就不会将其与我们绘制内容的实际屏幕混淆),所以下一个合乎逻辑的步骤是将它们从主循环中分离出来.

You already figured out that your game consists of different screens (let's call them Scene so we don't confuse it with the actual screen where we draw stuff), so the next logical step is to seperate them out from the main loop.

假设您有以下场景:

  • 简介
  • 主菜单
  • 游戏

然后您应该为每个类创建一个类,然后该类将负责绘图/事件处理/这部分中的任何需要.

then you should create a class for each of those, which will then be responsible for drawing/event handling/whatever-needed-in-this-part.

一个简单的例子:

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 来管理场景之间的转换.此外,您可能需要某种游戏状态对象来传递场景(例如,在游戏结束场景中显示游戏场景中的分数).

This way, you have a single mainloop, but different parts of your game are managed by seperate classes. In the simple example above, each scene knows what other scene to activate on a certain event, but this is not necessary. You could create some kind of SceneHandler that manages the transitions between the scenes. Also, you may want to have some kind of game state object that you want to pass around scenes (e.g. show your points from the game scene in your game-over scene).

这篇关于试图弄清楚如何跟踪 Pygame 事件并组织游戏的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆