这个基本的pygame结构怎么样?

4 投票
6 回答
6402 浏览
提问于 2025-04-15 14:16

这是我现在实现简单pygame的方式:

import pygame, sys
from pygame.locals import *

def run_game():
    pygame.init()

    SIZE = (640, 400)
    BG_COLOUR = (0, 0, 0)
    LINE_COLOUR = (255, 255, 255)

    screen = pygame.display.set_mode(SIZE)
    clock = pygame.time.Clock()

    while True:
        time_passed = clock.tick(30)
        for event in pygame.event.get():
                if event.type == QUIT:
                        exit_game()

        screen.fill(BG_COLOUR)
        pygame.draw.aaline(screen, LINE_COLOUR, (1, 1), (639, 399))
        pygame.display.flip()

def exit_game():
    sys.exit()

if __name__ == "__main__"
    run_game()

我还看到有人使用一个叫keeprunning的标志来退出主事件循环,另外也有人用pygame.event.poll()来代替循环使用pygame.event.get()。你有什么建议吗,比如变量的命名方式,或者其他让代码更有效或更易读的方法?

6 个回答

2

pygame.Color() 这个类用起来很方便:

from pygame import Color

# example: text is 20% gray. gray100 = (255,255,255)
text_fg = Color('gray20')
text_bg = Color('gray80')

# many names are defined
Color("red")

# rgb, rgba
Color(100, 100, 100)
Color(100, 100, 100, 20)

#hex
Color("fefefe")
Color("fefefe00")
3

你的例子非常好。 但是如果你想看看“pygame.event.poll()”是怎么工作的,可以看看这个简单的例子:

event = pygame.event.poll()
    while "ok":
        event = pygame.event.wait()
        cursor = pygame.mouse.get_pos()
        if event.type == QUIT:  raise SystemExit
            if event.type == MOUSEBUTTONUP and pygame.mouse.get_pressed()[0]:
               print "up"
        if event.type == MOUSEBUTTONDOWN and pygame.mouse.get_pressed()[0]:
               print "down"
        if event.type == KEYDOWN and event.key == K_SPACE: print "space key"
        if event.type == KEYDOWN and event.key == K_BACKSPACE:
               print "backspace key"

你可以使用pygame中的所有事件:

  • pygame.event.get - 从事件队列中获取所有事件
  • pygame.event.poll - 从事件队列中获取一个单独的事件
  • pygame.event.wait - 等待从事件队列中获取一个单独的事件

或者

  • pygame.event.clear([pygame.QUIT, pygame.ACTIVEEVENT, pygame.KEYDOWN, pygame.KEYUP, pygame.MOUSEMOTION, pygame.JOYBUTTONUP, pygame.USEREVENT]) 来清除事件队列中的所有事件

基本上,你为这些事件创建函数并使用它们。就像这样:

def click_down():
    #print "Event queue:", pygame.event.peek()
    return pygame.event.peek(pygame.MOUSEBUTTONDOWN)

def is_click():
    if not click_down():
        return None

    clicks = pygame.event.get(pygame.MOUSEBUTTONDOWN)
    pygame.event.get(pygame.MOUSEBUTTONUP)
    return clicks[0].pos
def quiting():
    return pygame.event.peek(pygame.QUIT)
def keyboard():
    pygame.event.pump()
    pygame.event.get(pygame.KEYDOWN)

或者阻止某些事件,比如:

pygame.event.set_blocked((pygame.JOYAXISMOTION))
12

不管pygame的作者推荐什么,我建议你不要使用from ... import *这种写法:这样会让你的代码更难读,因为读的人需要检查每一个名字,看看它是本地定义的还是来自那个烦人的*。你可以改成import pygame.locals as pygl,然后每次用到的名字都加上前缀(在你的代码中,这意味着把QUIT改成pygl.QUIT)。你选择的短名字其实不太重要,但我强烈推荐这种结构。记住:命名空间是个很棒的主意——我们应该多用!-)

到处都用4个空格的缩进,正如PEP 8所说:你似乎在混用4个空格和其他8个空格或制表符——不要这样做!

不要给那些你根本不会用到的变量赋值,就像你对time_passed所做的那样。

像这样写代码:

if event.type == QUIT:
    exit_game()

在你只测试一个或几个可能性的时候是可以的(用if/elif),但在可读性和效率上都不太好。当你需要处理多个情况时,最好在循环之前用一个字典来设置:

dispatch = {pygl.QUIT: exit_game, # whatever else
           }

然后用:

f = dispatch.get(event.type)
if f is None:  # the "else" case"
   ...
else: f()

撰写回答