0

I've been trying to follow this tutorial to include a coin in the game loot_1.png but when I get to the tutorial part that says ...Add the final line from the following code sample to your loop: and i try to compile my game.py file, the code breaks with the following error in my terminal:

    #python game.py
    pygame 1.9.6
    Hello from the pygame community. https://www.pygame.org/contribute.html
    run0(0, 528, 3)
    run1(300, 400, 3)
    run2(500, 528, 4)
    Traceback (most recent call last):
      File "game.py", line 252, in <module>
        loot_list = Level.loot(1,tx,ty)
    TypeError: loot() takes 2 positional arguments but 3 were given

I tried to find a solution by looking at the questions but without success: write() takes 2 positional arguments but 3 were given, TypeError: fit_transform() takes 2 positional arguments but 3 were given, TypeError: hook() takes 2 positional arguments but 3 were given, Pygame TypeError: update() takes 1 positional argument but 2 were given.

game.py

import pygame
import sys
import os

'''
Objects
'''

class Platform(pygame.sprite.Sprite):
    # x location, y location, img width, img height, img file    
    def __init__(self,xloc,yloc,imgw,imgh,img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images',img)).convert()
        self.image.convert_alpha()
        self.rect = self.image.get_rect()
        self.rect.y = yloc
        self.rect.x = xloc

class Player(pygame.sprite.Sprite):
    '''
    Spawn a player
    '''

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.movex = 0
        self.movey = 0
        self.frame = 0
        self.health = 10
        # gravity variables here
        self.collide_delta = 0
        self.jump_delta = 6
        self.score = 1
        self.images = []
        for i in range(1,9):
            img = pygame.image.load(os.path.join('images','spr' + str(i) + '.png')).convert()
            img.convert_alpha()
            img.set_colorkey(ALPHA)
            self.images.append(img)
            self.image = self.images[0]
            self.rect  = self.image.get_rect()
    def jump(self,platform_list):
        self.jump_delta = 0
    def gravity(self):
        self.movey += 3.2  # how fast player falls

        if self.movey >= 15:
            self.movey = 6

        if self.rect.bottom > worldy and self.movey >= 0: # <-- uses bottom
           self.movey = 0
           self.rect.bottom = worldy # <-- uses bottom
    def control(self,x,y):
        '''
        control player movement
        '''
        self.movex += x
        self.movey += y

    def update(self):
        '''
        Update sprite position
        '''
        plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
        for p in plat_hit_list:
            self.collide_delta = 0 # stop jumping
            self.movey = 0

            if self.rect.y > p.rect.y:
                self.rect.y = p.rect.y+ty
            else:
                self.rect.y = p.rect.y-ty
        if self.collide_delta < 6 and self.jump_delta < 6:
            self.jump_delta = 6*2
            self.movey -= 33  # how high to jump
            self.collide_delta += 6
            self.jump_delta    += 6

        self.rect.x = self.rect.x + self.movex
        self.rect.y = self.rect.y + self.movey

        # moving left
        if self.movex < 0:
            self.frame += 1
            if self.frame > ani*3:
                self.frame = 0
            self.image = self.images[self.frame//ani]

        # moving right
        if self.movex > 0:
            self.frame += 1
            if self.frame > ani*3:
                self.frame = 0
            self.image = self.images[(self.frame//ani)+4]

        # collisions
        enemy_hit_list = pygame.sprite.spritecollide(self, enemy_list, False)
        for enemy in enemy_hit_list:
            self.health -= 1
            print(self.health)

        plat_hit_list = pygame.sprite.spritecollide(self, plat_list, False)
        for p in plat_hit_list:
            self.rect.bottom = p.rect.top
            self.collide_delta = 0 # <----- this is missing

        ground_hit_list = pygame.sprite.spritecollide(self, ground_list, False)
        for g in ground_hit_list:
            self.movey = 0
            self.rect.y = worldy-ty-ty
            self.collide_delta = 0 # stop jumping
            if self.rect.y > g.rect.y:
               self.health -= 1
               print(self.health)


class Enemy(pygame.sprite.Sprite):
    '''
    Spawn an enemy
    '''
    def __init__(self,x,y,img):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load(os.path.join('images',img))
        #self.image.convert_alpha()
        #self.image.set_colorkey(ALPHA)
        self.rect = self.image.get_rect()
        self.rect.x = x
        self.rect.y = y
        self.counter = 0

    def move(self):
        '''
        enemy movement
        '''
        distance = 80
        speed = 8

        if self.counter >= 0 and self.counter <= distance:
            self.rect.x += speed
        elif self.counter >= distance and self.counter <= distance*2:
            self.rect.x -= speed
        else:
            self.counter = 0

        self.counter += 1

class Level():
    def bad(lvl,eloc):
        if lvl == 1:
            enemy = Enemy(eloc[0],eloc[1],'yeti.png') # spawn enemy
            enemy_list = pygame.sprite.Group() # create enemy group
            enemy_list.add(enemy)              # add enemy to group

        if lvl == 2:
            print("Level " + str(lvl) )

        return enemy_list

        def loot(lvl,lloc):
            if lvl == 1:
                loot_list = pygame.sprite.Group()
                loot = Platform(300,ty*7,tx,ty, 'loot_1.png')
                loot_list.add(loot)

            if lvl == 2:
                print(lvl)

        return loot_list

    def loot(lvl,lloc):
        print(lvl)

    def ground(lvl,gloc,tx,ty):
        ground_list = pygame.sprite.Group()
        i=0
        if lvl == 1:
            while i < len(gloc):
                ground = Platform(gloc[i],worldy-ty,tx,ty,'ground.png')
                ground_list.add(ground)
                i=i+1

        if lvl == 2:
            print("Level " + str(lvl) )

        return ground_list

    def platform(lvl,tx,ty):
        plat_list = pygame.sprite.Group()
        ploc = []
        i=0
        if lvl == 1:
            ploc.append((0,worldy-ty-128,3))
            ploc.append((300,worldy-ty-256,3))
            ploc.append((500,worldy-ty-128,4))

            while i < len(ploc):
                j=0
                while j <= ploc[i][2]:
                    plat = Platform((ploc[i][0]+(j*tx)),ploc[i][1],tx,ty,'ground.png')
                    plat_list.add(plat)
                    j=j+1
                print('run' + str(i) + str(ploc[i]))
                i=i+1

        if lvl == 2:
            print("Level " + str(lvl) )

        return plat_list
'''
Setup
'''
worldx = 760
worldy = 720

fps = 40 # frame rate
ani = 4  # animation cycles
clock = pygame.time.Clock()
pygame.init()
main = True

BLUE  = (25,25,200)
BLACK = (23,23,23 )
WHITE = (254,254,254)
ALPHA = (0,255,0)

world = pygame.display.set_mode([worldx,worldy])
backdrop = pygame.image.load(os.path.join('images','stage.png')).convert()
backdropbox = world.get_rect()
player = Player() # spawn player
player.rect.x = 0
player.rect.y = 0
player_list = pygame.sprite.Group()
player_list.add(player)
steps = 10 # how fast to move
forwardx  = 600
backwardx = 230
eloc = []
eloc = [200,20]
gloc = []
#gloc = [0,630,64,630,128,630,192,630,256,630,320,630,384,630]
tx = 64 #tile size
ty = 64 #tile size

i=0
while i <= (worldx/tx)+tx:
    gloc.append(i*tx)
    i=i+1

enemy_list = Level.bad( 1, eloc )
ground_list = Level.ground( 1,gloc,tx,ty )
plat_list = Level.platform( 1,tx,ty )
loot_list = Level.loot(1,tx,ty)

'''
Main loop
'''
while main == True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit(); sys.exit()
            main = False

        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                print("LEFT")
                player.control(-steps,0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                print("RIGHT")
                player.control(steps,0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                print('jump')

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or event.key == ord('a'):
                player.control(steps,0)
            if event.key == pygame.K_RIGHT or event.key == ord('d'):
                player.control(-steps,0)
            if event.key == pygame.K_UP or event.key == ord('w'):
                player.jump(plat_list)

            if event.key == ord('q'):
                pygame.quit()
                sys.exit()
                main = False


        # scroll the world forward
        if player.rect.x >= forwardx:
                scroll = player.rect.x - forwardx
                player.rect.x = forwardx
                for p in plat_list:
                        p.rect.x -= scroll
                for e in enemy_list:
                    e.rect.x -= scroll

        # scroll the world backward
        if player.rect.x <= backwardx:
                scroll = backwardx - player.rect.x
                player.rect.x = backwardx
                for p in plat_list:
                        p.rect.x += scroll

        ## scrolling code above
    world.blit(backdrop, backdropbox)
    player.gravity() # check gravity
    player.update()
    player_list.draw(world)
    enemy_list.draw(world)
    ground_list.draw(world)
    plat_list.draw(world)
    loot_list.draw(world)
    for e in enemy_list:
        e.move()
    pygame.display.flip()
    clock.tick(fps)

content folder images:

For enemy (sprit) is yeti.png: https://i.stack.imgur.com/oXLko.jpg

For background is stage.png: https://i.stack.imgur.com/Tmyok.jpg

and the image of the player:

spr.png: https://i.stack.imgur.com/mGsb3.jpg

and the image of the loot_1.png:

https://opengameart.org/sites/default/files/loot_goldcoins_big.png

7beggars_nnnnm
  • 697
  • 3
  • 12

1 Answers1

2

This appears to be an error in the tutorial itself.

In the previous part (the one about adding loot), they post this as the loot method:

def loot(lvl,lloc):
    if lvl == 1:
        loot_list = pygame.sprite.Group()
        loot = Platform(300,ty*7,tx,ty, 'loot_1.png')
        loot_list.add(loot)

    if lvl == 2:
        print(lvl)

    return loot_list

This method takes 2 arguments (lvl and lloc), which you have included in your code (although twice for some reason, and not indented correctly).

Later on in that same part, as well as the part you linked, the same method is found in the "all the code you've written so far" code dump:

class Level():
    ...

    def loot(lvl,tx,ty):
        if lvl == 1:
            loot_list = pygame.sprite.Group()
            loot = Platform(200,ty*7,tx,ty, 'loot_1.png')
            loot_list.add(loot)

        if lvl == 2:
            print(lvl)

        return loot_list

Now, the method takes 3 arguments (lvl, tx, and ty). Based on the contents of the two definitions, and the fact that they are the same between them, I believe the second version is correct (def loot(lvl, tx, ty):...).

Finally, to answer the question, the error you're getting is coming from this discrepancy - you implemented the (incorrect) 2-argument version, while the rest of the tutorial code is expecting the 3-argument version.

b_c
  • 1,202
  • 13
  • 24
  • ThankXD! To deal with my almost complete ignorance in python, I am using the code from the previous tutorial (with fixes implemented) and if necessary also using the full code at the bottom of the current tutorial page. So I think for lack of attention I have mixed and repeated parts of one code or another in my current code. – 7beggars_nnnnm Jan 15 '20 at 22:52