код рисования доски для перемещения овала - PullRequest
4 голосов
/ 19 июля 2011

Я работаю над игрой в шашки для колледжа.Я нарисовал доску, используя tk, но я не могу реализовать функцию перемещения для фигур.Если кто-нибудь увидит какие-либо ошибки в моем коде или может предложить помощь, я был бы признателен.Вот полный источник.Заранее спасибо.

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

Я знаю о рекурсии, однако мне нужна базовая функция для работыперед перемещением каких-либо функций.

lst2 = []

#counter variable
i=0

#board variable is what stores the X/O/- values.
# It's a 2D list. We iterate over it, looking to see
# if there is a value that is X or O. If so, we draw
# text to the screen in the appropriate spot (based on
# i and j.
while i < len(board):
  j=0
  while j < len(board[i]):

    if board[i][j] == 2:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Red",outline='Black'))
    elif board[i][j] == 4:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Red",outline='Black'))
    elif board[i][j] == 1:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Black",outline='Black'))
    elif board[i][j] == 3:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Black",outline='Black'))

    j+=1

  i+=1

Ответы [ 2 ]

27 голосов
/ 22 июля 2011

Вы можете переместить элемент на холсте, используя методы ordinates и / или move , чтобы изменить координаты с того, что они есть, на то, что вы хотите, чтобы они были.

Вот простой пример, показывающий, как создать и переместить элемент на холсте:

import Tkinter as tk

class Example(tk.Frame):
    '''Illustrate how to drag items on a Tkinter canvas'''

    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        # create a canvas
        self.canvas = tk.Canvas(width=400, height=400)
        self.canvas.pack(fill="both", expand=True)

        # this data is used to keep track of an 
        # item being dragged
        self._drag_data = {"x": 0, "y": 0, "item": None}

        # create a couple of movable objects
        self._create_token((100, 100), "white")
        self._create_token((200, 100), "black")

        # add bindings for clicking, dragging and releasing over
        # any object with the "token" tag
        self.canvas.tag_bind("token", "<ButtonPress-1>", self.on_token_press)
        self.canvas.tag_bind("token", "<ButtonRelease-1>", self.on_token_release)
        self.canvas.tag_bind("token", "<B1-Motion>", self.on_token_motion)

    def _create_token(self, coord, color):
        '''Create a token at the given coordinate in the given color'''
        (x,y) = coord
        self.canvas.create_oval(x-25, y-25, x+25, y+25, 
                                outline=color, fill=color, tags="token")

    def on_token_press(self, event):
        '''Begining drag of an object'''
        # record the item and its location
        self._drag_data["item"] = self.canvas.find_closest(event.x, event.y)[0]
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y

    def on_token_release(self, event):
        '''End drag of an object'''
        # reset the drag information
        self._drag_data["item"] = None
        self._drag_data["x"] = 0
        self._drag_data["y"] = 0

    def on_token_motion(self, event):
        '''Handle dragging of an object'''
        # compute how much the mouse has moved
        delta_x = event.x - self._drag_data["x"]
        delta_y = event.y - self._drag_data["y"]
        # move the object the appropriate amount
        self.canvas.move(self._drag_data["item"], delta_x, delta_y)
        # record the new position
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
2 голосов
/ 19 июля 2011

6-е РЕДАКТИРОВАНИЕ: Вот два решения для вас:

  1. (как предлагает Брайан) либо запомните старое местоположение перемещенной фигуры, перерисуйте ее там (=> нарисуйте в цвете фона), перерисуйте в новом месте
  2. проще: очистить и перерисовать всю доску

5-е РЕДАКТИРОВАНИЕ: Хорошо, спасибо за удаление кода.

Объясните точно в чем проблема с вашим кодом для рисования на доске? 'Перемещенный фрагмент не удален из старого местоположения'? «Все фигуры нарисованы с неправильными координатами или цветами»? ... Недопустимо просто сохранять дамп кода и говорить «Этот код не работает».

