为什么 pygame 键盘事件不会发生?

Why won't a pygame keyboard event take place?

我想让对象在按下上键盘时跳起来。但是这个错误老是弹出,并没有work.It是列表中存储的照片随时间变化,按下上键盘时跳转的配置

Traceback (most recent call last):
  File "C:/osp_git/T01/RUN/Run.py", line 123, in main
    all_sprites.update(mt)
  File "C:\Users\AppData\Local\Programs\Python\Python36\lib\site-packages\pygame\sprite.py", line 531, in update
    sprite.update(*args, **kwargs)
  File "C:/osp_git/T01/RUN/Run.py", line 58, in update
    if userInput[pygame.K_UP] and not self.SM_jump:
TypeError: 'float' object is not subscriptable

def update()发生错误。

这个更新函数是接收键盘输入的函数,跳转函数是跳转的函数

这是我的完整代码。

import pygame

pygame.init()

SCREEN_H = 560
SCREEN_W = 1000
SCREEN = pygame.display.set_mode((SCREEN_W,SCREEN_H))

BG01 = pygame.image.load("IMG/background.jpg")
BG02 = BG01.copy()

clock = pygame.time.Clock()


class MeltingSnowman(pygame.sprite.Sprite):
    SnowMan_X = 80
    SnowMan_Y = 419
    position = (SnowMan_X, SnowMan_Y)
    JUMP_VEL = 8

    def __init__(self, position):

        SnowMan_X = 80
        SnowMan_Y = 419
        position = (SnowMan_X, SnowMan_Y)

        self.SM_jump = False
        self.walk_index = 0
        self.jump_vel = self.JUMP_VEL

        super(MeltingSnowman, self).__init__()
        size = (100, 100)

        images = [(pygame.image.load('IMG/DinoRun1.png')),
                  (pygame.image.load('IMG/DinoRun2.png')),
                  (pygame.image.load('IMG/DinoJump.png')),
                  (pygame.image.load('IMG/DinoDuck1.png')),
                  (pygame.image.load('IMG/DinoDuck2.png'))]

        self.rect = pygame.Rect(position, size)
        self.rect.x = self.SnowMan_X
        self.rect.y = self.SnowMan_Y
        self.images = [pygame.transform.scale(image, size) for image in images]

        self.index = 0
        self.image = images[self.index]

        self.animation_time = 1
        self.current_time = 0

    def update(self, userInput):
        if self.SM_jump:
            self.jump()

        if self.walk_index >= 10:
            self.walk_index = 0

        if userInput[pygame.K_UP] and not self.SM_jump:
            self.SM_jump = True
        elif userInput[pygame.K_DOWN] and not self.SM_jump:
            self.SM_jump = False
        elif not (self.SM_jump or userInput[pygame.K_DOWN]):
            self.SM_jump = False

    def jump(self):
        self.image = self.images[self.index]
        if self.SM_jump:
            self.rect.y -= self.jump_vel * 4
            self.jump_vel -= 1
            MeltingSnowman.SnowMan_Y = 100

        if self.jump_vel < - 8:
            self.SM_jump = False
            self.jump_vel = self.JUMP_VEL
            MeltingSnowman.SnowMan_Y = 400


    def run(self, mt):
        self.current_time += mt

        if self.current_time >= self.animation_time:
            self.current_time = 0

            self.index += 1
            if self.index == len(self.images):
                GameOver()
                pygame.display.flip()
                pygame.time.delay(2000)
                pygame.quit()
                exit()

            self.image = self.images[min(self.index, len(self.images) - 1)]


    def draw(self, SCREEN):
        SCREEN.blit(self.image, (self.rect.x, self.rect.y))

def GameOver():
    font = pygame.font.Font('NanumGothic.ttf', 30)
    GAMEOVER = font.render("GAME OVER", True, (255,255,255))
    SCREEN.blit(GAMEOVER, (400, 250))

def Background(BG, x, y):
    global SCREEN, BG01
    SCREEN.blit(BG01, (x, y))

def main():

    player = MeltingSnowman(position=(80, 419))
    all_sprites = pygame.sprite.Group(player)

    BG01_x = 0
    BG02_x = SCREEN_W

    run = True
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

        mt = clock.tick(100) / 1000

        all_sprites.update(mt)
        all_sprites.draw(SCREEN)
        pygame.display.update()

        BG01_x -= 4; BG02_x -= 4

        if BG01_x == -SCREEN_W:
            BG01_x = SCREEN_W
        if BG02_x == -SCREEN_W:
            BG02_x = SCREEN_W

        Background(BG01, BG01_x, 0)
        Background(BG02, BG02_x, 0)

        clock.tick(30)

您调用 all_sprites.update(mt)。因此 update 的实参是 mt.

您必须将 pygame.key.get_pressed 的 return 值传递给 update:

keys = pygame.key.get_pressed()
all_sprites.update(keys)

注意,如果你有不同的 Sprite 类 和不同的 Update 方法,你必须将精灵放在不同的 Groups 并在每个 Group 上分别调用 update。或者,您需要确保每个 update 方法具有相同的参数,或者您需要使用关键字参数。


pygame.sprite.Group.draw() and pygame.sprite.Group.update()pygame.sprite.Group.

提供的方法

后者委托给包含的pygame.sprite.Sprites — you have to implement the method. See pygame.sprite.Group.update()update方法:

Calls the update() method on all Sprites in the Group. [...]

前者使用包含的 pygame.sprite.Spriteimagerect 属性来绘制对象 - 你必须确保 pygame.sprite.Sprite 具有所需的属性。见 pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]