функция pygame запускается дважды - PullRequest
0 голосов
/ 07 апреля 2020

В настоящее время я делаю игру pacman и создал функцию, которая определяет, куда призрак должен перемещать каждое нажатие клавиши, чтобы приблизиться к игроку

from pygame.locals import *
import numpy

def distcalc(start, end):
    y_dist = start[0]-end[0]
    x_dist =  start[1]-end[1]
    total_dist = y_dist + x_dist
    if total_dist < 0:
        total_dist = -total_dist
    return total_dist

def sort(data):
    sorted_x = (sorted(data.items(), key=lambda kv: kv[1]))
    new_data = dict(sorted_x)
    return(new_data)


def pathfind(matrix, start, end):
    dict_ = {}
    start.reverse()
    end.reverse()
    children = [(start[0], start[1]-1), (start[0], start[1]+1), (start[0]-1, start[1]), (start[0]+1, start[1])]
    print(children)
    for item in reversed(children):
        if a[item] == 0:
            children.remove(item)
    for item in children:
        dict_[item] = distcalc(item, end)
    sorteddict= sort(dict_)
    print(sorteddict)
    coordinates = (list(sorteddict.keys()))
    move = coordinates[0]
    if move[0] > start[1]:
        print('down')
        return 'down'
    elif move[0] < start[1]:
        print('up')
        return 'up'
    elif move[1] < start[0]:
        print('left')
        return 'left'
    elif move[1] > start[0]:
        print('right')
        return 'right'


#constants representing colour
BLACK = (0, 0, 0 )
BROWN = (153, 76, 0 )
GREEN = (0, 255, 0 )
BLUE = (0, 0, 255)
WHITE = (255, 255, 255)

#constants representing the different resources
W = 0
P = 1
G = 2

#a dictionary linking resources to textures
textures = {
                W  : pygame.image.load('wall.png'),
                G  : pygame.image.load('path.png'),
                P  : pygame.image.load('path+pellet.png')
             }
level = 1

tilemap = [
    [W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W],
    [W, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, W],
    [W, P, W, W, W, P, W, W, W, P, P, W, P, W, P, W, W, W, P, W],
    [W, P, W, W, W, P, P, P, P, P, P, W, P, P, P, W, W, W, P, W],
    [W, P, W, W, W, P, W, W, W, P, P, W, W, W, P, W, W, W, P, W],
    [W, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, W],
    [W, W, W, W, W, P, W, W, W, W, W, W, W, W, P, W, W, W, W, W],
    [P, P, P, P, P, P, W, P, P, P, P, P, P, W, P, P, P, P, P, P],
    [W, W, W, W, W, P, W, W, W, P, P, W, W, W, P, W, W, W, W, W],
    [W, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, W],
    [W, P, W, W, P, W, P, W, P, W, W, W, W, P, W, P, W, W, P, W],
    [W, P, W, W, P, W, P, W, P, P, P, P, W, P, W, P, W, W, P, W],
    [W, P, W, W, P, W, P, W, W, W, W, P, W, P, W, P, W, W, P, W],
    [W, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, P, W],
    [W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W, W],
    ]
a = numpy.array(tilemap)
#useful game dimensions
TILESIZE = 40
MAPWIDTH = 20
MAPHEIGHT = 15

#set up the display
pygame.init()
DISPLAYSURF = pygame.display.set_mode((MAPWIDTH*TILESIZE,MAPHEIGHT*TILESIZE))

