Я создаю платформер с tkinter, у меня есть player
в центре «камеры» (canvas view
), и когда пользователь нажимает Arrow left
или Arrow right
, игрок перемещает свою левую сторону иКамера следит за ним.Это хорошо работает, если нет фонового изображения, но когда я добавляю его (3600x1070) и нажимаю Arrow left/right
, игра запускается с задержкой.Задержка вызвана canvas scroll
для того, чтобы позволить камере следовать за игроком, и я не понимаю, как ее решить.Вот исполняемый пример для демонстрации моей проблемы
from tkinter import *
from random import *
from PIL import Image, ImageTk
ARROW_LEFT = 37
ARROW_RIGHT = 39
master = Tk()
key_list = []
ws = master.winfo_screenwidth()
hs = master.winfo_screenheight()
x = (ws / 2) - (700 // 2)
y = (hs / 2) - (700 // 2)
master.geometry('%dx%d+%d+%d' % (700 + 4, 700 + 4, x, y))
master.title("My game")
canvas = Canvas(master, width=2000, height=2000, bg="black")
canvas.configure(scrollregion=(0, 0, 5000, 5000), yscrollincrement='1', xscrollincrement='1')
canvas.grid(row=0)
class Background:
def __init__(self, canvas=None, background_path="", game_window=None):
self.game_window = game_window
self.canvas = canvas
self.image = Image.open(background_path)
self.img_copy = self.image.copy()
self.image = self.img_copy.resize((ws * 2, hs))
self.background_image = ImageTk.PhotoImage(self.image)
x = (2000//2) - ws//2
y = (2000/2) - hs
self.background = self.canvas.create_image(x, y, image=self.background_image, tag='background', anchor=NW)
class Rain:
def __init__(self, master):
self.canvas = canvas
self.master = master
self.lenght = randint(10, 20)
self.rain_speed = randint(5, 30)
self.particel_speed = randint(5, 50)
def blob(self):
x1 = randint(canvas.canvasx(0), canvas.canvasx(ws))
y1 = 0
colors = ["red", "yellow", "blue", "green", "purple"]
index = randint(0, len(colors) - 1)
line = self.canvas.create_line(x1, y1, x1, y1 + self.lenght, fill=colors[index], width=2, tag="rain")
self.move(line, self.canvas.coords(line))
def move(self, line, coords):
line_x1 = round(coords[0])
line_y1 = round(coords[1])
line_x2 = round(coords[2])
line_y2 = round(coords[3])
if line_y2 > canvas.canvasy(hs) or line_x1 < canvas.canvasx(0) or line_x1 > canvas.canvasx(ws):
self.canvas.delete(line)
self.blob()
return
else:
self.canvas.coords(line, coords[0], coords[1] + 5, coords[2],
coords[3] + 5)
coords = self.canvas.coords(line)
self.master.after(self.rain_speed, lambda: self.move(line, coords))
def rain():
for _ in range(20):
Rain(master).blob()
def scroll_screen_left(canvas):
canvas.xview_scroll(-3, UNITS)
def scroll_screen_right(canvas):
canvas.xview_scroll(3, UNITS)
def key_listner(event):
event = event.keycode
if event not in key_list:
key_list.append(event)
def key_organizator():
if len(key_list) > -1:
combo = [
{ARROW_LEFT},
{ARROW_RIGHT},
]
if set(key_list) in combo:
pass
else:
for key in key_list:
if {key} in combo:
key_list.clear()
key_list.append(key)
if set(key_list) in combo:
if ARROW_LEFT in key_list:
scroll_screen_left(canvas) # lag
elif ARROW_RIGHT in key_list:
scroll_screen_right(canvas) # lag
master.after(10, lambda: key_organizator())
def clear_key(event):
event = event.keycode
if event in key_list:
key_list.remove(event)
BACKGROUND_1_LAYER_PATH = "assets/background/background_1.png"
layer1_background = Background(canvas=canvas, background_path=BACKGROUND_1_LAYER_PATH)
key_organizator()
rain()
master.bind("<KeyRelease>", clear_key)
master.bind("<KeyPress>", key_listner)
master.mainloop()
Если вы нажмете стрелку вправо для имитации движения игрока, вы увидите, как частицы начинают замедляться при падении, чем ближе вы подходите кЦентр изображения больше, они замедляются.
Если вы удалите линию layer1_background = Background(canvas=canvas, background_path=BACKGROUND_1_LAYER_PATH)
, вы сможете увидеть, как она работает без фонового изображения (частица движется намного быстрее)