2016-07-22 48 views
0

我开发了一个十六进制游戏的接口,它获得了一个二维数组(其值为1,白色单元格为2,黑色单元格为2,空白单元格为0)屏幕作为输入并基于第一个点绘制十六进制表格。如何通过点击画布小部件来协调数组值和tkinter画布的更改?

我想触发的,因为它改变了细胞对1或2的值(这意味着在单击的单元格中发挥

石头的白色或黑色)的方式鼠标左键点击操作。当我点击单元格并获得阵列的打印时,单击单元格的值将更改,但点击的六边形的颜色不会更改。

这里是确切的代码是正常工作,除非点击触发图形的变化。

from tkinter import * 
class gui: 
    """ 
    This class is built to let the user have a better interaction with 
    game. 
    inputs => 
    canvas = Canvas(root) 
    board = board is the array of gamestate class which shows the game board. 
    start_points = This entry indicates an array of points which is the top 
    left coordinate of item of the graphical interface. 
    """ 
    def __init__(self, root, start_points, board): 
     self.canvas = Canvas(root, width=900, height=768) 
     self.board = board 
     self.start = [start_points[0], start_points[1], start_points[2], 
         start_points[3], start_points[4], start_points[5]] 
     self.temp = [] 
     for i in self.start: 
      self.temp.append(i) 
     self.initial_offset = 20 # Offset for each row and first item 
     self.hex_x = 40   # Offset for each hexagon in each row 
     self.hex_y = 40   # Offset from top of screen 
     self.hex_board = [] 
     self.array_to_hex(self.board) 
     self.bind() 
     self.canvas.pack(anchor='nw') 

    def hexagon(self, points, color): 
     """ 
     Creates a hexagon by getting a list of points and their assigned colors 
     according to the game board 
     """ 
     if color is 0: 
      hx = self.canvas.create_polygon(points[0], points[1], points[2], 
              points[3], points[4], points[5], 
             fill='#fe8b03', outline='black', width=2) 
     elif color is 1: 
      hx = self.canvas.create_polygon(points[0], points[1], points[2], 
              points[3], points[4], points[5], 
             fill='white', outline='black', width=2) 
     else: 
      hx = self.canvas.create_polygon(points[0], points[1], points[2], 
              points[3], points[4], points[5], 
             fill='#3e3f3a', outline='black', width=2) 
     return hx 

    def genrow(self, points, colors): 
     """ 
     By getting a list of points as the starting point of each row and a list of 
     colors as the dedicated color for each item in row, it generates a row of 
     hexagons by calling hexagon functions multiple times. 
     """ 
     row = [] 
     temp_array = [] 
     for i in range(len(colors)): 
      for point in points: 
       temp_points_x = point[0] + self.hex_x * i 
      temp_points_y = point[1] 
      temp_array.append([temp_points_x, temp_points_y]) 
     if colors[i] is 0: 
      hx = self.hexagon(temp_array, 0) 
     elif colors[i] is 1: 
      hx = self.hexagon(temp_array, 1) 
     else: 
      hx = self.hexagon(temp_array, 2) 
     row.append(hx) 
     temp_array = [] 
    return row 

def array_to_hex(self, array): 
    """ 
    Simply gets the gameboard and generates the hexagons by their dedicated colors. 
    """ 
    for i in range(len(array)): 
     for point in self.temp: 
      point[0] += self.hex_x 
      point[1] += self.hex_y 
     for point in self.temp: 
      point[0] -= self.initial_offset 
     row = self.genrow(self.temp, self.board[i]) 
     self.temp.clear() 
     for k in self.start: 
      self.temp.append(k) 
     self.hex_board.append(row) 

    def bind(self): 
     """ 
     Binding triggers for the actions defined in the class. 
     """ 
     self.canvas.bind('<Motion>', self.mouse_motion) 
     self.canvas.bind('<1>', self.mouse_click) 

    def mouse_motion(self, event): 
     """ 
     Simply implements a hovering action for each item 
     """ 
     if self.canvas.find_withtag(CURRENT): 
      current_color = self.canvas.itemcget(CURRENT, 'fill') 
      self.canvas.itemconfig(CURRENT, fill="cyan") 
      self.canvas.update_idletasks() 
      self.canvas.after(150) 
      self.canvas.itemconfig(CURRENT, fill=current_color) 

    def mouse_click(self, event): 
     """ 
     This function changes the color of item (depending on the player turns) 
     to assigned color 
     """ 
     x, y = event.x, event.y 
     idd = self.canvas.find_overlapping(x, y, x, y) 
     idd = list(idd) 
     if len(idd) is not 0: 
      p = idd[0] 
      index = [[ix, iy] for ix, 
      row in enumerate(self.hex_board) for iy, 
      i in enumerate(row) if i == p][0] 
      self.board[index[0]][index[1]] = 1 
      for i in self.board: 
       print(i) 
      print('\n') 

row_item_offset = 40 
x_offset = 20 
y_offset = 40 
points1 = [[25, 10], [45, 25], [45, 50], [25, 65], [5, 50], [5, 25]] 
test_array = [[1, 0, 0, 0, 0, 0], 
       [0, 0, 2, 0, 0, 0], 
       [1, 1, 1, 2, 1, 2], 
       [0, 0, 0, 2, 0, 2], 
       [0, 1, 0, 0, 1, 2], 
       [0, 0, 0, 2, 0, 0]] 
root = Tk() 
hexagons = gui(root, points1, test_array) 
root.mainloop() 

我是那种想刷新整个项目或使用忘记方法删除整个部件,并再次重新包装他们,但我

不知道如何实现这一点。 我想我需要修改mouse_click_trigger方法。 任何人都可以提供任何建议与示例代码? 谢谢。

回答

0

我真的希望这是你在找什么:

from tkinter import * 
root = Tk() 
root.geometry("600x600-400+50") 
root.title("Game") 

class App: 
    def __init__(self, master): 
     self.master = master 

     self.rbvar = IntVar() 

     self.stonerb = Radiobutton(self.master, text="Stone", 
            variable=self.rbvar, value=1, command=self.figurefunc) 
     self.stonerb.pack() 

     self.blackrb = Radiobutton(self.master, text="Black", 
            variable=self.rbvar, value=2, command=self.figurefunc) 
     self.blackrb.pack() 

     self.board = Canvas(self.master, bg='#b35900', width=500, height=500) 
     self.board.pack() 

     self.figure = self.board.create_polygon(0,0, 0,0, 0,0, 0,0, 0,0, 0,0) 

     self.stoneCoords = 60,200, 100,200, 120,230, 100,260, 60,260, 40,230 
     self.blackCoords = 440,200, 400,200, 380,230, 400,260, 440,260, 460,230 

    def figurefunc(self): 
     if self.rbvar.get() == 1: 
      self.board.coords(self.figure, self.stoneCoords) 
      self.board.itemconfig(self.figure, fill='#f2f2f2') 
     else: 
      self.board.coords(self.figure, self.blackCoords) 
      self.board.itemconfig(self.figure, fill='black') 


myapp = App(root) 

唷!

+0

OK.first首先,感谢您的提示,很高兴看到您渴望提供帮助。但我的意思是这样的:我点击一个六边形,它在self.board中更改该项目的值,然后基于新阵列再次创建整个板子。这导致点击的项目变成白色或黑色。 –

+0

我需要以这种方式改变self.board数组,因为我将在程序的其他部分使用self.board数组。 –

+0

通过这种方式,您可以随时摧毁并重新创建世界。但是因为我们可以使每个屏幕成为一个框架,所以我们可以在不破坏父窗口的情况下完成。 –