Форум сайта python.su
9
Привет еще раз,
прочитав первый томик Лутца “Программирование на Python”, задался идеей написать в канвасе клон игры “2048” (http://gabrielecirulli.github.io/2048/).
Но столкнулся с проблемой по припривязке функций к событиям.
Ниже привожу код который уже успел написать. Идея в том что бы создать канвас и потом в рандомном порядке добалять картинки с циферками.
События нажатий стрелок привязаны к функциям которые должны смещать картинки с циферками и объединять их при необходимости (когда сталкиваются картинки с одинаковыеми цифрами).
Каждая картинка имеет тэг, который являет собой строку. В этой строке зашифрованы координаты картинки и инфрмация о цифре нарисованной на ней (последние 4 символа).
Например тэг ‘1362600002’ говорит о том что картинка с цифрой “2” находится в координатах (X = 136, Y = 260).
Также есть список board который содержит в себе аналогичную информацию.
При создании картинки (после каждого хода), информация о координатах и картинке записывается в список board и в тэг картинки.
Во время хода (например нажатии стрелки вправо), программа ищет созданные картинки в словаре тэгов photos и анализирует список board на предмет наличия места справа от картинки для перемещения или картинки с такой же цифрой для слития". После чего передает необходимые переменные функции tranform: tagg - тэг картинки и инфой о ней, moveX - перемещение по оси Х, moveY - перемещение по оси У, merge - слитие (да/нет).
Функция tranform не дописана до конца. Сейчас она может только перемещать картинки, но не слиять их.
НО, она не работает. Не понимаю в чем дело. Начальные 2 картинки создаются, но при нажатии стрелки вправо - не перемещаются.
Для проверки добавил функцию принт перед вызовом self.tranform(tagg, moveX, moveY, merge). И самое удивительно, что принт выдает корректный переменные (tagg, moveX, moveY, merge). Значит похоже, что что-то не так в функции tranform, но я не вижу причин почему она не работает.
Ниже привожу код. Также прикрепляю папку с кодом и самыми картинками, что бы можно было протестировать программу у себя на ПК.
from tkinter import * from random import choice class MMain(): W = 112 H = 112 w = 12 h = 12 photos = {} board = [[[12, 12, 124, 124, 0], [136, 12, 248, 124, 0], [260, 12, 372, 124, 0], [384, 12, 496, 124, 0]], [[12, 136, 124, 248, 0], [136, 136, 248, 248, 0], [260, 136, 372, 248, 0], [384, 136, 496, 248, 0]], [[12, 260, 124, 372, 0], [136, 260, 248, 372, 0], [260, 260, 372, 372, 0], [384, 260, 496, 372, 0]], [[12, 384, 124, 496, 0], [136, 384, 248, 496, 0], [260, 384, 372, 496, 0], [384, 384, 496, 496, 0]]] def __init__(self, parent = None): canvas = Canvas(width=508, height=508, bg = '#aa9d93') for i in range(4): for j in range(4): canvas.create_rectangle(j * (self.W + self.w) + self.w, i * (self.H + self.h) + self.h, j * (self.W + self.h) + (self.W + self.h), i * (self.W + self.h) + (self.W + self.h), fill='#d6c5c7', width=0) canvas.pack(fill = BOTH, expand = YES) canvas.bind('<Left>', self.moveLeft) canvas.bind('<Up>', self.moveUp) canvas.bind('<Right>', self.moveRight) canvas.bind('<Down>', self.moveDown) canvas.focus_set() self.canvas = canvas self.runGame() self.pp() # print data for self checking def pp(self): print(self.photos) print(self.board) def moveLeft(): pass def moveUp(): pass def moveRight(self, event): for tagg in sorted(self.photos, reverse = True): # search tiles on board num = int(tagg[-4:]) if tagg[:3] == '384': # tile is on rightmost position and can't move continue elif tagg[:5] == '26012': # tile is on [rightmost - 1] position and we check what is in rightmost position L = [self.board[0][3][4]] merge = False # if True - tiles will merged. moveX = 0 # moveX, moveY - variables for canvas.move('tag', moveX, moveY) moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) # print for self checking - it works fine, variables are correct! self.tranform(tagg, moveX, moveY, merge) # self.tranform doesn't work with the same variables. Why???? continue elif tagg[:6] == '260136': L = [self.board[1][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:6] == '260260': L = [self.board[2][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:6] == '260384': L = [self.board[3][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:5] == '13612': L = [self.board[0][2][4], self.board[0][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:6] == '136136': L = [self.board[1][2][4], self.board[1][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:6] == '136260': L = [self.board[2][2][4], self.board[2][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:6] == '136384': L = [self.board[3][2][4], self.board[3][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:4] == '1212': L = [self.board[0][1][4], self.board[0][2][4], self.board[0][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:5] == '12136': L = [self.board[1][1][4], self.board[1][2][4], self.board[1][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:5] == '12260': L = [self.board[2][1][4], self.board[2][2][4], self.board[2][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue elif tagg[:5] == '12384': L = [self.board[3][1][4], self.board[3][2][4], self.board[3][3][4]] merge = False moveX = 0 moveY = 0 for i in L: if i > num: break elif i == 0: moveX += 124 continue elif i == num: moveX += 124 merge = True break if moveX > 0: print(tagg, moveX, moveY, merge) self.tranform(tagg, moveX, moveY, merge) continue def moveDown(): pass def runGame(self): # according rules for start we need 2 tiles with '2' self.makeTwo() self.makeTwo() def makeTwo(self): aimCell = None boardChoice = [] for i in self.board: for j in i: if j[4] == 0: boardChoice.append(j) aimCell = choice(boardChoice) tagg = ''.join([str(aimCell[0]), str(aimCell[1]), '0002']) # tagg - tag for widget, string, which includes coord and tiles numer. For ex.: '1362600002': X = 136, Y = 260, tiles number = 2. self.photos[tagg] = PhotoImage(file = 'numbers\\small_2.gif') smalTwo = self.canvas.create_image(aimCell[0] + 15, aimCell[1] + 15, image = self.photos[tagg], anchor = NW) self.canvas.after(200, self.updateTwo, aimCell[0], aimCell[1], tagg) self.canvas.after(200, self.canvas.delete, smalTwo) # delete small tiles (small_2.gif) for i in self.board: # write data to the board, that there is tile '2' on position (aimCell[0], aimCell[1]) for j in i: if j[0] == aimCell[0] and j[1] == aimCell[1]: j[4] = int(tagg[-4:]) def updateTwo(self, x, y, z): # draw origin_2 self.photos[z] = PhotoImage(file = 'numbers\\origin_2.gif') self.canvas.create_image(x, y, image = self.photos[z], anchor = NW, tag = z) def tranform(self, tagg, moveX, moveY, merge): # it works now, but is not finished. TD: merge case if merge == False: if moveX > 0: move, moveX = 31, (moveX - 31) self.canvas.move(tagg, move, 0) if moveX: self.canvas.after(50, self.tranform, tagg, moveX, 0, merge) elif moveY > 0: move, moveY = 31, (moveY - 31) self.canvas.move(tagg, 0, move) if moveY: self.canvas.after(50, self.tranform, tagg, 0, moveY, merge) else: num = int(tagg[-4:]) if moveX > 0: move, moveX = 31, (moveX - 31) self.canvas.move(tagg, move, 0) if moveX: self.canvas.after(50, self.tranform, tagg, moveX, 0, merge) elif moveY > 0: move, moveY = 31, (moveY - 31) self.canvas.move(tagg, 0, move) if moveY: self.canvas.after(50, self.tranform, tagg, 0, moveY, merge) if __name__ == '__main__': MMain() mainloop()
Отредактировано WoMax (Авг. 9, 2014 00:56:29)
Прикреплённый файлы:
file.zip (60,6 KБ)
Офлайн
58
Давайте так. Напишите маленькую програмку, которая бы реализовывала Вашу проблему. Читать это все да еще разбираться желания нет. Может у кого-нибудь возникнет, но у меня пока не появилось 
P.S. Тема должна быть в разделе GUI.
P.S.S. С удовольствием Вам помогу, но лопатить тонны кода (да еще и не самого лучшего качества), как-то не охота 
Офлайн
9
Оки
Написал, маленьку версию, создал тему в разделе GUI:
http://python.su/forum/topic/24789/?page=1#post-131648
Офлайн