2016-07-22 14 views
0

私は、2次元配列(白いセルの場合は1、黒いセルの場合は2、空のセルの場合はキャンバスウィジェットをクリックすると、配列値とtkinterキャンバスの変更をどのように調整できますか?

0)を取得し、最初の六角形の座標を画面に入力し、最初に

ポイントに基づいて16進表を描画します。

は、私はそれが(クリックされたセルに白または黒の

石を演じる意味)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。まず、おかげさまで、ありがとうございました。私が意味していたことはこれです:私は六角形をクリックします。それはself.boardのその項目の値を変更し、新しい配列に基づいてボード全体を作り直します。クリックした項目が白または黒に変わります。 –

+0

プログラムの他の部分でself.board配列を使用するため、self.board配列をそのように変更する必要があります。 –

+0

このようにすれば、いつでもあなたは世界を破壊し、再現することができます。しかし、各画面をフレームにすることができるので、親ウィンドウを破壊することなくそれを行うことができます。 –

関連する問題