2016-11-20 6 views
-1

Я пытаюсь создать игру, в которой изображения помещаются в случайные ячейки сетки. Мне удалось создать сетку, и я попытался использовать ее для случайного размещения изображений, но она не работает так, как мне бы хотелось.Как случайно разместить изображения в сетке холста tkinter

try: 
    import tkinter as tk 
    from tkinter import ttk 
    from tkinter.ttk import * 
except ImportError: 
    import Tkinter as tk 
    from Tkinter import ttk 
    from Tkinter.ttk import * 
import random 
from random import randint 

window = tk.Tk() 
style = ttk.Style(window) 
style.configure("BW.TLabel") 
game_frame = tk.Frame(window) 
game_grid = tk.Canvas(game_frame, width=450, height=450, borderwidth=0, 
         highlightthickness=0) 

def grid_create(): 
    global row, col, cell_width, cell_height, rect, rows , columns 
    rows = 8 
    columns = 8 
    cell_width = 50 
    cell_height = 50 
    rect = {} 
    for i in (game_grid, game_frame): 
     i.pack() 
    for column in range(8): 
     for row in range(8): 
      x1 = column*cell_width 
      y1 = row * cell_height 
      x2 = x1 + cell_width 
      y2 = y1 + cell_height 
      rect[row,column] = game_grid.create_rectangle(x1,y1,x2,y2, 
                 fill="green", 
                  tags="rect") 
    grid_draw() 
def grid_draw(): 
    global row, col 
    game_grid.itemconfig("rect", fill="green") 
    for i in range(8): 
     row = random.randint(0,8) 
     col = random.randint(0,8) 
    create_objects() 
def create_objects(): 
    rows = 8 
    columns = 8 
    cell_width = 50 
    cell_height = 50 
    bandits = 5 
    bandit_list = {} 
    bandit_img = tk.PhotoImage(file="Bandit.png") 

    for column in range(randint(0,8)): 
     for row in range(randint(0,8)): 
      x1 = column*cell_width + 22 
      y1 = row * cell_height - 22 
      x2 = x1 + cell_width 
      y2 = y1 + cell_height 
      bandit_list[row, column] = game_grid.create_image(x1, y2, 
                   image=bandit_img) 
    for i in range(randint(0,5)): 
     row = random.randint(0,8) 
     col = random.randint(0,8) 
grid_create() 
window.mainloop() 

Я хочу только пять «Бандиты», которое будет отображаться в случайных клетках - отсюда bandits = 5 - но я не могу показаться, чтобы выяснить, как это сделать. Я также не хочу, чтобы какой-либо из «бандитов» перекрывался. Любая помощь приветствуется.

Изображение: Link to image as I do not have the required reputation to embed it here.

ответ

1

Существует проблема с PhotoImage и "Garbage Collector", которые удаляют (из памяти) изображения присваивается локальной переменной в функции.

Вы должны назначить его глобальной переменной ie.

# create global variable 
bandit_img = None 

def create_objects(): 
    # inform function to use global varia 
    global bandit_img 

    bandit_img = tk.PhotoImage(file="Bandit.png") 

или экземпляра виджета: см «Примечание» на стр http://effbot.org/tkinterbook/photoimage.htm


Чтобы получить только 5 бандитов вы должны получить случайные значения (row,col) и проверить, если он не существует в списке бандита. Если в списке существует (row,col), то вы снова и снова получаете случайные значения. Вы можете использовать while True цикл и break оставить петлю, когда вы найдете уникальный (row,col)

try: 
    import tkinter as tk 
    import tkinter.ttk as ttk 
except ImportError: 
    import Tkinter as tk 
    import ttk 

import random 

# --- constants --- (UPPER_CASE names) 

ROWS = 8 
COLUMNS = 8 
CELL_WIDTH = 50 
CELL_HEIGHT = 50 
BANDITS_NUMBER = 5 

# --- functions --- 

def create_grid(): 

    data = {} 

    for col in range(COLUMNS): 
     for row in range(ROWS): 
      x1 = col * CELL_WIDTH 
      y1 = row * CELL_HEIGHT 
      x2 = x1 + CELL_WIDTH 
      y2 = y1 + CELL_HEIGHT 
      data[row, col] = game_grid.create_rectangle(x1, y1, x2, y2, 
                 fill="green", tags="rect") 

    return data 

def create_bandits(image): 

    data = {} 

    for i in range(BANDITS_NUMBER): 

     while True: 
      row = random.randint(0, ROWS-1) 
      col = random.randint(0, COLUMNS-1) 
      if (row,col) not in data: 
       break 

     x1 = col * CELL_WIDTH + 22 
     y1 = row * CELL_HEIGHT - 22 
     x2 = x1 + CELL_WIDTH 
     y2 = y1 + CELL_HEIGHT 

     data[row, col] = game_grid.create_image(x1, y2, image=image) 

    return data 

# --- main --- 

# - init - 

window = tk.Tk() 

game_frame = tk.Frame(window) 
game_frame.pack() 

game_grid = tk.Canvas(game_frame, width=450, height=450, borderwidth=0, 
         highlightthickness=0) 
game_grid.pack() 
game_grid.itemconfig("rect", fill="green") 

# - data - 

rects = create_grid() 

# create global variable 
bandit_image = tk.PhotoImage(file="Bandit.png") 

# send image to function - so you don't need word "global" 
bandits = create_bandits(bandit_image) 

# - start - 

window.mainloop()