Using object outside of function

Viewed 62

How can I use the player object, that was created in the first function so I can call player.movePlayer() in the second function? It always tells me "name "player" is not defined"

def drawLevel(level):
    global gameDrawn
    x = y = 0

    

    walls = []

    ends = []

    players = []
    if gameDrawn == False:
        screen.fill(WOODY)
        drawGrid()
        drawRect()
        for row in levels[level]:
            for col in row:
                if col == "W":
                    wall = Wall((x, y))
                    walls.append(wall)
                if col == "E":
                    end = End((x, y))
                    ends.append(end)
                if col == "P":
                    player = Player((x,y))
                    players.append(player)
                x += 80
            y += 80
            x = 0
        for wall in walls:
            pygame.draw.rect(screen, BLACK, wall.rect)
        for end in ends:
            pygame.draw.rect(screen, RED, end.rect)
        for player in players:
            pygame.draw.rect(screen, BLUE, player.rect)
    gameDrawn = True
    #elif gameDrawn == True:
        #for event in pygame.event.get():
            #if event.type == pygame.USEREVENT: 
                #drawTimer(counter)
                #counter -= 1  
    return players
    return walls
    return ends
def main_loop_state_running():
    global level
    players = drawLevel(level)

    for event in pygame.event.get():
        for i in range(len(move_list)):
            player.movePlayer()

If you need to see it, this is my player class:

class Player(object):
    def __init__(self, pos):
        
        self.rect = pygame.Rect(pos[0], pos[1], pxl(1), pxl(1))

    #def move(dx, dy):
        # Bewegung für x und y. Kollision wird überprüft
        #if dx != 0:
            #wallCollisionDetection((dx, 0))
        #if dy != 0:
            #wallCollisionDetection(0, dy)

    def move(self, dx, dy):
        walls = drawLevel(level)
        # Den Spieler bewegen
        self.rect.x += dx
        self.rect.y += dy

        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0:  
                    self.rect.right = wall.rect.left
                if dx < 0:  
                    self.rect.left = wall.rect.right
                if dy > 0:  
                    self.rect.bottom = wall.rect.top
                if dy < 0:  
                    self.rect.top = wall.rect.bottom

    def movePlayer(self):
        for i in range(len(move_list)):
            if move_list[i] == 1:
               self.move(pxl(0), pxl(-1))
            elif move_list[i] == 2:
                self.move(pxl(0), pxl(1))
            elif move_list[i] == 3:
                self.move(pxl(1), pxl(0))
            elif move_list[i] == 4:
                self.move(pxl(-1), pxl(0))

The function movePlayer() should move the player rectangle based on which element is in the list at that moment

2 Answers

First: at the end of your function, you have:

    return players
    return walls
    return ends

This won't work, because after the first return, the function is done. You can return all three lists by doing:

    return players, walls, ends

When you call this function, you would then assign all three variables like this:

    players, walls, ends = drawLevel(level)

If you only need to use one variable, a standard convention is to assign the ones you don't need to _:

    players, _, _ = drawLevel(level)

To get the individual Player objects out of the players list, you need to iterate over it. Instead of:

player.movePlayer()

do:

for player in players:
    player.MovePlayer()

Your issue is in the return statement of the drawLevel method.

Change the return statement in drawLevel to

def drawLevel(level):
    # previous code
    return (player, walls, end)

Edit the main_loop_state_running method to

def main_loop_state_running()
    global level
    player, walls, end = drawLevel(level)
    # interact with player
Related