Ошибка при удалении объекта Ursina

Пытаюсь написать шахматы, используя движок Ursina. При этом фигуры создаю на основе класса Draggable:

class Piece(Draggable):
    def __init__(self, board, team):
        self.board = board
        self.team = team
        super().__init__(
        ...

При этом помещая их в массив, созданный при инициализации доски self.board

class Board(Entity):
    def __init__(self):
        super().__init__(
            parent=camera.ui,
            model='quad',
            texture=load_texture('assets/Board.png'),
            origin=(-3.5 / 8, -3.5 / 8),
            position=(-3.5 / 8, -3.5 / 8)
        )
        self.board = []
        for i in range(64):
            self.board.append(None)

    def change(self, square, piece):
        if self.board[square] is not None:
            destroy(self.board[square])
        self.board[square] = piece
        if piece is not None:
            piece.position = ((square % 8) / 8, (square // 8) / 8)

используя метод change().

При этом этой же функцией пытаюсь реализовать перемещение и взятие фигур. Последнее требует очистить из массива новую клетку, и поместить туда новую фигуру. В самом массиве это прекрасно работает (проверил дебагом), однако прежняя фигура остается на доске вне масива и фигура как бы ставится на фигуру. При попытке исправить, пытаясь ее просто удалить функцией destroy(entity, delay=0), происходит ошибка: ошибка при перетаскивании фигуры


Ответы (1 шт):

Автор решения: Данил Егорин

Извините, если начали думать над проблемой. Проблема заключалась в непредставленной мной функции перемещения фигуры:

self.board.change(int(round(self.old_y * 8)) * 8 + int(round(self.old_x * 8)), None)
self.board.change(int(round(self.y * 8)) * 8 + int(round(self.x * 8)), self)

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

Раз уж создал вопрос, оставлю свою реализацию, вдруг кому пригодится:

from ursina import *

white = 'w'
black = 'b'


class State:
    def __init__(self, board):
        self.wtm = True
        self.board = board
        self.new()

    def new(self):
        self.board.add(0 + 0, Rook(self.board, white)), self.board.add(8 * 7 + 0, Rook(self.board, black))
        self.board.add(0 + 1, Knight(self.board, white)), self.board.add(8 * 7 + 1, Knight(self.board, black))
        self.board.add(0 + 2, Bishop(self.board, white)), self.board.add(8 * 7 + 2, Bishop(self.board, black))
        self.board.add(0 + 3, Queen(self.board, white)), self.board.add(8 * 7 + 3, Queen(self.board, black))
        self.board.add(0 + 4, King(self.board, white)), self.board.add(8 * 7 + 4, King(self.board, black))
        self.board.add(0 + 5, Bishop(self.board, white)), self.board.add(8 * 7 + 5, Bishop(self.board, black))
        self.board.add(0 + 6, Knight(self.board, white)), self.board.add(8 * 7 + 6, Knight(self.board, black))
        self.board.add(0 + 7, Rook(self.board, white)), self.board.add(8 * 7 + 7, Rook(self.board, black))
        for i in range(8):
            self.board.add(8 + i, Pawn(self.board, white))
            self.board.add(8 * 6 + i, Pawn(self.board, black))


class Board(Entity):
    def __init__(self):
        super().__init__(
            parent=camera.ui,
            model='quad',
            texture=load_texture('assets/Board.png'),
            origin=(-3.5 / 8, -3.5 / 8),
            position=(-3.5 / 8, -3.5 / 8)
        )
        self.board = []
        for i in range(64):
            self.board.append(None)

    def add(self, square, piece):
        self.board[square] = piece
        if piece is not None:
            piece.position = ((square % 8) / 8, (square // 8) / 8)

    def move(self, square1, square2):
        if self.board[square2] is not None:
            destroy(self.board[square2])
            self.board[square2] = None
        self.board[square1].position = ((square2 % 8) / 8, (square2 // 8) / 8)
        self.board[square2] = self.board[square1]
        self.board[square1] = None


class Piece(Draggable):
    def __init__(self, board, team):
        self.board = board
        self.team = team
        super().__init__(
            parent=self.board,
            scale=(1 / 8),
            color=rgb(0, 0, 0, 0),
            highlight_scale=1.05
        )
        self.old_x = 0
        self.old_y = 0

    def drag(self):
        self.old_x = self.x
        self.old_y = self.y

    def drop(self):
        if self.x < -0.5 / 8 or self.x > 7.5 / 8 or self.y < -0.5 / 8 or self.y > 7.5 / 8:
            self.x = self.old_x
            self.y = self.old_y
        elif (int(round(self.old_y * 8)) * 8 + int(round(self.old_x * 8))) == (
                int(round(self.y * 8)) * 8 + int(round(self.x * 8))):
            self.x = self.old_x
            self.y = self.old_y
        else:
            self.board.move(
                int(round(self.old_y * 8)) * 8 + int(round(self.old_x * 8)),
                int(round(self.y * 8)) * 8 + int(round(self.x * 8)),
            )


class Pawn(Piece):
    def __init__(self, board, team):
        super().__init__(
            board=board,
            team=team,
        )
        self.icon = 'assets/' + self.team + 'P'
        self.tooltip = Tooltip('Pawn')


class Rook(Piece):
    def __init__(self, board, team):
        super().__init__(
            board=board,
            team=team,
        )
        self.icon = 'assets/' + self.team + 'R'
        self.tooltip = Tooltip('Rook')


class Knight(Piece):
    def __init__(self, board, team):
        super().__init__(
            board=board,
            team=team,
        )
        self.icon = 'assets/' + self.team + 'N'
        self.tooltip = Tooltip('Knight')


class Bishop(Piece):
    def __init__(self, board, team):
        super().__init__(
            board=board,
            team=team,
        )
        self.icon = 'assets/' + self.team + 'B'
        self.tooltip = Tooltip('Bishop')


class Queen(Piece):
    def __init__(self, board, team):
        super().__init__(
            board=board,
            team=team,
        )
        self.icon = 'assets/' + self.team + 'Q'
        self.tooltip = Tooltip('Queen')


class King(Piece):
    def __init__(self, board, team):
        super().__init__(
            board=board,
            team=team,
        )
        self.icon = 'assets/' + self.team + 'K'
        self.tooltip = Tooltip('King')


class App(Ursina):
    def __init__(self):
        super().__init__(
            vsync=False,
            borderless=False
        )
        self.board = Board()
        self.state = State(self.board)


def main():
    chess = App()
    chess.run()


if __name__ == '__main__':
    main()

→ Ссылка