«Я не знаю, как перерисовать кусочки, не удаляя другие кусочки». Я думаю, что это ваша проблема прямо здесь. Если вы объявляете и вызываете redrawBoard(), он должен перерисовать ВСЕ фигуры (!), А не только перемещенную фигуру. Согласен? то есть вы должны выполнить итерацию по всей доске [] [] и вызывать drawPiece () для каждой фигуры. Но ваш код, кажется, уже делает это?

Позвольте мне предложить вам, как очистить существующий код рисования доски, и в этом процессе вы почти наверняка найдете свою ошибку. Очевидно, вам нужно очищать и перерисовывать экран каждый раз, когда происходит какое-либо движение (или продвижение), вы на самом деле это делаете? Объявите FN redrawBoard() для этого. Если вы не сделаете очистку, то после хода фигура будет отображаться в ее старых И новых местах, что, очевидно, будет неправильным? (Комментарий о Частота кадров - это то, как часто холст будет обновляться каждую секунду. заставляет задуматься, когда вы перерисовываете, вам не нужно перерисовывать 10 раз в секунду, если у вас также нет часов или других изменяющихся данных Но, эй, это тоже работает.

Во-первых, настоятельно рекомендуем использовать перечисление для самостоятельного документирования значений , используемых в доске [] []

class Checkers():
    EMPTY=0
    RED_PIECE=1
    RED_KING=2
    BLACK_PIECE=3
    BLACK_KING=4

Далее вы можете значительно убрать код рисования доски. Так как все 4 случая рисования фрагментов вызывают общий случай, сделайте его fn и сделайте этот fn незагроможденным:

def drawPiece(i,j,fillColor,outlineColor):
    """Draw single piece on screen."""
    x = (i+1)*width + width/2
    y = (j+1)*height + height/2
    lst2.append(canvas.create_oval(x+15,y+15,x-15,y-15,fill=fillColor,outline=outlineColor))

Теперь код рисования доски, который вызывает их строго, имеет только два случая: (2,4) или (1,3), если вы правильно выполнили перечисление:

и, между прочим, никогда не используйте цикл while, когда более удобочитаемый цикл for:

for i in range(len(board)):
    for j in range(len(board[i])):
        if board[i][j] in (RED_PIECE,RED_KING):
            drawPiece(i,j,'Red','Black')
        elif board[i][j] in (BLACK_PIECE,BLACK_KING):
            drawPiece(i,j,'Black','Black')

Разве это разложение не бесконечно легче читать и отлаживать? Это самодокументирование. Теперь ваша ошибка должна практически выпрыгнуть на вас.

(Кстати, в настоящее время вы рисуете королей точно так же, как фигуры, но я думаю, вы исправите это позже.)


4-е РЕДАКТИРОВАНИЕ: Вы заставляли нас смотреть не на те fns, грр ... вы говорите, что ваша ошибка на самом деле в коде рисования доски . Не могли бы вы исправить заголовок, который по-прежнему гласит «Реализация функции движения» ?


ОРИГИНАЛЬНЫЙ ОТВЕТ: О том, что жаждет машина, это еще не вопрос - пока нет: расскажите, что вы сейчас пытаетесь и почему это не работает. Также удалите весь несвязанный код.

Похоже, у вас проблемы с функцией moveTo(i,j) - но что именно? (Глобал secondPass, secondPosition сигнализируют, что у вас могут быть проблемы ... знаете ли вы рекурсию? Если нет, то не беспокойтесь.)

Кроме того, в качестве стилистической вещи, и чтобы упростить вашу жизнь, эта реализация не ОО, глобалы кричат ​​о плохой декомпозиции. Попробуйте переписать как класс Checkers, сделать доску и т. Д. Членом, написать метод init(). Я бы переименовал функцию grid(x,y) в initialize(nrows,ncols).

(И кашель, кашель! Признаки того, что вы адаптировали это от кого-то другого ...)

#Frame rate is how often canvas will be updated
# each second. For Tic Tac Toe, 10 should be plenty.
FRAME_RATE = 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...