Ошибка при удалении объекта 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()