SecretSix
SecretSix

Reputation: 53

It keeps showing "TypeError: update() takes 1 positional argument but 2 were given"

I am trying to code a game with Python, but it keeps showing the error "TypeError: update() takes 1 positional argument but 2 were given". I have checked multiple forums including stackoverflow multiple times, but all of them were saying that the error occurs when we forget a 'self' argument. However, that is not my case.

Below, you can see my tiles.py file. It shows the Tile class.

import pygame
class Tile(pygame.sprite.Sprite):
    def __init__(self,pos,size):
        super().__init__()
        self.image = pygame.Surface((size,size))
        self.image.fill('grey')
        self.rect = self.image.get_rect(topleft = pos)
    def update(self,x_shift):
        self.rect.x += x_shift

As you can see, both the __init__() and the update() functions has the self argument. When I run the update part in level.py:

import pygame
from tiles import Tile
from settings import tile_size
from player import Player

class Level:
    def __init__(self,level_data,surface):
        self.display_surface = surface
        self.setup_level(level_data)
        self.world_shift = 0
    def setup_level(self,layout):
        self.tiles = pygame.sprite.Group()
        self.player = pygame.sprite.GroupSingle()
        for row_index,row in enumerate(layout):
            for col_index,cell in enumerate(row):
                x = col_index * tile_size
                y = row_index * tile_size
                if cell == 'X':
                    tile = Tile((x,y),tile_size)
                    self.tiles.add(tile)
                if cell == 'P':
                    player_sprite = Player((x,y))
                    self.tiles.add(player_sprite)
    def run(self):
        #level tiles
        self.tiles.update(self.world_shift)
        self.tiles.draw(self.display_surface)
        #player
        self.player.update()
        self.player.draw(self.display_surface)

The run function's self.tiles.update(self.world_shift), as you can see, also has an argument in it, which is the x_shift argument. However, when I run the run function in my main.py file:

import pygame, sys
from settings import *
from level import Level

#Setup
pygame.init()
screen = pygame.display.set_mode((screen_width,screen_height))
clock = pygame.time.Clock()
level = Level(level_map,screen)
pygame.display.set_caption('Pirates Run')

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
    
    screen.fill('black')
    level.run()

    pygame.display.update()
    clock.tick(60)

When I have run the code, the only output I get is a black screen that appears for less than a second and then closes, and then an error that looks like this:

Traceback (most recent call last):
File "c:\Users\User\OneDrive\Desktop\Blazel\Pirates Run\code\main.py", line 19, in <module>
level.run()
File "c:\Users\User\OneDrive\Desktop\Blazel\Pirates Run\code\level.py", line 26, in run    
self.tiles.update(self.world_shift)
File "C:\Users\User\AppData\Local\Programs\Python\Python39\lib\site- 
packages\pygame\sprite.py", line 531, in update
sprite.update(*args, **kwargs)
TypeError: update() takes 1 positional argument but 2 were given

Please help me solve this problem! Thanks!

Upvotes: 0

Views: 1921

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

First some basics:

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. [...]


You add player_sprite to the self.tiles Group.

self.tiles.add(player_sprite)

The Tile object has an update methode:

def update(self,x_shift):

The Player object has an update method with a different argument list. This causes the error. Do not add player_sprite to tiles, but create a separate Group for the player to solve the issue (e.g. pygame.sprite.GroupSingle).

Upvotes: 1

Related Questions