Tkinter холст прокрутки лаг с изображениями - PullRequest
0 голосов
/ 05 марта 2019

Я создаю платформер с 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), вы сможете увидеть, как она работает без фонового изображения (частица движется намного быстрее)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...