Pygame 需要“for event in pygame.event.get()";为了不崩溃 [英] Pygame needs "for event in pygame.event.get()" in order not to crash

查看:194
本文介绍了Pygame 需要“for event in pygame.event.get()";为了不崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

程序像这样工作正常但是,我不明白为什么它需要无用的for event in pygame.event.get(): None in the gameOvergame_loop 中的 while 语句.如果您能找到删除它的方法或解释为什么没有它就不能运行,那就太好了!

The program works fine like this but, I don't understand why it needs the useless for event in pygame.event.get(): None in the gameOver while statement inside game_loop. If you could find a way to delete it or explain why it doesn't run without it, that would be great!

import pygame, time, random

pygame.init()

# SOUND/TEXTURES
icon = pygame.image.load("textures\snakeicon.png")
pygame.display.set_icon(icon)

# VARIABLES
white = (255, 255, 255)
black = (0, 0, 0)
red = (200, 0, 0)
green = (0, 155, 0)
bright_green = (0, 250, 0)
bright_red = (255, 0, 0)

font_size = 50
font = pygame.font.SysFont(None, font_size)

# FUNCTIONS

def text_objects(text, font):
    textSurface = font.render(text, True, black)
    return textSurface, textSurface.get_rect()


def button(msg, x, y, w, h, ic, ac, action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()

    if x + w > mouse[0] > x and y + h > mouse[1] > y:
        pygame.draw.rect(gameWindow, ac, (x, y, w, h))
        if click[0] == 1 and action != None:
            if action == "play":
                game_loop()

            elif action == "quit":
                gameRun = False
                gameWindow.fill(white)
                message_to_screen("Closing Game...", black, 280, 280)
                pygame.display.update()
                time.sleep(1)
                pygame.quit()
                quit()

    else:
        pygame.draw.rect(gameWindow, ic, (x, y, w, h))

    smallText = pygame.font.Font("freesansbold.ttf", 20)
    textSurf, textRect = text_objects(msg, smallText)
    textRect.center = ((x + (w / 2)), (y + (h / 2)))
    gameWindow.blit(textSurf, textRect)

def snake(rect_x, rect_y, block_size):
    pygame.draw.rect(gameWindow, green, [rect_x, rect_y, block_size, block_size])

def message_to_screen(msg, color, x, y):
    screen_text = font.render(msg, True, color)
    gameWindow.blit(screen_text, [x, y])


# WINDOW/SURFACE
display_w = 800
display_h = 600
window_title = "Window"

gameWindow = pygame.display.set_mode((display_w, display_h))
pygame.display.set_caption(window_title)

# FPS/Clock
clock = pygame.time.Clock()


# Game Loop


def game_loop():
    # RECT OPTIONS
    moveSpeed = 10
    block_size = 10

    rect_x = display_w / 2
    rect_y = display_h / 2

    change_x = 0
    change_y = 0

    randApplex = round(random.randrange(0, display_w - block_size) / 10.0) * 10.0
    randAppley = round(random.randrange(0, display_h - block_size) / 10.0) * 10.0

    global gameRun, gameOver
    gameRun = True
    gameOver = False

    while gameRun:

        while gameOver:
            gameRun = False
            gameWindow.fill(white)
            # button(msg, x, y, w, h, ic, ac, action=None)
            message_to_screen("Game Over!", red, 300, 300)
            button("Restart", 150, 450, 100, 50, green, bright_green, "play")
            button("Quit", 550, 450, 100, 50, red, bright_red, "quit")
            pygame.display.update()

           # RIGHT HERE!

            for event in pygame.event.get():
                None

           # RIGHT THERE!

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameRun = False
                gameOver = False
                gameWindow.fill(white)
                message_to_screen("Closing Game...", black, 280, 280)
                pygame.display.update()
                time.sleep(1)
                pygame.quit()
                quit()

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    change_y = -moveSpeed
                    change_x = 0
                elif event.key == pygame.K_s:
                    change_y = moveSpeed
                    change_x = 0
                elif event.key == pygame.K_a:
                    change_x = -moveSpeed
                    change_y = 0
                elif event.key == pygame.K_d:
                    change_x = moveSpeed
                    change_y = 0

        # BOARDER CRASH
        if rect_x >= display_w or rect_x < 0 or rect_y >= display_h or rect_y < 0:
            gameOver = True
        # LOGIC
        rect_x += change_x
        rect_y += change_y

        if rect_x == randApplex and rect_y == randAppley:
            randApplex = round(random.randrange(0, display_w - block_size) / 10.0) * 10.0
            randAppley = round(random.randrange(0, display_h - block_size) / 10.0) * 10.0

        # RENDER
        gameWindow.fill(white)

        pygame.draw.rect(gameWindow, red, [randApplex, randAppley, block_size, block_size])
        snake(rect_x, rect_y, block_size)
        pygame.display.update()

        clock.tick(15)

    message_to_screen("You Lose!", red, 325, 300)
    pygame.display.update()
    time.sleep(1)
    message_to_screen("Closing Game!", black, 280, 350)
    pygame.display.update()
    time.sleep(1)

    # QUIT
    pygame.quit()
    quit()


game_loop()

推荐答案

基本上,操作系统希望 pygame 在您的程序期间处理事件.如果操作系统注意到事件未被处理,它会提醒用户.该程序实际上并没有崩溃或冻结,操作系统只是说您的程序变得没有响应(这是因为您没有响应任何用户事件),但它仍然可以工作.

Basically, the OS expects pygame to handle events during your program. If the OS notice that events aren't handled, it'll alert the user. The program doesn't actually crash or freeze, the OS is just saying that your program has become unresponsive (which it has because you're not responding to any user events), but it still works.