#the player image
PLAYER = pygame.image.load('pacman.png')
GHOST = pygame.image.load('ghost.png')
#the position of the player [x,y]
ghostPos = [7,7]
playerPos = [2,1]
while True:
    #get all the user events
    for event in pygame.event.get():
        #if the user wants to quit
        if event.type == QUIT:
            #end the game and close the window
            pygame.quit()
            sys.exit()
        #if a key is pressed
        elif event.type == KEYDOWN:
            if pathfind(a, ghostPos, playerPos) == 'left':
                ghostPos[0]-=1
            elif pathfind(a, ghostPos, playerPos) == 'right':
                ghostPos[0]+=1
            elif pathfind(a, ghostPos, playerPos) == 'up':
                ghostPos[1]-=1
            elif pathfind(a, ghostPos, playerPos) == 'down':
                ghostPos[0]+=1
            print(playerPos)
            print(ghostPos)
            #if the right arrow key is pressed
            if event.key == K_RIGHT:
                PLAYER = pygame.image.load('pacman.png')
                if playerPos[0] == 19 and playerPos[1] == 7:
                        playerPos = [-1,7]
                if tilemap[playerPos[1]][ playerPos[0]+1] == 2 or tilemap[playerPos[1]][ playerPos[0]+1] == 1:
                    if tilemap[playerPos[1]][ playerPos[0]] == 1:
                        tilemap[playerPos[1]][ playerPos[0]] = 2
                    playerPos[0] += 1


            #if the left arrow key is pressed
            if event.key == K_LEFT:
                PLAYER = pygame.image.load('pacmanL.png')
                if playerPos[0] == 0 and playerPos[1] == 7:
                        playerPos = [19,7]
                if tilemap[playerPos[1]][ playerPos[0]-1] == 2 or tilemap[playerPos[1]][ playerPos[0]-1] == 1:
                    if tilemap[playerPos[1]][ playerPos[0]] == 1:
                        tilemap[playerPos[1]][ playerPos[0]] = 2
                    playerPos[0] -= 1

            #if the up arrow key is pressed
            if event.key == K_UP:
                PLAYER = pygame.image.load('pacmanU.png')
                if tilemap[playerPos[1]-1][ playerPos[0]] == 2 or tilemap[playerPos[1]-1][ playerPos[0]] == 1:
                    if tilemap[playerPos[1]][ playerPos[0]] == 1:
                        tilemap[playerPos[1]][ playerPos[0]] = 2
                    playerPos[1] -= 1

            #if the down arrow key is pressed
            if event.key == K_DOWN:
                PLAYER = pygame.image.load('pacmanD.png')
                if tilemap[playerPos[1]+1][ playerPos[0]] == 2 or tilemap[playerPos[1]+1][ playerPos[0]] == 1:
                    if tilemap[playerPos[1]][ playerPos[0]] == 1:
                        tilemap[playerPos[1]][ playerPos[0]] = 2
                    playerPos[1] += 1


    # draw map by looping through each row then column
    for row in range(MAPHEIGHT):
        #loop through each column in the row
        for column in range(MAPWIDTH):
            # draw the resource at that position in the tilemap, using the correct image
            DISPLAYSURF.blit(textures[tilemap[row][column]], (column*TILESIZE,row*TILESIZE))

    # display the player at the correct position
    DISPLAYSURF.blit(PLAYER,(playerPos[0]*TILESIZE,playerPos[1]*TILESIZE))

    # displays the first ghost
    DISPLAYSURF.blit(GHOST, (ghostPos[0]*TILESIZE, ghostPos[0]*TILESIZE))





    #update the display
    pygame.display.update()

, однако каждая клавиша нажимает операторы печати. из функции поиска пути напечатайте дважды, и это то, что я получаю

{(7, 8): 12}
right
[(7, 6), (7, 8), (6, 7), (8, 7)]
{(7, 8): 12}
right
[2, 1]
[8, 7]

Я понимаю, что отсутствие комментариев может затруднить понимание кода, но я надеялся, что кто-то может определить, почему функция, кажется, запускается дважды, это называется в разделе KEYDOWN спасибо

1 Ответ

4 голосов
/ 07 апреля 2020

В этом разделе pathfind вызывается от 1 до 4 раз, в зависимости от результата:

            if pathfind(a, ghostPos, playerPos) == 'left':
                ghostPos[0]-=1
            elif pathfind(a, ghostPos, playerPos) == 'right':
                ghostPos[0]+=1
            elif pathfind(a, ghostPos, playerPos) == 'up':
                ghostPos[1]-=1
            elif pathfind(a, ghostPos, playerPos) == 'down':
                ghostPos[0]+=1`

Внутри метода pathfind () вы печатаете 'right', я полагаю, это то, что делает 'multicall. Попробуйте вызвать метод pathfind только один раз так:

direction = pathfind(...)
if direction == 'right':
  ...
elif direction == 'up':
  ...
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...