Feb-17-2021, 09:45 AM
(This post was last modified: Feb-17-2021, 09:47 AM by deanhystad.)
Another way to do this is do everything in absolute coordinates except the move request.
import tkinter as tk def clip(x, lower, upper): """Clip value to be in range lower..uper""" return lower if x < lower else upper if x > upper else x class Ship(): def __init__(self, parent, wide, high): self.canvas = tk.Canvas(parent, width=wide, height=high) self.canvas.pack() self.img = tk.PhotoImage(file = "test_image.png") img_wide = self.img.width() img_high = self.img.height() self.xmax = wide - img_wide self.ymax = high - img_high x = int((wide - img_wide) / 2) y = int((high - img_high) / 2) self.img_id = self.canvas.create_image(x, y, anchor=tk.NW, image=self.img) def move(self, x, y): # Convert to absolute coordinates and clip to range imgx, imgy = self.canvas.coords(self.img_id) x = clip(x + imgx, 0, self.xmax) y = clip(y + imgy, 0, self.ymax) self.canvas.moveto(self.img_id, x, y) def main(): root = tk.Tk() ship = Ship(root, 500, 400) root.bind("<Right>", lambda e: ship.move(x=5, y=0)) root.bind("<Left>", lambda e: ship.move(x=-5, y=0)) root.bind("<Up>", lambda e: ship.move(x=0, y=-5)) root.bind("<Down>", lambda e: ship.move(x=0, y=5)) root.mainloop() main()