当您的游戏进入小场景时,您可能认为不需要处理事件,但您应该始终检查一个事件:pygame.QUIT 事件(在用户按下顶部角落的关闭按钮).在您的示例中,您不允许用户在游戏结束序列期间退出(您为玩家提供了一个点击按钮,但用户也希望点击关闭按钮也会关闭游戏).

When your game is entering small scenes you might think that you don't need to handle events, but there is one event you should always check for: the pygame.QUIT event (sent when the user press the close button at the top corner). In your example you're not allowing the user to quit during the game over sequence (you're providing the player a button to click but a user would also expect clicking the close button would close the game as well).

另一个原因是事件队列不断填​​满.因此,如果用户发送多个键并用鼠标按下多个区域,则不会发生任何直到他/她再次进入游戏(您有一个事件循环).然后将执行每个事件.因此,定期清空队列很重要.每次调用 pygame.event.get()pygame.event.clear() 时,队列都会被清空.

Another reason is that the event queue is constantly filling up. So if the user would spam multiple keys and press multiple areas with the mouse, nothing would happen until he/she enters the game again (where you have an event loop). Then every event would be executed. Therefore it's important to regularly empty the queue. The queue is emptied every time you call pygame.event.get() or pygame.event.clear().

函数 pygame.event.pump() 是将所有事件放入事件队列的函数(它不会清除之前的事件,它只是添加).如果未调用该函数,则不会用任何事件填充/更新事件队列.但是,该函数在函数 pygame.event.get()pygame.event.clear()pygame.event.poll() 中被隐式调用pygame.event.wait()pygame.event.peek(),所以很少有理由显式调用它.如果你确定你不想在某个时候处理事件,你可以使用 pygame.event.clear() 这样当你再次开始处理事件时事件队列是空的.如果您根本不想处理事件,请使用 pygame.event.pump().

The function pygame.event.pump() is the function that put all events into the event queue (it doesn't clear the previous events, it just adds). The event queue won't be filled/updated with any events if the function isn't called. However, the function is implicitly called inside the functions pygame.event.get(), pygame.event.clear(), pygame.event.poll(), pygame.event.wait() and pygame.event.peek(), so there is rarely a reason to call it explicitly. If you are sure you don't want to handle events at some time, you could use pygame.event.clear() so the event queue is empty when you start processing events again. If you don't want to handle events at all, then use pygame.event.pump().

这篇关于Pygame 需要“for event in pygame.event.get()";为了不崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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