Why won't a pygame keyboard event take place?

Viewed 31

I want to make the object jump when it presses the upper keyboard. But this error keeps popping up and it doesn't work.It is a configuration in which the photos stored in the list change over time and jump when you press the upper keyboard.

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

The error occurs in def update().

This update function is a function of receiving keyboard input, and jump function is a function of jumping.

This is my full code.

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)
1 Answers

You invoke all_sprites.update(mt). Therefore the actual argument of update is mt.

You have to pass the return value of pygame.key.get_pressed to update:

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

Note, if you have different Sprite classes with different Update methods, you have to put the sprites in different Groups and invoke update on each Group individually. Alternatively, you need to make sure that each update method has the same parameters, or you need to use keyword arguments.


pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.

The latter delegates to the update method of the contained pygame.sprite.Sprites — you have to implement the method. See pygame.sprite.Group.update():

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

The former uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects — you have to ensure that the pygame.sprite.Sprites have the required attributes. See 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. [...]

Related