Akliph
Akliph

Reputation: 25

only last iteration of list in for loop takes effect when in while loop [Python, Pygame] for pacman game, how do i fix this?

Trying to make imported csv of rects in pygame iterate through a list of tuples in a for loop, in main game loop, in order to add collision with the rects in the list. Only the last rect in the list has collision meaning that only the last tuple's parameters are taken into account in the game loop.

    while gameExit == False:
    for event in pygame.event.get():
        if event.type == QUIT:
            gameExit = True
        #Gets keypresses and moves the player accordingly
        if event.type == pygame.KEYDOWN:
            #print(str(event.key))
            if event.key == pygame.K_LEFT:
                xChange = -playersize/2
                yChange = 0
                #print(str(x)+", "+str(y))
            elif event.key == pygame.K_RIGHT:
                xChange = playersize/2
                yChange = 0
                #print(str(x)+", "+str(y))
            elif event.key == pygame.K_UP:
                yChange = -playersize/2
                xChange = 0
                #print(str(x)+", "+str(y))
            elif event.key == pygame.K_DOWN:
                yChange = playersize/2
                xChange = 0
        """
        #Make player stop moving after keyup
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT or pygame.K_RIGHT:
                xChange = 0
            if event.key == pygame.K_UP or pygame.K_DOWN:
                yChange = 0
        """
    #if player goes out of bounds then move them to the other side of the screen
    if pacX > width or pacX < 0 or pacY > height or pacY < 0: 
        if pacX > width: pacX = 0
        if pacX < 0: pacX = width - playersize
        if pacY > height: pacY = 0
        if pacY < 0: pacY = height - playersize

    #is the movement selected going to intersect with a boundary?
    #THIS IS THE FOR LOOP REFERENCED ABOVE

        for coord in xy:
            x = float(coord[0])
            y = float(coord[1])
            rectwidth = float(coord[2])
            rectheight = float(coord[3])

            if pacX+xChange > round(x-playersize) and pacX+xChange < round(x+rectwidth) and pacY+yChange > round(y-playersize) and pacY+yChange < round(y+rectheight):
                touching = True
            else:
                touching = False


    #if not touching a boundary then allow move

    if not touching:
        pacX += xChange
        pacY += yChange
    elif touching == True:
        pass
        #print("Sorry, that's out of bounds...")



    #draw everything on the display
    DISPLAY.fill(grey)
    pygame.draw.rect(DISPLAY,yellow,[pacX,pacY,playersize,playersize])
    buildlevel(xy,DISPLAY,darkBlue)
    pygame.display.update()
    clock.tick(fps)

pygame.quit()
sys.exit()

CSV FILE: (Each of these are the coordinate and dimensions parameters for the pygame.draw.rect() method in pygame. Each row is stored as one tuple in the xy list.)


100 100 100 100
200 200 100 100
300 300 100 100
300 300 100 100
400 400 100 100

Upvotes: 0

Views: 147

Answers (1)

MegaIng
MegaIng

Reputation: 7886

If we reduce your example to pseudo-(python)-code, it looks something like this:

for block in blocks:
    if collide(player, block):
        touching = True
    else:
        touching = False

If you now step trough this, either in your mind or with a debugger, you realize the touching gets set every time the loop-body executes, overwriting the previous value. To fix this, only set touching = True in the loop body.

for block in blocks:
    if collide(player, block):
        touching = True

But now touching might have not been initialized. This can be fixed by setting touching = False before the loop:

touching = False
for block in blocks:
    if collide(player, block):
        touching = True

Upvotes: 1

Related Questions