События мыши python pygame не работают и не вызывают ошибок

avatar
Matteo
7 мая 2021 в 15:25
136
2
3

Я новичок в python и пытаюсь создать игру в шахматы с помощью pygame, у меня есть шахматная доска и различные фигуры, размещенные на ней как объекты. Это класс штук:

class piece(object):
    def __init__(self, x, y, which):
        self.x = x
        self.y = y
        self.which = which
        self.square = getsquare(x + PIECE/2, y + PIECE/2)
        self.dragging = False

    def drag(self, x, y):
        limit = 720
        if x >= limit:
            x = limit
        self.x = x - PIECE/2
        self.y = y - PIECE/2
    def draw(self, win):
        win.blit(self.which, (self.x, self.y))
        self.square = getsquare(self.x + PIECE/2, self.y + PIECE/2)

где PIECE — размер спрайтов с изображениями частей. Я попытался создать систему перетаскивания для частей (хранящихся в длинном списке из 64 элементов), и с использованием только 1 части это сработало, но когда я использовал полный список, он перестал работать без каких-либо ошибок. Это система перетаскивания:

"""event listeners"""
for event in pygame.event.get():
    if event.type == pygame.QUIT: #quit event
        run = False
    """mouse release"""
    if event.type == pygame.MOUSEBUTTONUP:
        clickpos = pygame.mouse.get_pos()
        x = clickpos[0]
        y = clickpos[1]
        sqr = getsquare(x, y)
        for i in pieceslist:
            if not i == "none":
                if i.dragging:
                    i.dragging = False
                    try:
                        i.x = squarepos(i.square[0], i.square[1])[1]
                        i.y = squarepos(i.square[0], i.square[1])[0]
                    except:
                        i.x = squarepos(originalsquare[0], originalsquare[1])[1]
                        i.y = squarepos(originalsquare[0], originalsquare[1])[0]
    """mouse click"""
    if event.type == pygame.MOUSEBUTTONDOWN:
        clickpos = pygame.mouse.get_pos()
        x = clickpos[0]
        y = clickpos[1]
        #print("X: " + str(x) + ", Y: " + str(y))
        sqr = getsquare(x, y)
        for i in pieceslist:
            if not i == "none":
                if sqr == i.square:
                    originalsquare = sqr
                    i.dragging = True
    """mouse drag"""
    if event.type == pygame.MOUSEMOTION:
        clickpos = pygame.mouse.get_pos()
        x = clickpos[0]
        y = clickpos[1]
        #print("X: " + str(x) + ", Y: " + str(y))
        sqr = getsquare(x, y)
        for i in pieceslist:
            if not i == "none":
                if i.dragging:
                    i.drag(x, y)

поскольку pieceslist заполнен объектами piece и строками "none", я сделал проверку if (я знаю, что есть лучшие способы сделать это, но я новичок в python)

Итак, проблема в том, что событие click работает и изменяет dragging, но когда дело доходит до события перетаскивания, у объекта больше нет dragging == True

РЕДАКТИРОВАТЬ:

squarepos() возвращает координаты места размещения спрайт-листа, getsquare() возвращает координаты по строке-столбцу:

def getsquare(x, y):
    if x <= BORDER or y <= BORDER or x >= squarepos(1,  9)[0] or y >= squarepos(9, 1)[1]:
        pass #not on the board
    else:
        x -= BORDER
        y -= BORDER
        x /= SQUARE
        y /= SQUARE
        return [int(x) + 1, int(y) + 1]

РЕДАКТИРОВАТЬ:

Полная программа здесь для тестирования и отладки

Источник

Ответы (2)

avatar
Rabbid76
8 мая 2021 в 16:48
1

Алгоритм перетаскивания действительно работает. Однако defBoardPieces() вызывается в каждом кадре. Поэтому игра сбрасывается каждый кадр. И перетаскивание не имеет никакого эффекта.

Удалите вызов defBoardPieces() из функции drawBoardPieces, но вызовите его один раз перед циклом приложения:

#renders board pieces
def drawBoardPieces(win):

    # defBoardPieces()    <--- DELETE

    for i in pieceslist:
        if not i == "none":
            i.draw(win)
pieceslist = []
startsquare = []

defBoardPieces()    # <--- INSERT

run = True
while run:
    # [...]

Позвоните defBoardPieces() также в reset:

def reset():
    global position
    position = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
    defBoardPieces()

avatar
marienbad
7 мая 2021 в 21:37
0

Используйте mouse.get_pressed()[0] для перетаскивания. 0 — левая кнопка.

if event.type == pygame.MOUSEBUTTONDOWN:
    if pygame.mouse.get_pressed()[0]:
    ... drag code here