Я работаю над игрой, в которой игрок должен собирать монеты, присаживаясь на сундуки. Однако, если они три раза приземлятся на один сундук, он удалит сундук, который там, и введет бандит на свое место, - который сбросит свои монеты обратно до нуля (эта часть не включена в код, предоставляемый по мере его запуска правильно).Удаление изображения с холста tkinter на основе его координат
try:
import tkinter as tk
from tkinter import ttk
except ImportError:
import Tkinter as tk
from Tkinter import ttk
import random
from collections import Counter
CELL_WIDTH = 50
CELL_HEIGHT = 50
rows = 8
columns = 8
bandit_number = 5
chest_number = 10
moves = 0
coins = 0
chests_visited =()
def create_grid():
game_frame.pack()
game_grid.pack()
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_chests(chest_image):
global chest_dict
chest_dict = {}
for i in range(chest_number):
while True:
row = random.randint(0, rows-1)
col = random.randint(0, columns-1)
if (row,col) not in chest_dict:
break
x1 = col * CELL_WIDTH + 24
y1 = row * CELL_HEIGHT - 26
x2 = x1 + CELL_WIDTH
y2 = y1 + CELL_HEIGHT
chest_dict[row,col] = game_grid.create_image(x1, y1, image=chest_image,
tags="chest")
return chest_dict
def create_bandits(bandit_image):
global bandit_dict
bandit_dict = {}
for i in range(bandit_number):
while True:
row = random.randint(0, rows-1)
col = random.randint(0, columns-1)
if (row,col) not in bandit_dict:
break
x = col * CELL_WIDTH + 22
y = row * CELL_HEIGHT - 22
x2 = x + CELL_WIDTH
y2 = y + CELL_HEIGHT
bandit_dict[row,col] = game_grid.create_image(x, y, image=bandit_image)
return bandit_dict
def position_player(player_image):
global arrow
arrow = game_grid.create_image(26, 375, image=player_image)
display_widgets()
return arrow
def display_widgets():
global move_entry_x, move_entry_y, help_lbl
help_lbl = tk.Label(game_grid, text="Enter the x value in the first entry"+
" and the y value in the second." + '\n' +
"Use negatives to move left and down.")
game_grid.create_window(200, 420, window=help_lbl)
move_entry_x = tk.Entry(game_grid)
game_grid.create_window(70, 450, window=move_entry_x)
move_entry_y = tk.Entry(game_grid)
game_grid.create_window(200, 450, window=move_entry_y)
enter_btn = ttk.Button(game_grid, text="Enter", command=check_move)
game_grid.create_window(305, 450, window=enter_btn)
def check_move():
global help_lbl
if (
move_entry_x.get()[0] == "-" or
move_entry_y.get()[0] == "-"
):
try:
if (
int(move_entry_x.get()[1])*CELL_WIDTH < 26 or
int(move_entry_x.get()[1])*CELL_WIDTH > int(rows)*CELL_WIDTH
):
print("Illegal move! Enter a different value")
elif (
int(move_entry_y.get()[1])*CELL_WIDTH < 26 or
int(move_entry_y.get()[1])*CELL_WIDTH > int(rows)*CELL_HEIGHT
):
print("Illegal move! Enter a different value")
else:
move_player(arrow)
except ValueError:
print("Please enter a number!")
else:
try:
if (
int(move_entry_x.get())*CELL_WIDTH < 26 or
int(move_entry_x.get())*CELL_WIDTH > int(rows)*CELL_WIDTH
):
print("Illegal move! Enter a different value")
elif (
int(move_entry_y.get())*CELL_WIDTH < 26 or
int(move_entry_y.get())*CELL_WIDTH > int(rows)*CELL_HEIGHT
):
print("Illegal move! Enter a different value")
else:
move_player(arrow)
except ValueError:
print("Please enter a number!")
def move_player(arrow):
global move_entry_x, move_entry_y, help_lbl, moves
x_move = move_entry_x.get()
y_move = move_entry_y.get()
x = int(x_move)*CELL_WIDTH
y = int(y_move)*CELL_HEIGHT
game_grid.move(arrow, x, -y)
moves += 1
print("Moves = "+str(moves))
check_position(arrow, chest_dict)
def check_position(arrow, chest_dict):
global coins, arrow_coords, chests_visited
arrow_coords = game_grid.coords(arrow)
for i in chest_dict:
chest_coords = game_grid.coords(chest_dict[i])
if (
int(arrow_coords[0])-2 in chest_coords and
int(arrow_coords[1])-1 in chest_coords
):
coins += 10
chests_visited += tuple(arrow_coords)
print("Chests visited: "+str(chests_visited))
check_chests()
return arrow, chest_dict
def check_chests():
global chests_visited, chest_dict, bandit_dict
cnt = Counter(chests_visited)
if (
[k for k, v in cnt.items() if v == 3]
):
game_grid.create_image(arrow_coords[0],arrow_coords[1],
image=bandit_image)
print("bandit_time")
window = tk.Tk()
game_frame = tk.Frame(window)
game_grid = tk.Canvas(game_frame, width=500, height=500, borderwidth=0,
highlightthickness=0)
game_grid.itemconfig("rect", fill="green")
bandit_image = tk.PhotoImage(file="Bandit.png")
chest_image = tk.PhotoImage(file="Treasure Chest.png")
player_image = tk.PhotoImage(file="Arrow.png")
rects = create_grid()
bandits = create_bandits(bandit_image)
chests = create_chests(chest_image)
player = position_player(player_image)
window.mainloop()
Я знаю, что вы можете использовать canvas.delete(item_id)
, чтобы удалить объект, учитывая, что она была определена, но моя проблема заключается в том, что, так как я создал свои объекты со словарем, они не имеют конкретные имена, которые я мог бы использовать, и я хотел бы знать, как я могу удалить объект из холста на основе его координат, а не его имени.
Кроме того, поскольку я использую изображения, в соответствии с ответами, которые я нашел, формат должен быть GIF, но я могу использовать формат PNG, и он все еще отлично работает, но когда я пытаюсь моя игра на другом устройстве, я получаю ожидаемую ошибку. Для этого есть причина?
'Tkinter', как по умолчанию работает только с' GIF' (и еще один формат). Для работы с PNG вам нужен модуль 'PIL' или' pillow': http://effbot.org/tkinterbook/photoimage.htm. Конечно, PIL/pillow' может использовать некоторые внешние библиотеки, и если у устройства нет этих библиотек, то событие 'PIL/pillow' не может помочь. – furas
'canvas.delete (data [row, col])' или 'canvas.delet (chest_dict [row, col])' – furas
@furas Я пошел дальше, но предлагаемое вами решение заставляет мою программу всегда предполагать, что сундук всегда 7-й строке и столбце, что дает мне «ключевую ошибку». Есть идеи? – Ernxst